from __future__ import annotations

from typing import Annotated

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

from app.api.deps import CurrentUserContext, get_current_user, get_db
from app.schemas.finance_report_config import (
    FinanceReportConfigRead,
    FinanceReportConfigUpdate,
)
from app.services.expense_claim_access_policy import ExpenseClaimAccessPolicy
from app.services.finance_report_tenant import TenantFinanceReportConfigService

router = APIRouter(prefix="/finance-report-config")
DbSession = Annotated[Session, Depends(get_db)]
CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)]
MANAGE_ROLES = frozenset({"finance", "executive"})


@router.get("", response_model=FinanceReportConfigRead)
def get_finance_report_config(
    db: DbSession,
    current_user: CurrentUser,
) -> FinanceReportConfigRead:
    _require_manage(current_user)
    row = TenantFinanceReportConfigService(db).get(tenant_id=current_user.tenant_id)
    if row is None:
        return FinanceReportConfigRead(
            tenant_id=current_user.tenant_id,
            status="disabled",
            delivery_enabled=False,
        )
    return _serialize(row)


@router.put("", response_model=FinanceReportConfigRead)
def update_finance_report_config(
    payload: FinanceReportConfigUpdate,
    db: DbSession,
    current_user: CurrentUser,
) -> FinanceReportConfigRead:
    _require_manage(current_user)
    try:
        row = TenantFinanceReportConfigService(db).upsert(
            tenant_id=current_user.tenant_id,
            recipients=payload.recipients,
            delivery_enabled=payload.delivery_enabled,
            updated_by=current_user.username,
        )
    except (LookupError, ValueError) as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
    return _serialize(row)


def _require_manage(current_user: CurrentUserContext) -> None:
    tenant_id = str(current_user.tenant_id or "").strip()
    roles = ExpenseClaimAccessPolicy.normalize_role_codes(current_user)
    if tenant_id and (current_user.is_admin or roles & MANAGE_ROLES):
        return
    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail="只有本租户财务人员或管理员可以维护报告收件配置。",
    )


def _serialize(row) -> FinanceReportConfigRead:
    return FinanceReportConfigRead(
        tenant_id=row.tenant_id,
        status=row.status,
        delivery_enabled=row.delivery_enabled,
        recipients=[str(item) for item in list(row.recipients_json or [])],
        updated_by=row.updated_by,
        updated_at=row.updated_at,
    )
