"""零基预算逐项论证 API — 管理会计OS (P2-① 2026-08-28)

CRUD 逐项论证项(budget_zero_based_items) + generate 生成零基预算写 budget_plans。
method-comparison 的 zero_based 分支优先读论证项（有数据→逐项求和 is_demo=false）。
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import Optional
from datetime import datetime

from app.database import get_db
from app.deps import get_entity_id
from app.auth_middleware import require_auth, require_role
from app.models import BudgetZeroBasedItem, KPIDefinition, BudgetPlan

router = APIRouter(
    prefix="/api/cma/budget",
    tags=["零基预算"],
    dependencies=[Depends(require_role("ceo", "finance", "it"))],
)


@router.get("/zero-based/items")
def list_zero_based_items(
    kpi_id: Optional[int] = Query(None),
    period: Optional[str] = Query(None),
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
):
    """零基逐项论证列表（kpi_id+period 过滤）"""
    query = db.query(BudgetZeroBasedItem).filter(BudgetZeroBasedItem.entity_id == entity_id)
    if kpi_id:
        query = query.filter(BudgetZeroBasedItem.kpi_id == kpi_id)
    if period:
        query = query.filter(BudgetZeroBasedItem.period == period)
    rows = query.order_by(BudgetZeroBasedItem.id.desc()).all()

    kpi_ids = {r.kpi_id for r in rows}
    kpis = {k.id: k for k in db.query(KPIDefinition).filter(KPIDefinition.id.in_(kpi_ids)).all()} if kpi_ids else {}
    result = []
    for r in rows:
        kpi = kpis.get(r.kpi_id)
        result.append({
            "id": r.id,
            "kpi_id": r.kpi_id,
            "kpi_code": kpi.kpi_code if kpi else "",
            "kpi_name": kpi.kpi_name if kpi else "",
            "period": r.period,
            "item_name": r.item_name,
            "item_category": r.item_category,
            "base_value": r.base_value,
            "justification": r.justification,
            "proposed_value": r.proposed_value,
            "status": r.status,
            "created_by": r.created_by,
            "created_at": r.created_at.isoformat() if r.created_at else None,
        })
    total_proposed = round(sum(r.proposed_value for r in rows), 2)
    return {"data": result, "total": len(result), "total_proposed": total_proposed}


@router.post("/zero-based/items")
def create_zero_based_item(
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """新建逐项论证项"""
    kpi_id = data.get("kpi_id")
    period = data.get("period")
    item_name = data.get("item_name")
    base_value = data.get("base_value")
    proposed_value = data.get("proposed_value")
    if not kpi_id or not period or not item_name:
        raise HTTPException(400, "缺少必要参数: kpi_id, period, item_name")
    if base_value is None:
        base_value = 0
    if proposed_value is None:
        proposed_value = 0

    kpi = db.query(KPIDefinition).filter(
        KPIDefinition.id == kpi_id,
        KPIDefinition.entity_id == entity_id,
    ).first()
    if not kpi:
        raise HTTPException(404, "KPI不存在")

    row = BudgetZeroBasedItem(
        entity_id=entity_id,
        kpi_id=kpi_id,
        period=period,
        item_name=item_name,
        item_category=data.get("item_category", "discretionary"),
        base_value=base_value,
        justification=data.get("justification"),
        proposed_value=proposed_value,
        status=data.get("status", "draft"),
        created_by=data.get("created_by") or (current_user.name if hasattr(current_user, "name") else None),
    )
    db.add(row)
    db.commit()
    db.refresh(row)
    return {"message": "论证项已创建", "id": row.id}


@router.put("/zero-based/items/{item_id}")
def update_zero_based_item(
    item_id: int,
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """更新逐项论证项"""
    row = db.query(BudgetZeroBasedItem).filter(
        BudgetZeroBasedItem.id == item_id,
        BudgetZeroBasedItem.entity_id == entity_id,
    ).first()
    if not row:
        raise HTTPException(404, "论证项不存在")
    for field in ("item_name", "item_category", "base_value", "justification",
                  "proposed_value", "status"):
        if field in data:
            setattr(row, field, data[field])
    db.commit()
    return {"message": "论证项已更新", "id": row.id}


@router.delete("/zero-based/items/{item_id}")
def delete_zero_based_item(
    item_id: int,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """删除逐项论证项"""
    row = db.query(BudgetZeroBasedItem).filter(
        BudgetZeroBasedItem.id == item_id,
        BudgetZeroBasedItem.entity_id == entity_id,
    ).first()
    if not row:
        raise HTTPException(404, "论证项不存在")
    db.delete(row)
    db.commit()
    return {"message": "论证项已删除"}


@router.post("/zero-based/generate")
def generate_zero_based_budget(
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """生成零基预算 = Σ(proposed_value)，写 budget_plans（version='zbb-YYYYMMDD'，calc_logic='zero_based_itemized'）"""
    kpi_id = data.get("kpi_id")
    period = data.get("period")
    year = data.get("year")
    if not kpi_id or not period:
        raise HTTPException(400, "缺少必要参数: kpi_id, period")

    items = db.query(BudgetZeroBasedItem).filter(
        BudgetZeroBasedItem.entity_id == entity_id,
        BudgetZeroBasedItem.kpi_id == kpi_id,
        BudgetZeroBasedItem.period == period,
    ).all()
    if not items:
        raise HTTPException(400, f"期间 {period} 无逐项论证项，请先录入")

    total = round(sum(i.proposed_value for i in items), 2)
    # 解析年份
    if not year:
        try:
            year = int(period.split("-")[0])
        except Exception:
            year = datetime.now().year
    month = 0
    try:
        month = int(period.split("-")[1]) if "-" in period else 0
    except Exception:
        month = 0

    version = f"zbb-{datetime.now().strftime('%Y%m%d')}"
    # 删除同KPI同期间同版本旧预算，防重复
    db.query(BudgetPlan).filter(
        BudgetPlan.entity_id == entity_id,
        BudgetPlan.kpi_id == kpi_id,
        BudgetPlan.period == period,
        BudgetPlan.version == version,
    ).delete()

    bp = BudgetPlan(
        entity_id=entity_id,
        kpi_id=kpi_id,
        period=period,
        budget_value=total,
        budget_year=year,
        budget_month=month,
        version=version,
        status="active",
        source_type="zero_based",
        calc_logic="zero_based_itemized",
        remark=f"零基逐项论证生成: {len(items)}项 Σ(proposed_value)={total}",
    )
    db.add(bp)
    db.commit()

    return {
        "message": f"零基预算已生成: {total}（{len(items)}项论证）",
        "kpi_id": kpi_id,
        "period": period,
        "total": total,
        "item_count": len(items),
        "version": version,
        "plan_id": bp.id,
    }
