from __future__ import annotations

import logging
from typing import Any

from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile
from fastapi.responses import Response

from app.modules.auth.presentation.auth import get_current_user
from app.modules.invoices.application.invoice_processing_service import InvoiceProcessingService

from .models import (
    DirectXmlUploadRequest,
    FidicIpcInvoiceRequest,
    IssueInvoiceRequest,
    ReconcileRequest,
    SendEmailInvoiceRequest,
)

logger = logging.getLogger("dscons.api.invoices")
router = APIRouter(prefix="/v1/erp/invoices", tags=["E-Invoices & Tax Management"])
invoice_router = router
invoice_service = InvoiceProcessingService()


@invoice_router.post("/upload-xml", summary="Tải lên và bóc tách File XML Hóa Đơn Gốc")
async def upload_invoice_xml(
    files: list[UploadFile] = File(None),
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Bóc tách tự động 1 hoặc nhiều file XML hóa đơn gốc (NĐ123 hoặc meInvoice)."""
    if not files:
        raise HTTPException(
            status_code=400, detail="Vui lòng đính kèm ít nhất 1 file XML."
        )

    user_name = (
        current_user.get("full_name") or current_user.get("email") or "SuperAdmin"
    )
    results = []
    success_count = 0
    dup_count = 0

    for file in files:
        if not file.filename.lower().endswith(".xml"):
            results.append(
                {
                    "filename": file.filename,
                    "status": "error",
                    "message": "Chỉ chấp nhận file định dạng .xml",
                }
            )
            continue

        try:
            content_bytes = await file.read()
            parsed = invoice_service.parse_xml_content(
                content_bytes, source_channel="manual_xml"
            )
            res = invoice_service.save_invoice(
                parsed, user_id=user_name, auto_reconcile=True
            )
            res["filename"] = file.filename
            if res.get("status") == "success":
                success_count += 1
            elif res.get("status") == "duplicate":
                dup_count += 1
            results.append(res)
        except Exception as e:
            results.append(
                {
                    "filename": file.filename,
                    "status": "error",
                    "message": f"Lỗi bóc tách XML: {e!s}",
                }
            )

    return {
        "status": "success",
        "message": f"Đã xử lý {len(files)} file: {success_count} hóa đơn mới nạp thành công, {dup_count} hóa đơn đã tồn tại.",
        "success_count": success_count,
        "duplicate_count": dup_count,
        "results": results,
    }


@invoice_router.post("/upload-xml-raw", summary="Nạp trực tiếp nội dung XML hóa đơn")
async def upload_invoice_xml_raw(
    req: DirectXmlUploadRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Nạp trực tiếp XML string từ webhook / email reader."""
    try:
        user_name = current_user.get("full_name") or "SuperAdmin"
        parsed = invoice_service.parse_xml_content(
            req.xml_content, source_channel=req.source_channel
        )
        res = invoice_service.save_invoice(
            parsed, user_id=user_name, auto_reconcile=True
        )
        return res
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Lỗi phân tích XML: {e!s}")


@invoice_router.post(
    "/{invoice_id}/reconcile", summary="Khớp nối Hóa Đơn với Dự Án & WBS"
)
async def reconcile_invoice(
    invoice_id: str,
    req: ReconcileRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Gán hóa đơn vào dự án cụ thể để theo dõi chi phí thực tế EVM / giải ngân."""
    user_name = current_user.get("full_name") or "SuperAdmin"
    res = invoice_service.reconcile_invoice(
        invoice_id=invoice_id,
        project_id=req.project_id,
        wbs_id=req.wbs_id,
        user_id=user_name,
    )
    if res.get("status") == "error":
        raise HTTPException(status_code=400, detail=res.get("message"))
    return res


@invoice_router.get(
    "/reports/vat-schedule",
    summary="Lấy bảng kê thuế GTGT đầu vào & đầu ra (Mẫu 01-1 & 01-2/GTGT)",
)
async def get_vat_schedule(
    from_date: str | None = Query(None, description="Từ ngày (YYYY-MM-DD)"),
    to_date: str | None = Query(None, description="Đến ngày (YYYY-MM-DD)"),
    vat_period: str | None = Query(None, description="Tên kỳ kê khai"),
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Tổng hợp bảng kê hóa đơn mua vào (01-1) và bán ra (01-2) phân nhóm theo thuế suất 0%, 5%, 8%, 10%, KCT."""
    schedule = invoice_service.get_vat_tax_schedule(
        from_date=from_date, to_date=to_date, vat_period=vat_period
    )
    return {"status": "success", "schedule": schedule}


@invoice_router.get(
    "/reports/vat-schedule/export",
    summary="Xuất file CSV bảng kê thuế GTGT (Mẫu 01-1 & 01-2/GTGT)",
)
async def export_vat_schedule_csv(
    from_date: str | None = Query(None, description="Từ ngày (YYYY-MM-DD)"),
    to_date: str | None = Query(None, description="Đến ngày (YYYY-MM-DD)"),
    direction: str = Query("all", description="Loại bảng kê: all, input, output"),
    current_user: dict[str, Any] = Depends(get_current_user),
):
    """Xuất trực tiếp file CSV chuẩn UTF-8 BOM để mở trên Microsoft Excel."""
    csv_content = invoice_service.export_vat_schedule_csv(
        from_date=from_date, to_date=to_date, direction=direction
    )
    f_tag = from_date.replace("-", "") if from_date else "dau_ky"
    t_tag = to_date.replace("-", "") if to_date else "hien_tai"
    filename = f"Bang_Ke_Thue_GTGT_{f_tag}_{t_tag}.csv"
    return Response(
        content=csv_content.encode("utf-8-sig"),
        media_type="text/csv",
        headers={"Content-Disposition": f"attachment; filename={filename}"},
    )


@invoice_router.post(
    "/output/ipc-invoice",
    summary="Lập hóa đơn bán ra / Đề nghị thanh toán đợt IPC FIDIC",
)
async def create_ipc_invoice(
    req: FidicIpcInvoiceRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Lập hóa đơn đầu ra từ khối lượng nghiệm thu hoàn thành WBS có khấu trừ tạm ứng & bảo hành 5%."""
    user_name = (
        current_user.get("full_name") or current_user.get("email") or "SuperAdmin"
    )
    items_dicts = [itm.model_dump() for itm in req.wbs_items]
    res = invoice_service.create_fidic_ipc_output_invoice(
        project_id=req.project_id,
        wbs_items=items_dicts,
        advance_deduction_pct=req.advance_deduction_pct,
        retention_pct=req.retention_pct,
        vat_rate_pct=req.vat_rate_pct,
        buyer_tax_code=req.buyer_tax_code,
        buyer_name=req.buyer_name,
        buyer_address=req.buyer_address,
        invoice_number=req.invoice_number,
        invoice_series=req.invoice_series,
        user_name=user_name,
        notes=req.notes,
    )
    if res.get("status") == "error":
        raise HTTPException(status_code=400, detail=res.get("message"))
    return res


@invoice_router.get(
    "/{invoice_id}/tax-risk-audit",
    summary="Rà soát rủi ro thuế & toàn vẹn chữ ký số của hóa đơn",
)
async def audit_invoice_tax_risk(
    invoice_id: str, current_user: dict[str, Any] = Depends(get_current_user)
) -> dict[str, Any]:
    """Kiểm tra chữ ký số, sai lệch thuế suất và độ trễ ký số theo Nghị định 123."""
    res = invoice_service.audit_invoice_tax_risk(invoice_id)
    if res.get("status") == "error":
        raise HTTPException(status_code=404, detail=res.get("message"))
    return {"status": "success", "audit": res, "audit_report": res}


@invoice_router.get(
    "/{invoice_id}/export-xml",
    summary="Xuất File XML Hóa Đơn Chuẩn MISA meInvoice / NĐ123",
)
async def export_invoice_xml(
    invoice_id: str, current_user: dict[str, Any] = Depends(get_current_user)
):
    """Xuất trực tiếp file XML hóa đơn gốc hoặc sinh file XML chuẩn MISA meInvoice theo Nghị định 123."""
    inv = invoice_service.get_invoice_detail(invoice_id)
    if not inv:
        raise HTTPException(status_code=404, detail="Không tìm thấy hóa đơn điện tử.")

    xml_content = inv.get("xml_raw_content")
    if not xml_content or not xml_content.strip():
        items = inv.get("items", [])
        xml_content = invoice_service.generate_misa_xml(inv, items)

    inv_series = inv.get("invoice_series", "1C26TDS")
    inv_num = inv.get("invoice_number", "00000001")
    filename = f"Hoa_Don_{inv_series}_{inv_num}.xml"

    return Response(
        content=xml_content.encode("utf-8"),
        media_type="application/xml",
        headers={"Content-Disposition": f"attachment; filename={filename}"},
    )


@invoice_router.get(
    "/{invoice_id}/html-view",
    summary="Bản Thể Hiện Hóa Đơn Điện Tử Khổ A4 (Chuẩn MISA meInvoice)",
)
async def get_invoice_html_view(
    invoice_id: str, current_user: dict[str, Any] = Depends(get_current_user)
):
    """Trả về trang HTML bản thể hiện hóa đơn điện tử khổ A4 sang trọng (hỗ trợ in ấn và lưu PDF)."""
    html = invoice_service.render_misa_invoice_html(invoice_id)
    from fastapi.responses import HTMLResponse

    return HTMLResponse(content=html, status_code=200)


@invoice_router.post(
    "/issue-output-invoice",
    summary="Lập & Xuất Hóa Đơn Bán Ra Mới (Chuẩn MISA meInvoice)",
)
async def issue_output_invoice(
    req: IssueInvoiceRequest, current_user: dict[str, Any] = Depends(get_current_user)
) -> dict[str, Any]:
    """Lập và xuất hóa đơn điện tử bán ra mới (hỗ trợ cả Ký phát hành ngay hoặc Lưu nháp theo chuẩn MISA meInvoice)."""
    user_name = (
        current_user.get("full_name") or current_user.get("email") or "SuperAdmin"
    )
    items_dicts = [itm.model_dump() for itm in req.items]

    res = invoice_service.issue_output_invoice(
        buyer_name=req.buyer_name,
        buyer_tax_code=req.buyer_tax_code,
        buyer_address=req.buyer_address,
        buyer_email=req.buyer_email,
        buyer_phone=req.buyer_phone,
        buyer_representative=req.buyer_representative,
        items=items_dicts,
        vat_rate_percent=req.vat_rate_percent,
        invoice_series=req.invoice_series,
        invoice_number=req.invoice_number,
        issue_date=req.issue_date,
        payment_method=req.payment_method,
        notes=req.notes,
        project_id=req.project_id,
        is_draft=req.is_draft,
        user_name=user_name,
    )
    if res.get("status") == "error":
        raise HTTPException(status_code=400, detail=res.get("message"))

    # Tự động gửi email nếu được yêu cầu và không phải bản nháp
    if (
        req.send_email_to_buyer
        and req.buyer_email
        and not req.is_draft
        and res.get("invoice_id")
    ):
        email_res = await invoice_service.send_invoice_to_buyer_email(
            res["invoice_id"], req.buyer_email
        )
        res["email_result"] = email_res

    return res


@invoice_router.post(
    "/{invoice_id}/sign-and-issue", summary="Ký Số & Phát Hành Hóa Đơn Nháp"
)
async def sign_and_issue_invoice_endpoint(
    invoice_id: str, current_user: dict[str, Any] = Depends(get_current_user)
) -> dict[str, Any]:
    """Ký số điện tử bằng chứng thư số của Công ty Định Sơn và chính thức phát hành hóa đơn nháp."""
    user_name = (
        current_user.get("full_name") or current_user.get("email") or "SuperAdmin"
    )
    res = invoice_service.sign_and_issue_invoice(invoice_id, user_name=user_name)
    if res.get("status") == "error":
        raise HTTPException(status_code=400, detail=res.get("message"))
    return res


@invoice_router.post(
    "/{invoice_id}/send-email", summary="Gửi Email Hóa Đơn Điện Tử Cho Khách Hàng"
)
async def send_invoice_email_endpoint(
    invoice_id: str,
    req: SendEmailInvoiceRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Gửi email thông báo phát hành hóa đơn điện tử kèm thông tin chi tiết đến email người mua."""
    res = await invoice_service.send_invoice_to_buyer_email(invoice_id, req.buyer_email)
    if res.get("status") == "error":
        raise HTTPException(status_code=400, detail=res.get("message"))
    return res


@invoice_router.get(
    "/export/misa-excel", summary="Xuất Bảng Kê Hóa Đơn Chuẩn Excel MISA (.xlsx)"
)
async def export_misa_excel(
    from_date: str | None = Query(None, description="Từ ngày (YYYY-MM-DD)"),
    to_date: str | None = Query(None, description="Đến ngày (YYYY-MM-DD)"),
    direction: str = Query("all", description="Loại hóa đơn: all, input, output"),
    current_user: dict[str, Any] = Depends(get_current_user),
):
    """Xuất file Excel (.xlsx) danh sách hóa đơn theo chuẩn bảng kê nhập liệu phần mềm MISA."""
    excel_bytes = invoice_service.export_misa_excel(
        from_date=from_date,
        to_date=to_date,
        direction=direction,
    )
    f_tag = from_date.replace("-", "") if from_date else "dau_ky"
    t_tag = to_date.replace("-", "") if to_date else "hien_tai"
    filename = f"Bang_Ke_Hoa_Don_MISA_{f_tag}_{t_tag}.xlsx"

    return Response(
        content=excel_bytes,
        media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        headers={"Content-Disposition": f"attachment; filename={filename}"},
    )
