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.expense_application_preview import (
    ExpenseApplicationPreviewDecisionCreate,
    ExpenseApplicationPreviewDecisionRead,
)
from app.schemas.reimbursement import (
    ExpenseApplicationPreviewActionPayload,
    ExpenseApplicationPreviewActionResponse,
)
from app.services.expense_application_preview_decisions import (
    PreviewDecisionConflictError,
)
from app.services.expense_application_preview_workflow import (
    ExpenseApplicationPreviewWorkflow,
)

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


@router.post(
    "/application-previews",
    response_model=ExpenseApplicationPreviewDecisionRead,
    status_code=status.HTTP_201_CREATED,
    summary="签发费用申请预览决策",
    description=(
        "服务端重新解析申请原文、重算规则字段并签发短期 decision_id；"
        "不接受客户端来源声明作为可信 AI 证据。"
    ),
)
def issue_expense_application_preview_decision(
    payload: ExpenseApplicationPreviewDecisionCreate,
    db: DbSession,
    current_user: CurrentUser,
) -> ExpenseApplicationPreviewDecisionRead:
    try:
        return ExpenseApplicationPreviewWorkflow(db).issue(payload, current_user)
    except PreviewDecisionConflictError as error:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(error)) from error
    except ValueError as error:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(error)) from error


@router.post(
    "/application-preview-action",
    response_model=ExpenseApplicationPreviewActionResponse,
    summary="按申请核对预览快速保存或提交申请单",
    description=(
        "用于 AI 工作台已完成表格核对后的轻量建单/提交流程，避免重复进入通用 Orchestrator 编排。"
    ),
)
def run_application_preview_action(
    payload: ExpenseApplicationPreviewActionPayload,
    db: DbSession,
    current_user: CurrentUser,
) -> ExpenseApplicationPreviewActionResponse:
    try:
        return ExpenseApplicationPreviewWorkflow(db).execute(payload, current_user)
    except PreviewDecisionConflictError as error:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(error)) from error
    except ValueError as error:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(error)) from error
