"""KPI派生规则 API — 管理会计OS (P2-② 2026-08-28)

派生规则配置(budget_derivation_rules)：apply-method 派生KPI时优先读规则，
percentage_of → base_kpi实际值×rate；incremental → 上月×(1+rate)；无规则fallback默认比例。
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import Optional

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 BudgetDerivationRule, KPIDefinition

router = APIRouter(
    prefix="/api/cma/budget",
    tags=["派生规则"],
    dependencies=[Depends(require_role("ceo", "finance", "it"))],
)


@router.get("/derivation-rules")
def list_derivation_rules(
    kpi_id: Optional[int] = Query(None),
    status: Optional[str] = Query(None),
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
):
    """派生规则列表（按 entity_id 隔离）"""
    query = db.query(BudgetDerivationRule).filter(BudgetDerivationRule.entity_id == entity_id)
    if kpi_id:
        query = query.filter(BudgetDerivationRule.kpi_id == kpi_id)
    if status:
        query = query.filter(BudgetDerivationRule.status == status)
    rows = query.order_by(BudgetDerivationRule.id.desc()).all()

    all_kpi_ids = {r.kpi_id for r in rows} | {r.base_kpi_id for r in rows if r.base_kpi_id}
    kpis = {k.id: k for k in db.query(KPIDefinition).filter(KPIDefinition.id.in_(all_kpi_ids)).all()} if all_kpi_ids else {}
    result = []
    for r in rows:
        kpi = kpis.get(r.kpi_id)
        base = kpis.get(r.base_kpi_id) if r.base_kpi_id else None
        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 "",
            "rule_type": r.rule_type,
            "base_kpi_id": r.base_kpi_id,
            "base_kpi_code": base.kpi_code if base else "",
            "base_kpi_name": base.kpi_name if base else "",
            "params": r.params,
            "formula_text": r.formula_text,
            "status": r.status,
            "created_at": r.created_at.isoformat() if r.created_at else None,
        })
    return {"data": result, "total": len(result)}


@router.post("/derivation-rules")
def create_derivation_rule(
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """新建派生规则（同KPI同类型唯一）"""
    kpi_id = data.get("kpi_id")
    rule_type = data.get("rule_type")
    if not kpi_id or rule_type not in ("incremental", "percentage_of", "formula"):
        raise HTTPException(400, "需要 kpi_id 且 rule_type ∈ incremental/percentage_of/formula")

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

    existing = db.query(BudgetDerivationRule).filter(
        BudgetDerivationRule.entity_id == entity_id,
        BudgetDerivationRule.kpi_id == kpi_id,
        BudgetDerivationRule.rule_type == rule_type,
    ).first()
    if existing:
        raise HTTPException(400, f"KPI({kpi_id})已存在 {rule_type} 规则")

    row = BudgetDerivationRule(
        entity_id=entity_id,
        kpi_id=kpi_id,
        rule_type=rule_type,
        base_kpi_id=data.get("base_kpi_id"),
        params=data.get("params"),
        formula_text=data.get("formula_text"),
        status=data.get("status", "active"),
    )
    db.add(row)
    db.commit()
    db.refresh(row)
    return {"message": "派生规则已创建", "id": row.id}


@router.put("/derivation-rules/{rule_id}")
def update_derivation_rule(
    rule_id: int,
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """更新派生规则"""
    row = db.query(BudgetDerivationRule).filter(
        BudgetDerivationRule.id == rule_id,
        BudgetDerivationRule.entity_id == entity_id,
    ).first()
    if not row:
        raise HTTPException(404, "规则不存在")
    for field in ("rule_type", "base_kpi_id", "params", "formula_text", "status"):
        if field in data:
            setattr(row, field, data[field])
    db.commit()
    return {"message": "派生规则已更新", "id": row.id}


@router.delete("/derivation-rules/{rule_id}")
def delete_derivation_rule(
    rule_id: int,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """删除派生规则"""
    row = db.query(BudgetDerivationRule).filter(
        BudgetDerivationRule.id == rule_id,
        BudgetDerivationRule.entity_id == entity_id,
    ).first()
    if not row:
        raise HTTPException(404, "规则不存在")
    db.delete(row)
    db.commit()
    return {"message": "派生规则已删除"}
