"""现金流分类规则 API — 管理会计OS (P2-⑥ 2026-08-28)

分类规则管理(cash_plan_classify_rules) + 待分类队列(cash_plan_unclassified) + 一键归类。
sync-cash-plans 未命中的KPI进入待分类队列，人工一键归类 → 自动补建规则+生成CashPlan。
"""
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 (
    CashPlanClassifyRule, CashPlanUnclassified, CashPlan,
    KPIDefinition, BudgetPlan,
)

router = APIRouter(
    prefix="/api/cma/budget",
    tags=["现金流分类"],
    dependencies=[Depends(require_role("ceo", "finance", "it"))],
)


# ── 分类规则 CRUD ──────────────────────────────

@router.get("/cash-classify-rules")
def list_classify_rules(
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
):
    """分类规则列表（按 entity_id 隔离）"""
    rows = db.query(CashPlanClassifyRule).filter(
        CashPlanClassifyRule.entity_id == entity_id
    ).order_by(CashPlanClassifyRule.priority.asc(), CashPlanClassifyRule.id.desc()).all()

    kpi_ids = {r.kpi_id for r in rows if r.kpi_id}
    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) if r.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 "",
            "kpi_code_pattern": r.kpi_code_pattern,
            "plan_type": r.plan_type,
            "priority": r.priority,
            "status": r.status,
            "created_at": r.created_at.isoformat() if r.created_at else None,
        })
    return {"data": result, "total": len(result)}


@router.post("/cash-classify-rules")
def create_classify_rule(
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """新建分类规则（kpi_id 精确 或 kpi_code_pattern 关键词 二选一）"""
    plan_type = data.get("plan_type")
    if plan_type not in ("receive", "pay"):
        raise HTTPException(400, "plan_type 必须是 receive/pay")
    kpi_id = data.get("kpi_id")
    pattern = data.get("kpi_code_pattern")
    if not kpi_id and not pattern:
        raise HTTPException(400, "需要 kpi_id 或 kpi_code_pattern 至少一个")

    row = CashPlanClassifyRule(
        entity_id=entity_id,
        kpi_id=kpi_id,
        kpi_code_pattern=pattern,
        plan_type=plan_type,
        priority=data.get("priority", 10),
        status=data.get("status", "active"),
    )
    db.add(row)
    db.commit()
    db.refresh(row)
    return {"message": "分类规则已创建", "id": row.id}


@router.put("/cash-classify-rules/{rule_id}")
def update_classify_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(CashPlanClassifyRule).filter(
        CashPlanClassifyRule.id == rule_id,
        CashPlanClassifyRule.entity_id == entity_id,
    ).first()
    if not row:
        raise HTTPException(404, "规则不存在")
    for field in ("kpi_id", "kpi_code_pattern", "plan_type", "priority", "status"):
        if field in data:
            setattr(row, field, data[field])
    db.commit()
    return {"message": "分类规则已更新", "id": row.id}


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


# ── 待分类队列 ──────────────────────────────

@router.get("/cash-unclassified")
def list_unclassified(
    status: Optional[str] = Query(None, description="pending/classified/ignored"),
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
):
    """待分类KPI队列"""
    query = db.query(CashPlanUnclassified).filter(CashPlanUnclassified.entity_id == entity_id)
    if status:
        query = query.filter(CashPlanUnclassified.status == status)
    rows = query.order_by(CashPlanUnclassified.created_at.desc()).all()
    result = []
    for r in rows:
        result.append({
            "id": r.id,
            "kpi_id": r.kpi_id,
            "kpi_name": r.kpi_name,
            "period": r.period,
            "budget_value": r.budget_value,
            "reason": r.reason,
            "status": r.status,
            "created_at": r.created_at.isoformat() if r.created_at else None,
            "resolved_at": r.resolved_at.isoformat() if r.resolved_at else None,
        })
    return {"data": result, "total": len(result)}


@router.post("/cash-unclassified/{item_id}/classify")
def classify_unclassified(
    item_id: int,
    data: dict,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """一键归类: body {plan_type: receive/pay}
    ① 自动补建分类规则 ② 标记队列 classified ③ 联动生成对应 CashPlan
    """
    plan_type = data.get("plan_type")
    if plan_type not in ("receive", "pay"):
        raise HTTPException(400, "plan_type 必须是 receive/pay")

    item = db.query(CashPlanUnclassified).filter(
        CashPlanUnclassified.id == item_id,
        CashPlanUnclassified.entity_id == entity_id,
        CashPlanUnclassified.status == "pending",
    ).first()
    if not item:
        raise HTTPException(404, "待分类记录不存在或已处理")

    # ① 自动补建规则（无精确KPI规则时）
    existing_rule = db.query(CashPlanClassifyRule).filter(
        CashPlanClassifyRule.entity_id == entity_id,
        CashPlanClassifyRule.kpi_id == item.kpi_id,
    ).first()
    if not existing_rule:
        db.add(CashPlanClassifyRule(
            entity_id=entity_id,
            kpi_id=item.kpi_id,
            kpi_code_pattern=None,
            plan_type=plan_type,
            priority=10,
            status="active",
        ))

    # ② 标记队列
    item.status = "classified"
    item.resolved_at = datetime.now()

    # ③ 联动生成 CashPlan（有期间和预算值时）
    plan_created = False
    if item.period and item.budget_value is not None:
        try:
            year, month = int(item.period.split("-")[0]), int(item.period.split("-")[1])
            plan_date = datetime(year, month, 1)
        except Exception:
            plan_date = None
        if plan_date:
            existing_plan = db.query(CashPlan).filter(
                CashPlan.entity_id == entity_id,
                CashPlan.related_kpi_id == item.kpi_id,
                CashPlan.plan_type == plan_type,
                CashPlan.plan_date == plan_date,
            ).first()
            if not existing_plan:
                db.add(CashPlan(
                    entity_id=entity_id,
                    plan_type=plan_type,
                    related_kpi_id=item.kpi_id,
                    amount=item.budget_value,
                    plan_date=plan_date,
                    description=f"待分类队列归类: {item.kpi_name or ''}",
                    status="pending",
                    source="budget_sync",
                ))
                plan_created = True

    db.commit()
    return {
        "message": f"已归类为 {plan_type}" + (" 并生成现金流计划" if plan_created else ""),
        "plan_type": plan_type,
        "rule_created": not existing_rule,
        "plan_created": plan_created,
    }


@router.post("/cash-unclassified/{item_id}/ignore")
def ignore_unclassified(
    item_id: int,
    db: Session = Depends(get_db),
    entity_id: int = Depends(get_entity_id),
    current_user=Depends(require_auth),
):
    """忽略该KPI（不生成规则）"""
    item = db.query(CashPlanUnclassified).filter(
        CashPlanUnclassified.id == item_id,
        CashPlanUnclassified.entity_id == entity_id,
    ).first()
    if not item:
        raise HTTPException(404, "待分类记录不存在")
    item.status = "ignored"
    item.resolved_at = datetime.now()
    db.commit()
    return {"message": "已忽略"}
