from fastapi import APIRouter, Depends, Query
from fastapi.responses import PlainTextResponse
from sqlalchemy.orm import Session

from app.api.deps import require_super_admin
from app.db.session import get_db
from app.schemas.insurance_company import (
    CreateInsuranceCompanyRequest,
    InsuranceCompanyAdminItem,
    UpdateInsuranceCompanyRequest,
)
from app.schemas.scan_keyword import CreateScanKeywordRequest, ScanKeywordItem, UpdateScanKeywordRequest
from app.schemas.super_admin import ActivityItem, AgencyOverviewItem, SuperAdminOverviewResponse
from app.schemas.user_context import CurrentUser
from app.services.insurance_company_service import InsuranceCompanyService
from app.services.scan_keyword_service import ScanKeywordService
from app.services.parser_performance_service import ParserPerformanceService
from app.services.super_admin_service import SuperAdminService

router = APIRouter()

@router.get("/overview", response_model=SuperAdminOverviewResponse)
def platform_overview(
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return SuperAdminService(db).get_overview()


@router.get("/agencies", response_model=list[AgencyOverviewItem])
def list_agencies(
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return SuperAdminService(db).list_agencies()


@router.get("/activity", response_model=list[ActivityItem])
def list_activity(
    agency_id: int | None = None,
    limit: int = Query(50, ge=1, le=200),
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return SuperAdminService(db).list_activity(limit=limit, agency_id=agency_id)


@router.get("/parser-performance")
def platform_parser_performance(
    agency_id: int | None = None,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    service = ParserPerformanceService(db)
    if agency_id is not None:
        return service.get_performance(agency_id)
    return service.get_platform_performance()


@router.get("/parser-report")
def parser_success_report(
    agency_id: int | None = None,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return ParserPerformanceService(db).get_parser_success_report(agency_id)


@router.get("/parser-report/export")
def export_parser_success_report(
    agency_id: int | None = None,
    format: str = Query("csv", pattern="^(csv|json)$"),
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    report = ParserPerformanceService(db).get_parser_success_report(agency_id)
    if format == "json":
        return report

    lines = [
        "Parser Success Report",
        f"Generated at,{report['generated_at']}",
        f"Scope,{report['scope_name']}",
        "",
        "SUMMARY",
        "Metric,Value",
        f"Overall parser score,{report['summary']['overall_parser_score']}",
        f"Extraction success rate,{report['summary']['extraction_success_rate']}",
        f"Field accuracy rate,{report['summary']['field_accuracy_rate']}",
        f"Total PDFs,{report['summary']['total_extractions']}",
        f"Confirmed policies,{report['summary']['confirmed_policies']}",
        f"Pending review,{report['summary']['pending_review']}",
        f"User reviews tracked,{report['summary']['total_reviews']}",
        f"Conversion rate,{report['funnel']['conversion_rate']}",
        "",
        "STATUS MATRIX",
        "Status,Count,Share rate",
    ]
    for row in report["status_matrix"]:
        lines.append(f"{row['status']},{row['count']},{row['share_rate']}")

    lines.extend(["", "BY AGENCY", "Agency,PDFs,Success rate,Field accuracy,Conversion,Pending"])
    for row in report["by_agency"]:
        lines.append(
            f"\"{row['agency_name']}\",{row['total_extractions']},{row['extraction_success_rate']},"
            f"{row['field_accuracy_rate']},{row['conversion_rate']},{row['pending_review']}"
        )

    lines.extend(["", "BY INSURER", "Insurer,PDFs,Extract OK,Field accuracy,Conversion,Reviews"])
    for row in report["by_insurer"]:
        lines.append(
            f"\"{row.get('company_name') or row['company_code']}\",{row['extractions']},"
            f"{row['extraction_success_rate']},{row['field_accuracy_rate']},"
            f"{row['conversion_rate']},{row['reviews']}"
        )

    lines.extend(["", "BY FIELD", "Field,Comparisons,Changes,Accuracy rate,Change rate"])
    for row in report["by_field"]:
        accuracy = "" if row["accuracy_rate"] is None else row["accuracy_rate"]
        change = "" if row["change_rate"] is None else row["change_rate"]
        lines.append(f"{row['field_name']},{row['comparisons']},{row['changes']},{accuracy},{change}")

    lines.extend(["", "BY SOURCE", "Source,Reviews,Comparisons,Changes,Accuracy rate"])
    for row in report["by_source"]:
        lines.append(
            f"{row['source']},{row['reviews']},{row['comparisons']},{row['changes']},{row['accuracy_rate']}"
        )

    return PlainTextResponse("\n".join(lines), media_type="text/csv")


@router.get("/insurance-companies", response_model=list[InsuranceCompanyAdminItem])
def list_insurance_companies_admin(
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return InsuranceCompanyService(db).list_all()


@router.get("/insurance-companies/parser-keys")
def list_parser_keys(
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return {"parser_keys": InsuranceCompanyService(db).list_parser_keys()}


@router.post("/insurance-companies", response_model=InsuranceCompanyAdminItem)
def create_insurance_company(
    payload: CreateInsuranceCompanyRequest,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return InsuranceCompanyService(db).create(
        name=payload.name,
        code=payload.code,
        parser_key=payload.parser_key,
        is_active=payload.is_active,
    )


@router.patch("/insurance-companies/{company_id}", response_model=InsuranceCompanyAdminItem)
def update_insurance_company(
    company_id: int,
    payload: UpdateInsuranceCompanyRequest,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    data = payload.model_dump(exclude_unset=True)
    return InsuranceCompanyService(db).update(company_id, **data)


@router.delete("/insurance-companies/{company_id}")
def delete_insurance_company(
    company_id: int,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    InsuranceCompanyService(db).delete(company_id)
    return {"ok": True}


@router.get("/scan-keywords", response_model=list[ScanKeywordItem])
def list_scan_keywords(
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return ScanKeywordService(db).list_all()


@router.post("/scan-keywords", response_model=ScanKeywordItem)
def create_scan_keyword(
    payload: CreateScanKeywordRequest,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return ScanKeywordService(db).create_manual(
        insurance_company_id=payload.insurance_company_id,
        keyword=payload.keyword,
    )


@router.patch("/scan-keywords/{keyword_id}", response_model=ScanKeywordItem)
def update_scan_keyword(
    keyword_id: int,
    payload: UpdateScanKeywordRequest,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    return ScanKeywordService(db).update(keyword_id, keyword=payload.keyword)


@router.delete("/scan-keywords/{keyword_id}")
def delete_scan_keyword(
    keyword_id: int,
    current_user: CurrentUser = Depends(require_super_admin),
    db: Session = Depends(get_db),
):
    ScanKeywordService(db).delete(keyword_id)
    return {"ok": True}
