"""预算自动从KPI推算 API — P1-2

根据KPI的目标值自动生成预算建议。
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.database import get_db
from app.auth_middleware import require_auth, require_role
from app.models import KPIDefinition, BudgetPlan, KPIValue, OperationLog
import json
import logging
from datetime import datetime

logger = logging.getLogger("cma.budget_gen")

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


def _calc_budget(kpi: KPIDefinition) -> dict:
    """根据KPI类型推算预算

    算法:
    - 降本类: (当前值-目标值)×0.3
    - 增收类: 目标增收额×0.2
    - 能力类: 人均培训成本×人数
    - 系统类: 按模块开发费估算
    """
    category = kpi.category or ""
    target = kpi.target_value or 0

    result = {
        "suggested_budget": 0,
        "calc_logic": "",
        "calc_type": "未知",
    }

    # 降本类: cost_control, cash_risk
    if category in ("cost_control", "cash_risk", "asset_efficiency"):
        result["calc_type"] = "降本类"
        # 当前值需要从最新的KPIValue获取
        # 这里返回算法描述，前端传入当前值
        result["calc_type_desc"] = "(当前值-目标值)×0.3"
        result["suggested_budget"] = 0  # 需要前端传当前值

    # 增收类: revenue_growth, profitability
    elif category in ("revenue_growth", "profitability", "customer_scale"):
        result["calc_type"] = "增收类"
        result["calc_type_desc"] = "目标增收额×0.2"
        result["suggested_budget"] = round(target * 0.2, 2)

    # 能力类: talent_pipeline, employee_engagement, innovation
    elif category in ("talent_pipeline", "employee_engagement", "innovation"):
        result["calc_type"] = "能力类"
        result["calc_type_desc"] = "人均培训成本×人数"
        result["suggested_budget"] = 0  # 需要外部参数

    # 系统类: 默认为系统类
    elif category in ("supply_chain", "delivery_quality", "customer_concentration", "customer_satisfaction"):
        result["calc_type"] = "系统类"
        result["calc_type_desc"] = "按功能模块开发费估算"
        result["suggested_budget"] = round(target * 0.15, 2)

    # 其他未分类
    else:
        result["calc_type"] = "系统类"
        result["calc_type_desc"] = "按功能模块开发费估算"
        result["suggested_budget"] = round(target * 0.15, 2)

    return result


@router.get("/kpi-budget-candidates")
def get_kpi_budget_candidates(
    year: int = None,
    db: Session = Depends(get_db),
):
    """获取可用于生成预算的KPI列表，按类型分类"""
    if not year:
        year = datetime.now().year

    kpis = db.query(KPIDefinition).filter(KPIDefinition.status == "active").all()

    # 获取每个KPI的最新实际值
    latest_values = {}
    for kpi in kpis:
        v = db.query(KPIValue).filter(
            KPIValue.kpi_id == kpi.id
        ).order_by(KPIValue.calculated_at.desc()).first()
        if v:
            latest_values[kpi.id] = v.actual_value

    # 分类
    categorized = {
        "cost_reduction": [],   # 降本类
        "revenue_growth": [],   # 增收类
        "capability": [],       # 能力类
        "system": [],           # 系统类
    }

    for kpi in kpis:
        calc_info = _calc_budget(kpi)
        current_val = latest_values.get(kpi.id)

        # 降本类: 需要当前值
        if calc_info["calc_type"] == "降本类":
            if current_val is not None and kpi.target_value:
                diff = current_val - kpi.target_value
                suggested = round(max(diff, 0) * 0.3, 2)
                calc_logic = f"当前值{current_val}-目标值{kpi.target_value}={diff:.2f}，×0.3={suggested:.2f}"
            else:
                suggested = 0
                calc_logic = "缺少当前值或目标值，无法计算"
            item = {
                "id": kpi.id,
                "kpi_code": kpi.kpi_code,
                "kpi_name": kpi.kpi_name,
                "dimension": kpi.dimension,
                "category": kpi.category,
                "calc_type": "降本类",
                "target_value": kpi.target_value,
                "current_value": current_val,
                "suggested_budget": suggested,
                "calc_logic": calc_logic,
            }
            categorized["cost_reduction"].append(item)

        elif calc_info["calc_type"] == "增收类":
            suggested = round((kpi.target_value or 0) * 0.2, 2)
            calc_logic = f"目标增收额{kpi.target_value}×0.2={suggested:.2f}"
            item = {
                "id": kpi.id,
                "kpi_code": kpi.kpi_code,
                "kpi_name": kpi.kpi_name,
                "dimension": kpi.dimension,
                "category": kpi.category,
                "calc_type": "增收类",
                "target_value": kpi.target_value,
                "current_value": current_val,
                "suggested_budget": suggested,
                "calc_logic": calc_logic,
            }
            categorized["revenue_growth"].append(item)

        elif calc_info["calc_type"] == "能力类":
            # 假设人均培训成本2000元, 默认10人
            suggested = round(2000 * 10, 2)
            calc_logic = f"人均培训成本2000元×10人={suggested:.2f}（可调整人数和单价）"
            item = {
                "id": kpi.id,
                "kpi_code": kpi.kpi_code,
                "kpi_name": kpi.kpi_name,
                "dimension": kpi.dimension,
                "category": kpi.category,
                "calc_type": "能力类",
                "target_value": kpi.target_value,
                "current_value": current_val,
                "suggested_budget": suggested,
                "calc_logic": calc_logic,
                "per_head_cost": 2000,
                "head_count": 10,
            }
            categorized["capability"].append(item)

        else:  # 系统类
            suggested = round((kpi.target_value or 0) * 0.15, 2)
            if suggested <= 0:
                suggested = 30000  # 默认3万
                calc_logic = "按模块开发费估算: 默认30000元（可调整）"
            else:
                calc_logic = f"目标值{kpi.target_value}×0.15={suggested:.2f}"
            item = {
                "id": kpi.id,
                "kpi_code": kpi.kpi_code,
                "kpi_name": kpi.kpi_name,
                "dimension": kpi.dimension,
                "category": kpi.category,
                "calc_type": "系统类",
                "target_value": kpi.target_value,
                "current_value": current_val,
                "suggested_budget": suggested,
                "calc_logic": calc_logic,
            }
            categorized["system"].append(item)

    return {"data": categorized}


@router.post("/generate-from-kpis")
def generate_budget_from_kpis(
    data: dict,
    db: Session = Depends(get_db),
    current_user=Depends(require_auth),
):
    """从选中的KPI生成预算科目

    Body: {
        year: int,
        month: int,
        version: string,
        items: [
            {
                kpi_id: int,
                budget_amount: float,  // 用户可编辑
                calc_logic: string,
                calc_type: string,
            }
        ]
    }
    """
    year = data.get("year", datetime.now().year)
    month = data.get("month", datetime.now().month + 1)
    version = data.get("version", "v1.0")
    items = data.get("items", [])

    if not items:
        raise HTTPException(400, "请至少选择一个KPI")

    period = f"{year}-{month:02d}"
    results = []
    total_amount = 0

    for item in items:
        kpi_id = item.get("kpi_id")
        budget_amount = item.get("budget_amount")
        calc_logic = item.get("calc_logic", "")
        calc_type = item.get("calc_type", "")

        if not kpi_id or budget_amount is None:
            continue

        kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first()
        if not kpi:
            continue

        # 检查是否已有记录
        existing = db.query(BudgetPlan).filter(
            BudgetPlan.kpi_id == kpi_id,
            BudgetPlan.period == period,
            BudgetPlan.version == version,
            BudgetPlan.status == "active",
        ).first()

        if existing:
            existing.budget_value = budget_amount
            existing.source_type = "kpi_generated"
            existing.source_kpi_id = kpi_id
            existing.calc_logic = calc_logic
            existing.remark = f"KPI推算({calc_type}): {calc_logic}"
            plan_id = existing.id
        else:
            plan = BudgetPlan(
                kpi_id=kpi_id,
                period=period,
                budget_value=budget_amount,
                budget_year=year,
                budget_month=month,
                version=version,
                status="active",
                source_type="kpi_generated",
                source_kpi_id=kpi_id,
                calc_logic=calc_logic,
                remark=f"KPI推算({calc_type}): {calc_logic}",
                created_by=current_user.name if hasattr(current_user, "name") else "",
            )
            db.add(plan)
            db.flush()
            plan_id = plan.id

        total_amount += budget_amount
        results.append({
            "kpi_id": kpi_id,
            "kpi_code": kpi.kpi_code,
            "kpi_name": kpi.kpi_name,
            "budget_amount": budget_amount,
            "calc_logic": calc_logic,
            "plan_id": plan_id,
        })

    # 操作日志
    log = OperationLog(
        user_id=getattr(current_user, "id", None),
        action="kpi_generate_budget",
        target_type="budget",
        detail=json.dumps({
            "year": year,
            "month": month,
            "version": version,
            "item_count": len(results),
            "total_amount": total_amount,
        }, ensure_ascii=False),
    )
    db.add(log)
    db.commit()

    return {
        "message": f"已从{len(results)}个KPI生成预算，合计¥{total_amount:,.2f}",
        "total_amount": total_amount,
        "items": results,
    }
