from __future__ import annotations

from datetime import UTC, datetime, timedelta
from typing import Annotated, Literal

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session

from app.api.deps import CurrentUserContext, get_current_user, get_db
from app.schemas.cfo_value import CfoValueDashboardRead, CfoValueFiltersRead
from app.services.cfo_value_analytics import CfoValueAnalyticsService
from app.services.savings_access_policy import SavingsPermissionError

router = APIRouter(prefix="/analytics")
DbSession = Annotated[Session, Depends(get_db)]
CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)]


@router.get(
    "/cfo-value",
    response_model=CfoValueDashboardRead,
    summary="查询 CFO 经营价值看板",
    description=(
        "仅汇总 Savings Ledger 中有基线、证据、去重和独立财务确认的价值事实；"
        "风险暴露、预计机会和待确认结果不会混入已确认现金节省。"
    ),
)
def get_cfo_value_dashboard(
    db: DbSession,
    current_user: CurrentUser,
    start: datetime | None = None,
    end: datetime | None = None,
    as_of: datetime | None = None,
    department_id: Annotated[str | None, Query(max_length=160)] = None,
    project_code: Annotated[str | None, Query(max_length=160)] = None,
    expense_type: Annotated[str | None, Query(max_length=80)] = None,
    supplier_id: Annotated[str | None, Query(max_length=160)] = None,
    city: Annotated[str | None, Query(max_length=160)] = None,
    owner_id: Annotated[str | None, Query(max_length=120)] = None,
    source_type: Annotated[str | None, Query(max_length=50)] = None,
    value_kind: Annotated[Literal["cash", "labor"] | None, Query()] = None,
) -> CfoValueDashboardRead:
    now = datetime.now(UTC)
    normalized_end = end or now
    normalized_start = start or (normalized_end - timedelta(days=90))
    normalized_as_of = as_of or now
    try:
        return CfoValueAnalyticsService(db).build_dashboard(
            current_user,
            start=normalized_start,
            end=normalized_end,
            as_of=normalized_as_of,
            filters=CfoValueFiltersRead(
                department_id=department_id,
                project_code=project_code,
                expense_type=expense_type,
                supplier_id=supplier_id,
                city=city,
                owner_id=owner_id,
                source_type=source_type,
                value_kind=value_kind,
            ),
        )
    except SavingsPermissionError as error:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=str(error),
        ) from error
    except (ValueError, PermissionError) as error:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(error),
        ) from error
