"""Import API routes — CSV upload/preview/confirm, ICD xlsx upload, import log."""

import logging
from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.config import get_settings
from app.core.dependencies import get_current_user, require_admin
from app.database import get_db
from app.models.audit import ImportLog
from app.models.user import User
from app.schemas.import_schemas import ImportPreview, ImportResult
from app.services.audit_service import log_action
from app.services.csv_parser import parse_csv
from app.services.icd_service import import_icd_from_xlsx
from app.services.import_service import confirm_import, preview_import

logger = logging.getLogger(__name__)
settings = get_settings()

router = APIRouter()


# ---------------------------------------------------------------------------
# Response schemas (co-located for simplicity)
# ---------------------------------------------------------------------------


class ICDImportResponse(BaseModel):
    """Result of importing ICD codes from an xlsx file."""

    updated: int
    errors: list[str] = []


class ImportLogResponse(BaseModel):
    """Single import-log entry."""

    id: int
    filename: str
    import_type: str
    cases_imported: int
    cases_skipped: int
    cases_updated: int
    errors: Optional[str] = None
    imported_by: Optional[int] = None
    imported_at: datetime

    model_config = {"from_attributes": True}


class ImportLogListResponse(BaseModel):
    """Paginated import-log response."""

    items: list[ImportLogResponse]
    total: int
    page: int
    per_page: int


# ---------------------------------------------------------------------------
# CSV Import — preview (dry-run)
# ---------------------------------------------------------------------------


@router.post("/csv", response_model=ImportPreview)
async def upload_csv_preview(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    user: User = Depends(require_admin),
):
    """Upload a CRM CSV file and preview what will be imported.

    Returns a list of rows with duplicate detection. No data is written
    to the database — the caller must confirm via ``POST /csv/confirm``.
    """
    if not file.filename or not file.filename.lower().endswith(".csv"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="File must be a .csv file",
        )

    content = await file.read()
    if len(content) > settings.MAX_UPLOAD_SIZE:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail=f"File exceeds maximum size of {settings.MAX_UPLOAD_SIZE // (1024 * 1024)}MB",
        )

    try:
        parsed = parse_csv(content, file.filename)
    except Exception as exc:
        logger.exception("CSV parsing failed for %s", file.filename)
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"CSV parsing failed: {exc}",
        )

    return preview_import(db, parsed, file.filename)


# ---------------------------------------------------------------------------
# CSV Import — confirm (write to DB)
# ---------------------------------------------------------------------------


@router.post("/csv/confirm", response_model=ImportResult)
async def confirm_csv_import(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    user: User = Depends(require_admin),
):
    """Re-upload the same CSV file to confirm the import.

    The file is re-parsed and non-duplicate cases are inserted into the
    database. An entry is written to the ``import_log`` table.
    """
    if not file.filename or not file.filename.lower().endswith(".csv"):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="File must be a .csv file",
        )

    content = await file.read()
    if len(content) > settings.MAX_UPLOAD_SIZE:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail=f"File exceeds maximum size of {settings.MAX_UPLOAD_SIZE // (1024 * 1024)}MB",
        )

    try:
        parsed = parse_csv(content, file.filename)
    except Exception as exc:
        logger.exception("CSV parsing failed for %s", file.filename)
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"CSV parsing failed: {exc}",
        )

    result = confirm_import(db, parsed, file.filename, user.id)
    log_action(
        db,
        user_id=user.id,
        action="csv_imported",
        entity_type="import",
        new_values={
            "filename": file.filename,
            "imported": result.imported,
            "skipped": result.skipped,
            "updated": result.updated,
        },
    )
    return result


# ---------------------------------------------------------------------------
# ICD Excel upload
# ---------------------------------------------------------------------------


@router.post("/icd-xlsx", response_model=ICDImportResponse)
async def upload_icd_xlsx(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    user: User = Depends(get_current_user),
):
    """Upload a filled-in ICD coding Excel template.

    Expects columns: Case_ID (col 1), ICD (col 7). Accessible to both
    admin and dak_mitarbeiter users.
    """
    if not file.filename or not file.filename.lower().endswith((".xlsx", ".xls")):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="File must be an Excel file (.xlsx)",
        )

    content = await file.read()
    if len(content) > settings.MAX_UPLOAD_SIZE:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail=f"File exceeds maximum size of {settings.MAX_UPLOAD_SIZE // (1024 * 1024)}MB",
        )

    try:
        result = import_icd_from_xlsx(db, content, user.id)
    except Exception as exc:
        logger.exception("ICD xlsx import failed for %s", file.filename)
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"ICD import failed: {exc}",
        )

    # Log the import
    log = ImportLog(
        filename=file.filename,
        import_type="icd_xlsx",
        cases_imported=0,
        cases_skipped=0,
        cases_updated=result["updated"],
        errors="; ".join(result["errors"]) if result["errors"] else None,
        imported_by=user.id,
    )
    db.add(log)
    db.commit()

    log_action(
        db,
        user_id=user.id,
        action="icd_xlsx_imported",
        entity_type="import",
        new_values={
            "filename": file.filename,
            "updated": result["updated"],
            "errors": len(result["errors"]),
        },
    )

    return ICDImportResponse(**result)


# ---------------------------------------------------------------------------
# Historical Excel upload (placeholder — full logic in Task 12)
# ---------------------------------------------------------------------------


@router.post("/historical", response_model=ImportResult)
async def upload_historical_excel(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    user: User = Depends(require_admin),
):
    """Upload the Abrechnung_DAK.xlsx for historical data import (admin only).

    This is a placeholder endpoint. The full import logic will be
    implemented in Task 12.
    """
    if not file.filename or not file.filename.lower().endswith((".xlsx", ".xls")):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="File must be an Excel file (.xlsx)",
        )

    content = await file.read()
    if len(content) > settings.MAX_UPLOAD_SIZE:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail=f"File exceeds maximum size of {settings.MAX_UPLOAD_SIZE // (1024 * 1024)}MB",
        )

    # TODO: Implement historical import in Task 12
    raise HTTPException(
        status_code=status.HTTP_501_NOT_IMPLEMENTED,
        detail="Historical Excel import is not yet implemented",
    )


# ---------------------------------------------------------------------------
# Import log (history)
# ---------------------------------------------------------------------------


@router.get("/log", response_model=ImportLogListResponse)
def get_import_log(
    page: int = Query(1, ge=1),
    per_page: int = Query(20, ge=1, le=100),
    import_type: Optional[str] = Query(None),
    db: Session = Depends(get_db),
    user: User = Depends(require_admin),
):
    """Return a paginated list of past imports (admin only)."""
    query = db.query(ImportLog)

    if import_type:
        query = query.filter(ImportLog.import_type == import_type)

    total = query.count()
    items = (
        query.order_by(ImportLog.imported_at.desc())
        .offset((page - 1) * per_page)
        .limit(per_page)
        .all()
    )

    return ImportLogListResponse(
        items=items,
        total=total,
        page=page,
        per_page=per_page,
    )
