from __future__ import annotations

import logging
from typing import Any

from fastapi import (
    APIRouter,
    Depends,
    HTTPException,
    Query,
    status,
)
from fastapi.responses import StreamingResponse

from app.modules.auth.presentation.auth import require_role
from app.core.postgres.erp_client import ErpDatabaseClient
from app.modules.takeoff.application.drawing_takeoff_service import get_drawing_takeoff_service

from .schemas import (
    ApplyChatCorrectionsRequest,
    ChatTrainRequest,
    LearnedRuleCreateRequest,
)

logger = logging.getLogger("dscons.api.takeoff.chat")
router = APIRouter()


@router.post(
    "/{takeoff_id}/chat-train",
    summary="Trò chuyện & Huấn luyện Trực tiếp AI Quỳnh QS khi bóc tách sai",
)
async def chat_train_ai_quynh_endpoint(
    takeoff_id: str,
    req: ChatTrainRequest,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Gửi phản hồi, chỉ đạo lỗi sai cho AI Quỳnh QS. AI Quỳnh sẽ tiếp thu, đề xuất danh mục hiệu chỉnh và tự động đúc kết Quy tắc rút kinh nghiệm vĩnh viễn."""
    user_msg = req.get_message()
    if not user_msg:
        raise HTTPException(
            status_code=400, detail="Vui lòng nhập nội dung chỉ đạo / huấn luyện."
        )

    service = get_drawing_takeoff_service()
    user_display = (
        req.sender_role
        or current_user.get("full_name")
        or current_user.get("username")
        or "Kỹ Sư Trưởng QS"
    )
    try:
        res = await service.chat_train_ai_quynh(
            takeoff_id=takeoff_id,
            user_message=user_msg,
            current_user_name=user_display,
            auto_apply=req.should_auto_apply(),
        )
        res["data"] = dict(res)
        return res
    except ValueError as val_err:
        raise HTTPException(status_code=404, detail=str(val_err))
    except Exception as exc:
        logger.error("[TAKEOFF] Lỗi huấn luyện AI Quỳnh: %s", exc)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi huấn luyện AI Quỳnh: {exc!s}"
        )


@router.post(
    "/{takeoff_id}/chat-train-stream",
    summary="Phản hồi Trực tiếp Thời Gian Thực (SSE Stream) của AI Quỳnh QS",
)
async def chat_train_ai_quynh_stream_endpoint(
    takeoff_id: str,
    req: ChatTrainRequest,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
):
    """Gửi chỉ đạo và nhận phản hồi SSE Realtime Streaming từ AI Quỳnh từng token không độ trễ."""
    user_msg = req.get_message()
    if not user_msg:
        raise HTTPException(
            status_code=400, detail="Vui lòng nhập nội dung chỉ đạo / huấn luyện."
        )

    service = get_drawing_takeoff_service()
    user_display = (
        req.sender_role
        or current_user.get("full_name")
        or current_user.get("username")
        or "Kỹ Sư Trưởng QS"
    )

    return StreamingResponse(
        service.chat_train_ai_quynh_stream(
            takeoff_id=takeoff_id,
            user_message=user_msg,
            current_user_name=user_display,
            auto_apply=req.should_auto_apply(),
        ),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",
        },
    )


@router.get(
    "/{takeoff_id}/chat-history",
    summary="Lấy Toàn Bộ Lịch Sử Hội Thoại Huấn Luyện của Hồ Sơ Bản Vẽ",
)
def get_takeoff_chat_history(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Lấy danh sách tin nhắn hội thoại huấn luyện giữa Kỹ sư QS và AI Quỳnh."""
    client = ErpDatabaseClient()
    messages = client.list_takeoff_chat_messages(takeoff_id)
    return {
        "status": "success",
        "takeoff_id": takeoff_id,
        "data": messages,
        "messages": messages,
        "count": len(messages),
    }


@router.delete(
    "/{takeoff_id}/chat-history",
    summary="Làm Mới / Xóa Lịch Sử Hội Thoại Huấn Luyện của Bản Vẽ",
)
def clear_takeoff_chat_history_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Xóa sạch lịch sử chat để bắt đầu phiên huấn luyện mới."""
    client = ErpDatabaseClient()
    client.clear_takeoff_chat_history(takeoff_id)
    return {
        "status": "success",
        "message": "Đã làm mới khung hội thoại huấn luyện thành công.",
    }


@router.post(
    "/{takeoff_id}/apply-chat-corrections",
    summary="1-Click Áp Dụng Danh Mục BoQ Hiệu Chỉnh Từ AI Quỳnh vào Bảng Dự Toán",
)
def apply_chat_corrections_endpoint(
    takeoff_id: str,
    req: ApplyChatCorrectionsRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Cập nhật các dòng BoQ đề xuất từ AI Quỳnh vào bảng bóc tách chính thức."""
    items = req.get_items()
    if not items:
        raise HTTPException(status_code=400, detail="Không có hạng mục nào để áp dụng.")

    client = ErpDatabaseClient()
    res = client.apply_chat_suggested_corrections(
        takeoff_id=takeoff_id,
        suggested_items=items,
        message_id=req.message_id,
    )
    return res


@router.get(
    "/learned-rules/list",
    summary="Danh Sách Toàn Bộ Quy Tắc Rút Kinh Nghiệm Đã Học Của AI Quỳnh QS",
)
def list_learned_rules_endpoint(
    drawing_type: str | None = Query(None, description="Lọc theo loại công trình"),
    category: str | None = Query(None, description="Lọc theo nhóm công tác"),
    is_active: bool = Query(True, description="Chỉ lấy quy tắc đang kích hoạt"),
    current_user: dict[str, Any] = Depends(
        require_role(
            ["superadmin", "director", "manager", "engineer", "staff"]
        )
    ),
) -> dict[str, Any]:
    """Xem danh sách các quy tắc rút kinh nghiệm mà AI Quỳnh đã học được từ các kỹ sư."""
    client = ErpDatabaseClient()
    rules = client.list_takeoff_learned_rules(
        drawing_type=drawing_type, category=category, is_active=is_active
    )
    return {
        "status": "success",
        "data": rules,
        "rules": rules,
        "count": len(rules),
    }


@router.post(
    "/learned-rules/create",
    summary="Thêm Thủ Công Quy Tắc Rút Kinh Nghiệm Cho AI Quỳnh",
    status_code=status.HTTP_201_CREATED,
)
def create_learned_rule_endpoint(
    req: LearnedRuleCreateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Thêm một quy tắc định mức hoặc kinh nghiệm mới vào bộ nhớ của AI Quỳnh."""
    client = ErpDatabaseClient()
    user_display = (
        req.created_by_role
        or current_user.get("full_name")
        or current_user.get("username")
        or "Kỹ Sư Trưởng QS"
    )
    created = client.save_takeoff_learned_rule(
        drawing_type=req.drawing_type,
        category=req.get_category(),
        error_pattern=req.get_error_pattern(),
        correction_rule=req.get_correction_rule(),
        learned_from_user=user_display,
        confidence_weight=req.confidence_weight,
    )
    return {
        "status": "success",
        "message": "Đã thêm quy tắc rút kinh nghiệm thành công cho AI Quỳnh!",
        "data": created,
        "rule": created,
    }


@router.delete(
    "/learned-rules/{rule_id}",
    summary="Xóa Quy Tắc Rút Kinh Nghiệm Khỏi Bộ Nhớ Của AI Quỳnh",
)
def delete_learned_rule_endpoint(
    rule_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Xóa quy tắc rút kinh nghiệm."""
    client = ErpDatabaseClient()
    ok = client.delete_takeoff_learned_rule(rule_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Không tìm thấy quy tắc để xóa.")
    return {
        "status": "success",
        "message": "Đã xóa quy tắc rút kinh nghiệm thành công.",
    }


@router.post(
    "/{takeoff_id}/reapply-rules-and-prices",
    summary="1-Click Tái Áp Dụng Toàn Bộ Quy Tắc Rút Kinh Nghiệm & Đơn Giá Sở Xây Dựng 2026",
)
def reapply_rules_and_prices_endpoint(
    takeoff_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Tái áp dụng quy tắc rút kinh nghiệm đã học và đồng bộ lại đơn giá SXD mới nhất cho hồ sơ bóc tách."""
    service = get_drawing_takeoff_service()
    try:
        res = service.reapply_rules_and_state_prices_to_takeoff(takeoff_id)
        return res
    except ValueError as val_err:
        raise HTTPException(status_code=404, detail=str(val_err))
    except Exception as exc:
        logger.error("[TAKEOFF] Lỗi khi tái áp dụng quy tắc & đơn giá: %s", exc)
        raise HTTPException(
            status_code=500, detail=f"Lỗi khi tái áp dụng quy tắc: {exc!s}"
        )


@router.post(
    "/learned-rules/deduplicate",
    summary="Gộp và Tối Ưu Hóa Bộ Nhớ Tri Thức (Deduplicate & Clean up)",
)
def deduplicate_learned_rules_endpoint(
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "manager", "engineer"])
    ),
) -> dict[str, Any]:
    """Tự động rà soát, gộp các quy tắc trùng lặp và cộng dồn số lần áp dụng/ghi nhớ của AI Quỳnh."""
    client = ErpDatabaseClient()
    res = client.deduplicate_takeoff_learned_rules()
    return {
        "status": "success",
        "message": f"Đã gộp thành công {res.get('duplicate_groups_merged', 0)} nhóm quy tắc trùng lặp và dọn dẹp {res.get('deleted_duplicate_rules', 0)} bản ghi thừa.",
        "data": res,
    }


@router.get("/training/drills")
async def get_drills():
    return [{"drill_id": "DRILL-NVH-DAITHANG-2026"}]

@router.post("/training/run-drill")
async def run_drill(data: dict):
    return {"status": "completed", "drill_id": data.get("drill_id", ""), "total_ground_truth_items": 1}

@router.get("/training/scorecard")
async def get_scorecard(drill_id: str):
    return {"score": 95, "drill_id": drill_id}
