"""客户维度KPI看板 API — P0-2"""
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import func, desc
from typing import Optional
from datetime import datetime, timedelta
from app.database import get_db
from app.auth_middleware import require_auth, require_role
from app.models import KPIDefinition, KPIValue, KPIAlert, User
import logging

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

router = APIRouter(prefix="/api/cma/customer-dashboard", tags=["客户看板"],
    dependencies=[Depends(require_role("ceo", "finance", "business", "it"))],
)


def parse_period(period_type: str, start_date: str = None, end_date: str = None):
    """解析时间区间"""
    today = datetime.now()
    if period_type == "month":
        start = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        end = today
    elif period_type == "quarter":
        q = (today.month - 1) // 3
        start = today.replace(month=q*3+1, day=1, hour=0, minute=0, second=0, microsecond=0)
        end = today
    elif period_type == "year":
        start = today.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
        end = today
    elif period_type == "custom" and start_date and end_date:
        start = datetime.strptime(start_date, "%Y-%m-%d")
        end = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1)
    else:
        start = today.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        end = today
    return start, end


@router.get("")
def list_customer_kpis(
    period: str = Query("month"),
    start_date: str = Query(None),
    end_date: str = Query(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(require_auth),
):
    """获取客户维度KPI列表（含最新值、预警、趋势）"""
    start, end = parse_period(period, start_date, end_date)
    period_str = start.strftime("%Y-%m")

    # 只查 customer 维度的 KPI
    kpis = db.query(KPIDefinition).filter(
        KPIDefinition.status == "active",
        KPIDefinition.dimension == "customer",
    ).order_by(KPIDefinition.kpi_code).all()

    result = []
    for k in kpis:
        base_query = db.query(KPIValue).filter(KPIValue.kpi_id == k.id)

        if period == "month":
            latest = base_query.filter(KPIValue.period == period_str).order_by(KPIValue.id.desc()).first()
        elif period == "quarter":
            q_month = (datetime.now().month - 1) // 3
            months = [f"{datetime.now().year}-{m:02d}" for m in range(q_month*3+1, q_month*3+4)]
            values = base_query.filter(KPIValue.period.in_(months)).all()
            latest_val = sum(v.actual_value for v in values if v.actual_value) if values else None
            latest = type('obj', (object,), {"actual_value": latest_val, "period": f"{months[0]}~{months[-1]}"})() if latest_val else None
        elif period == "year":
            values = base_query.filter(KPIValue.period.like(f"{period_str[:4]}%")).all()
            latest_val = sum(v.actual_value for v in values if v.actual_value) if values else None
            latest = type('obj', (object,), {"actual_value": latest_val, "period": period_str[:4]})() if latest_val else None
        elif period == "custom" and start_date and end_date:
            periods = []
            d = start
            while d <= end:
                periods.append(d.strftime("%Y-%m"))
                d += timedelta(days=32)
                d = d.replace(day=1)
            values = base_query.filter(KPIValue.period.in_(set(periods))).all()
            latest_val = sum(v.actual_value for v in values if v.actual_value) if values else None
            latest = type('obj', (object,), {"actual_value": latest_val, "period": f"{start_date}~{end_date}"})() if latest_val else None
        else:
            latest = base_query.order_by(KPIValue.period.desc()).first()

        # 最新预警
        alert = db.query(KPIAlert).filter(
            KPIAlert.kpi_id == k.id,
            KPIAlert.status == "pending",
        ).order_by(KPIAlert.id.desc()).first()

        # 趋势（环比变化率）
        trend = None
        achievement_rate = None
        period_values = []

        if latest and latest.actual_value:
            prev_period_str = None
            if period == "month":
                year_s, month_s = period_str.split("-")
                y_s, m_s = int(year_s), int(month_s)
                m_s -= 1
                if m_s <= 0:
                    m_s += 12
                    y_s -= 1
                prev_period_str = f"{y_s}-{m_s:02d}"

            if prev_period_str:
                prev_val = db.query(KPIValue).filter(
                    KPIValue.kpi_id == k.id,
                    KPIValue.period == prev_period_str,
                ).order_by(KPIValue.id.desc()).first()
                if prev_val and prev_val.actual_value and prev_val.actual_value > 0:
                    trend = round((latest.actual_value - prev_val.actual_value) / prev_val.actual_value * 100, 2)
                elif prev_val and prev_val.actual_value and prev_val.actual_value == 0:
                    trend = 100.0 if latest.actual_value > 0 else 0

        # 达成率
        if latest and latest.actual_value and k.target_value and k.target_value > 0:
            achievement_rate = round(latest.actual_value / k.target_value * 100, 1)

        # 最近6期趋势数据
        period_q = db.query(KPIValue).filter(
            KPIValue.kpi_id == k.id,
        ).order_by(KPIValue.period.desc()).limit(6).all()
        period_values = [
            {"period": v.period, "value": v.actual_value}
            for v in reversed(period_q) if v.actual_value is not None
        ]

        result.append({
            "id": k.id,
            "kpi_code": k.kpi_code,
            "kpi_name": k.kpi_name,
            "dimension": k.dimension,
            "category": k.category,
            "unit": k.unit,
            "target_value": k.target_value,
            "actual_value": latest.actual_value if latest else None,
            "period": latest.period if latest else None,
            "alert_level": alert.alert_level if alert else "none",
            "alert_message": alert.alert_message if alert else None,
            "frequency": k.frequency,
            "responsible_dept": k.responsible_dept,
            "responsible_user": k.responsible_user,
            "trend": trend,
            "achievement_rate": achievement_rate,
            "period_values": period_values,
            "kpi_name": k.kpi_name,
        })

    return {"data": result, "period": period, "total": len(result)}


@router.get("/trend/{kpi_id}")
def get_kpi_trend(
    kpi_id: int,
    months: int = Query(12, ge=3, le=24),
    db: Session = Depends(get_db),
):
    """获取单个KPI的历史趋势数据"""
    kpi = db.query(KPIDefinition).filter(KPIDefinition.id == kpi_id).first()
    if not kpi:
        raise HTTPException(404, "KPI不存在")

    # 获取最近N期数据
    values = db.query(KPIValue).filter(
        KPIValue.kpi_id == kpi_id,
    ).order_by(KPIValue.period.desc()).limit(months).all()

    trend_data = [
        {"period": v.period, "value": v.actual_value}
        for v in reversed(values) if v.actual_value is not None
    ]

    # 计算预警水平和触发时间
    alerts = db.query(KPIAlert).filter(
        KPIAlert.kpi_id == kpi_id,
    ).order_by(KPIAlert.created_at.desc()).limit(10).all()

    alert_logs = [
        {
            "level": a.alert_level,
            "message": a.alert_message,
            "time": a.created_at.isoformat() if a.created_at else None,
            "status": a.status,
        }
        for a in alerts
    ]

    return {
        "kpi": {
            "id": kpi.id,
            "kpi_code": kpi.kpi_code,
            "kpi_name": kpi.kpi_name,
            "target_value": kpi.target_value,
            "unit": kpi.unit,
            "threshold_green": kpi.threshold_green,
            "threshold_yellow": kpi.threshold_yellow,
            "threshold_red": kpi.threshold_red,
        },
        "trend_data": trend_data,
        "alerts": alert_logs,
    }


@router.get("/summary")
def get_customer_summary(
    period: str = Query("month"),
    db: Session = Depends(get_db),
):
    """客户维度概要统计"""
    total = db.query(func.count(KPIDefinition.id)).filter(
        KPIDefinition.status == "active",
        KPIDefinition.dimension == "customer",
    ).scalar() or 0

    # 预警统计
    pending_alerts = db.query(func.count(KPIAlert.id)).filter(
        KPIAlert.status == "pending",
        KPIAlert.kpi_id.in_(
            db.query(KPIDefinition.id).filter(
                KPIDefinition.status == "active",
                KPIDefinition.dimension == "customer",
            )
        ),
    ).scalar() or 0

    # 二级类别分布
    cat_stats = db.query(
        KPIDefinition.category,
        func.count(KPIDefinition.id),
    ).filter(
        KPIDefinition.status == "active",
        KPIDefinition.dimension == "customer",
    ).group_by(KPIDefinition.category).all()

    return {
        "total": total,
        "pending_alerts": pending_alerts,
        "category_stats": [{"category": c[0], "count": c[1]} for c in cat_stats],
    }
