"""Project and WBS Management API endpoints."""

from __future__ import annotations

from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel

from app.modules.auth.presentation.auth import get_current_user, require_role
from app.core.postgres.project_crud_repository import ProjectCrudRepository
from app.modules.core.application.ai_wbs_generator_service import AIWbsGeneratorService

router = APIRouter(prefix="/v1/erp/projects", tags=["Project & WBS Management"])


# ------------------------------------------------------------------------------
# Pydantic Request Models
# ------------------------------------------------------------------------------
class ProjectCreateRequest(BaseModel):
    project_code: str | None = None
    project_name: str
    client_name: str | None = None
    location: str | None = None
    description: str | None = None
    project_type: str | None = "Dân dụng & Hạ tầng"
    status: str | None = "planning"
    priority: str | None = "medium"
    budget_amount: float | None = 0.0
    contract_value: float | None = 0.0
    start_date: str | None = None
    expected_end_date: str | None = None
    project_manager_id: str | None = None
    notes: str | None = None
    contract_number: str | None = None
    contract_type: str | None = "Trọn gói"
    contract_duration_days: int | None = 180
    advance_payment_percent: float | None = 10.0
    retention_percent: float | None = 5.0
    contract_signing_date: str | None = None
    contract_schedule_json: list[dict[str, Any]] | None = None
    wbs_items: list[dict[str, Any]] | None = None
    milestones: list[dict[str, Any]] | None = None


class ProjectUpdateRequest(BaseModel):
    project_name: str | None = None
    client_name: str | None = None
    location: str | None = None
    description: str | None = None
    project_type: str | None = None
    status: str | None = None
    priority: str | None = None
    budget_amount: float | None = None
    contract_value: float | None = None
    start_date: str | None = None
    expected_end_date: str | None = None
    actual_end_date: str | None = None
    project_manager_id: str | None = None
    progress_percent: int | None = None
    notes: str | None = None
    contract_number: str | None = None
    contract_type: str | None = None
    contract_duration_days: int | None = None
    advance_payment_percent: float | None = None
    retention_percent: float | None = None
    contract_signing_date: str | None = None
    contract_schedule_json: list[dict[str, Any]] | None = None


class WbsItemCreateRequest(BaseModel):
    parent_wbs_id: str | None = None
    wbs_code: str
    task_name: str
    task_type: str = "task"
    unit: str | None = None
    quantity: float | None = 0.0
    unit_price_vnd: float | None = 0.0
    total_amount_vnd: float | None = 0.0
    start_date: str | None = None
    end_date: str | None = None
    duration_days: int = 1
    progress_percent: int = 0
    status: str = "todo"
    assigned_role: str | None = None
    sort_order: int = 0
    notes: str | None = None


class WbsItemUpdateRequest(BaseModel):
    task_name: str | None = None
    task_type: str | None = None
    unit: str | None = None
    quantity: float | None = None
    unit_price_vnd: float | None = None
    total_amount_vnd: float | None = None
    start_date: str | None = None
    end_date: str | None = None
    duration_days: int | None = None
    progress_percent: int | None = None
    status: str | None = None
    assigned_role: str | None = None
    sort_order: int | None = None
    notes: str | None = None


class AIGenerateWbsRequest(BaseModel):
    project_name: str
    project_type: str = "Dân dụng & Hạ tầng"
    contract_value: float = 0.0
    start_date: str | None = None
    duration_days: int = 180
    contract_schedule_text: str | None = None


# ------------------------------------------------------------------------------
# API Endpoints
# ------------------------------------------------------------------------------
@router.get("")
def list_projects(
    status: str | None = Query(default=None),
    search: str | None = Query(default=None),
    current_user: dict[str, Any] = Depends(get_current_user),
) -> list[dict[str, Any]]:
    """Lấy danh sách toàn bộ dự án kèm KPI tiến độ WBS."""
    repo = ProjectCrudRepository()
    return repo.list_projects(status=status, search=search)


@router.get("/{project_id_or_code}")
def get_project_detail(
    project_id_or_code: str,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Xem chi tiết dự án kèm cây WBS, Milestones, Timeline và Rủi ro."""
    repo = ProjectCrudRepository()
    detail = repo.get_project_detail(project_id_or_code)
    if not detail:
        raise HTTPException(status_code=404, detail="Không tìm thấy dự án")
    return detail


@router.post("", status_code=201, operation_id="create_project_full_erp")
def create_project(
    payload: ProjectCreateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "pm"])
    ),
) -> dict[str, Any]:
    """Tạo mới dự án kèm WBS ban đầu (ERP full-featured endpoint)."""
    repo = ProjectCrudRepository()
    return repo.create_project(payload.model_dump(exclude_none=True))



@router.put("/{project_id}")
def update_project(
    project_id: str,
    payload: ProjectUpdateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "pm", "site_engineer"])
    ),
) -> dict[str, Any]:
    """Cập nhật thông tin dự án & hợp đồng."""
    repo = ProjectCrudRepository()
    return repo.update_project(project_id, payload.model_dump(exclude_none=True))


@router.delete("/{project_id}")
def delete_project(
    project_id: str,
    current_user: dict[str, Any] = Depends(require_role(["superadmin", "director"])),
) -> dict[str, Any]:
    """Xóa dự án."""
    repo = ProjectCrudRepository()
    ok = repo.delete_project(project_id)
    if not ok:
        raise HTTPException(
            status_code=404, detail="Không thể xóa dự án hoặc không tìm thấy"
        )
    return {"status": "success", "message": f"Đã xóa dự án {project_id}"}


@router.post("/{project_id}/wbs", status_code=201)
def create_wbs_item(
    project_id: str,
    payload: WbsItemCreateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "pm", "site_engineer"])
    ),
) -> dict[str, Any]:
    """Thêm một công việc WBS mới vào dự án."""
    repo = ProjectCrudRepository()
    return repo.create_wbs_item(project_id, payload.model_dump(exclude_none=True))


@router.put("/wbs/{wbs_id}")
def update_wbs_item(
    wbs_id: str,
    payload: WbsItemUpdateRequest,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "pm", "site_engineer"])
    ),
) -> dict[str, Any]:
    """Cập nhật tiến độ / trạng thái công việc WBS."""
    repo = ProjectCrudRepository()
    item = repo.update_wbs_item(wbs_id, payload.model_dump(exclude_none=True))
    if not item:
        raise HTTPException(status_code=404, detail="Không tìm thấy công việc WBS")
    return item


@router.delete("/wbs/{wbs_id}")
def delete_wbs_item(
    wbs_id: str,
    current_user: dict[str, Any] = Depends(
        require_role(["superadmin", "director", "pm"])
    ),
) -> dict[str, Any]:
    """Xóa công việc WBS."""
    repo = ProjectCrudRepository()
    ok = repo.delete_wbs_item(wbs_id)
    if not ok:
        raise HTTPException(
            status_code=404, detail="Không tìm thấy công việc WBS để xóa"
        )
    return {"status": "success", "message": f"Đã xóa công việc WBS {wbs_id}"}


@router.post("/ai-generate-wbs")
def ai_generate_wbs(
    payload: AIGenerateWbsRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Nhân viên AI Phúc & Thảo tự động tính toán Timeline CPM và phân rã WBS từ biểu giá hợp đồng."""
    service = AIWbsGeneratorService()
    return service.generate_timeline_and_wbs(
        project_name=payload.project_name,
        project_type=payload.project_type,
        contract_value=payload.contract_value,
        start_date=payload.start_date,
        duration_days=payload.duration_days,
        contract_schedule_text=payload.contract_schedule_text,
    )
