from __future__ import annotations

import logging
import re
from pathlib import Path
from typing import Any

from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import FileResponse

from app.modules.auth.presentation.auth import get_current_user, require_role
from app.core.postgres.erp_client import ErpDatabaseClient

logger = logging.getLogger("dscons.api.erp.documents_stream_diff")
router = APIRouter()
erp_client = ErpDatabaseClient()


@router.get("/documents/{doc_id}/versions")
def get_document_versions(
    doc_id: str, current_user: dict[str, Any] = Depends(get_current_user)
) -> list[dict[str, Any]]:
    """Lấy danh sách toàn bộ các phiên bản trong chùm văn bản."""
    return erp_client.list_document_versions(doc_id)


@router.get("/documents/{doc_id}/diff/{compare_doc_id}")
async def get_document_diff(
    doc_id: str,
    compare_doc_id: str,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Chạy so sánh AI Diffing giữa 2 phiên bản văn bản bất kỳ."""
    doc_a = erp_client.get_document(doc_id)
    doc_b = erp_client.get_document(compare_doc_id)
    if not doc_a or not doc_b:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy văn bản để so sánh."
        )

    doc_service = DocumentProcessingService()
    text_a = (
        doc_service.extract_text(
            doc_a.get("file_path", ""), doc_a.get("file_format", "pdf")
        )
        if doc_a.get("file_path")
        else doc_a.get("summary_content", "")
    )
    text_b = (
        doc_service.extract_text(
            doc_b.get("file_path", ""), doc_b.get("file_format", "pdf")
        )
        if doc_b.get("file_path")
        else doc_b.get("summary_content", "")
    )

    diff_result = await doc_service.compare_document_versions(
        old_text=text_a,
        new_text=text_b,
        filename_old=f"{doc_a.get('document_code')} ({doc_a.get('version_number', 'v1.0')})",
        filename_new=f"{doc_b.get('document_code')} ({doc_b.get('version_number', 'v1.1')})",
    )

    return {"doc_a": doc_a, "doc_b": doc_b, "diff_analysis": diff_result}


@router.get("/documents/{doc_id}/audit-details")
def get_document_audit_details(
    doc_id: str, current_user: dict[str, Any] = Depends(get_current_user)
) -> dict[str, Any]:
    """Lấy chi tiết điểm tin cậy OCR, cờ cảnh báo (flags) và nhận xét của kiểm toán viên Thủy."""
    doc = erp_client.get_document(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Không tìm thấy văn bản.")
    return {
        "doc_id": doc["id"],
        "document_code": doc.get("document_code"),
        "ocr_confidence_score": doc.get("ocr_confidence_score", 85),
        "quarantine_status": doc.get("quarantine_status", "clear"),
        "ocr_validation_flags": doc.get("ocr_validation_flags") or [],
        "cross_audit_summary": doc.get("cross_audit_summary")
        or "Chưa có nhận xét kiểm toán.",
        "verified_by_user_id": doc.get("verified_by_user_id"),
        "verified_at": doc.get("verified_at"),
    }


@router.get("/documents/{doc_id}/stream")
def stream_document_file(
    doc_id: str,
    download: bool = False,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "pm", "site_engineer", "accountant", "viewer"]
        )
    ),
):
    """Truy cập file văn bản an toàn qua xác thực RBAC, ngăn chặn truy cập công khai."""
    doc = erp_client.get_document(doc_id)
    if not doc or not doc.get("file_path"):
        raise HTTPException(status_code=404, detail="Không tìm thấy file văn bản.")

    file_path = Path(doc["file_path"])
    if not file_path.exists():
        raise HTTPException(
            status_code=404, detail="File vật lý không tồn tại trên hệ thống lưu trữ."
        )

    media_type_map = {
        "pdf": "application/pdf",
        "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "txt": "text/plain; charset=utf-8",
        "png": "image/png",
        "jpg": "image/jpeg",
        "jpeg": "image/jpeg",
    }
    fmt = str(doc.get("file_format", "pdf")).lower()
    media_type = media_type_map.get(fmt, "application/octet-stream")

    disposition = "attachment" if download else "inline"
    safe_title = re.sub(
        r"[^a-zA-Z0-9_\.-]", "_", str(doc.get("document_title", "document"))
    )
    filename = f"{safe_title}.{fmt}"

    return FileResponse(
        path=str(file_path),
        media_type=media_type,
        headers={"Content-Disposition": f'{disposition}; filename="{filename}"'},
    )
