# AI_CHANGELOG
# - 2026-03-20 | Prompt: R3 项目类型筛选接口重建 | SkillFilterEnum 和 ProjectFilterEnum
#   枚举值从 all/chinese/snooker/mahjong/karaoke 改为 ALL/BILLIARD/SNOOKER/MAHJONG/KTV，
#   与 dws.cfg_area_category.category_code 一致，消除前后端映射层。
# - 2026-03-27 | Prompt: board-finance-integration T2.4 | AreaFilterEnum 从 7 项重建为 9 项
#   （新增 vip/snooker/ktv，移除 teamBuilding），与区域筛选对照表一致。

"""三看板接口 Pydantic Schema（BOARD-1/2/3 请求参数枚举 + 响应模型）。"""

from __future__ import annotations

from enum import Enum

from app.schemas.base import CamelModel


# ---------------------------------------------------------------------------
# 请求参数枚举（Task 2.1）
# ---------------------------------------------------------------------------

class CoachSortEnum(str, Enum):
    """BOARD-1 排序维度。"""
    perf_desc = "perf_desc"
    perf_asc = "perf_asc"
    salary_desc = "salary_desc"
    salary_asc = "salary_asc"
    sv_desc = "sv_desc"
    task_desc = "task_desc"


class SkillFilterEnum(str, Enum):
    """BOARD-1 技能筛选（值与 dws.cfg_area_category.category_code 一致）。"""
    # CHANGE 2026-03-20 | R3 修复：枚举值从 chinese/snooker 等前端自定义值
    # 改为数据库 category_code（BILLIARD/SNOOKER/MAHJONG/KTV），消除映射层。
    ALL = "ALL"
    BILLIARD = "BILLIARD"
    SNOOKER = "SNOOKER"
    MAHJONG = "MAHJONG"
    KTV = "KTV"


class BoardTimeEnum(str, Enum):
    """BOARD-1 时间范围。"""
    month = "month"
    quarter = "quarter"
    last_month = "last_month"
    last_3m = "last_3m"
    last_quarter = "last_quarter"
    last_6m = "last_6m"


class CustomerDimensionEnum(str, Enum):
    """BOARD-2 客户维度。"""
    recall = "recall"
    potential = "potential"
    balance = "balance"
    recharge = "recharge"
    recent = "recent"
    spend60 = "spend60"
    freq60 = "freq60"
    loyal = "loyal"


class ProjectFilterEnum(str, Enum):
    """BOARD-2 项目筛选（值与 dws.cfg_area_category.category_code 一致）。"""
    # CHANGE 2026-03-20 | R3 修复：枚举值从 chinese/snooker 等前端自定义值
    # 改为数据库 category_code（BILLIARD/SNOOKER/MAHJONG/KTV），消除映射层。
    ALL = "ALL"
    BILLIARD = "BILLIARD"
    SNOOKER = "SNOOKER"
    MAHJONG = "MAHJONG"
    KTV = "KTV"


class FinanceTimeEnum(str, Enum):
    """BOARD-3 时间范围。"""
    month = "month"
    lastMonth = "lastMonth"
    week = "week"
    lastWeek = "lastWeek"
    quarter3 = "quarter3"
    quarter = "quarter"
    lastQuarter = "lastQuarter"
    half6 = "half6"


class AreaFilterEnum(str, Enum):
    """BOARD-3 区域筛选。"""
    # CHANGE 2026-03-27 | board-finance-integration T2.4 | 枚举从 7 项重建为 9 项，
    # 与区域筛选对照表一致（all/hall/hallA-C/vip/snooker/mahjong/ktv）
    all = "all"
    hall = "hall"
    hallA = "hallA"
    hallB = "hallB"
    hallC = "hallC"
    vip = "vip"
    snooker = "snooker"
    mahjong = "mahjong"
    ktv = "ktv"


# ---------------------------------------------------------------------------
# BOARD-1 响应 Schema（Task 2.2）
# ---------------------------------------------------------------------------

class CoachSkillItem(CamelModel):
    text: str
    cls: str


class CoachBoardItem(CamelModel):
    """助教看板单条记录（扁平结构，包含所有维度字段）。"""

    # 基础字段（所有维度共享）
    id: int
    name: str
    initial: str
    avatar_gradient: str
    level: str  # star/senior/middle/junior
    skills: list[CoachSkillItem]
    top_customers: list[str]  # ["💖 王先生", "💛 李女士"]

    # perf 维度
    perf_hours: float = 0.0
    perf_hours_before: float | None = None
    perf_gap: str | None = None  # "距升档 13.8h" 或 None
    perf_reached: bool = False

    # salary 维度
    salary: float = 0.0
    salary_perf_hours: float = 0.0
    salary_perf_before: float | None = None

    # sv 维度
    sv_amount: float = 0.0
    sv_customer_count: int = 0
    sv_consume: float = 0.0

    # task 维度
    task_recall: int = 0
    task_callback: int = 0


class CoachBoardResponse(CamelModel):
    items: list[CoachBoardItem]
    total: int
    page: int
    page_size: int
    dim_type: str  # perf/salary/sv/task


# ---------------------------------------------------------------------------
# BOARD-2 响应 Schema（Task 2.3）
# ---------------------------------------------------------------------------

class CustomerAssistant(CamelModel):
    name: str
    cls: str
    heart_score: float
    badge: str | None = None
    badge_cls: str | None = None


class CustomerBoardItemBase(CamelModel):
    """客户看板基础字段（所有维度共享）。"""
    id: int
    name: str
    initial: str
    avatar_cls: str
    assistants: list[CustomerAssistant]


class RecallItem(CustomerBoardItemBase):
    ideal_days: int
    elapsed_days: int
    overdue_days: int
    visits_30d: int
    balance: str
    recall_index: float


class PotentialTag(CamelModel):
    text: str
    theme: str


class PotentialItem(CustomerBoardItemBase):
    potential_tags: list[PotentialTag]
    spend_30d: float
    avg_visits: float
    avg_spend: float


class BalanceItem(CustomerBoardItemBase):
    balance: str
    last_visit: str  # "3天前"
    monthly_consume: float
    available_months: str  # "约0.8个月"


class RechargeItem(CustomerBoardItemBase):
    last_recharge: str
    recharge_amount: float
    recharges_60d: int
    current_balance: str


class RecentItem(CustomerBoardItemBase):
    days_ago: int
    visit_freq: str  # "6.2次/月"
    ideal_days: int
    visits_30d: int
    avg_spend: float


class Spend60Item(CustomerBoardItemBase):
    spend_60d: float
    visits_60d: int
    high_spend_tag: bool
    avg_spend: float


class WeeklyVisit(CamelModel):
    val: int
    pct: int  # 0-100


class Freq60Item(CustomerBoardItemBase):
    visits_60d: int
    avg_interval: str  # "5.0天"
    weekly_visits: list[WeeklyVisit]  # 固定长度 8
    spend_60d: float


class CoachDetail(CamelModel):
    name: str
    cls: str
    heart_score: float
    badge: str | None = None
    avg_duration: str
    service_count: int
    coach_spend: float
    relation_idx: float


class LoyalItem(CustomerBoardItemBase):
    intimacy: float
    top_coach_name: str
    top_coach_heart: float
    top_coach_score: float
    coach_name: str
    coach_ratio: str  # "78%"
    coach_details: list[CoachDetail]


class CustomerBoardResponse(CamelModel):
    items: list[dict]  # 实际类型取决于 dimension
    total: int
    page: int
    page_size: int


# ---------------------------------------------------------------------------
# BOARD-3 响应 Schema（Task 2.4）
# ---------------------------------------------------------------------------

class OverviewPanel(CamelModel):
    """经营一览：8 项核心指标 + 各 3 个环比字段（Optional，compare=0 时为 None）。"""
    occurrence: float
    discount: float  # 负值
    discount_rate: float
    confirmed_revenue: float
    cash_in: float | None = None
    cash_out: float | None = None
    cash_balance: float | None = None
    balance_rate: float | None = None
    # occurrence 环比
    occurrence_compare: str | None = None
    occurrence_down: bool | None = None
    occurrence_flat: bool | None = None
    # discount 环比
    discount_compare: str | None = None
    discount_down: bool | None = None
    discount_flat: bool | None = None
    # discount_rate 环比
    discount_rate_compare: str | None = None
    discount_rate_down: bool | None = None
    discount_rate_flat: bool | None = None
    # confirmed_revenue 环比
    confirmed_revenue_compare: str | None = None
    confirmed_revenue_down: bool | None = None
    confirmed_revenue_flat: bool | None = None
    # cash_in 环比
    cash_in_compare: str | None = None
    cash_in_down: bool | None = None
    cash_in_flat: bool | None = None
    # cash_out 环比
    cash_out_compare: str | None = None
    cash_out_down: bool | None = None
    cash_out_flat: bool | None = None
    # cash_balance 环比
    cash_balance_compare: str | None = None
    cash_balance_down: bool | None = None
    cash_balance_flat: bool | None = None
    # balance_rate 环比
    balance_rate_compare: str | None = None
    balance_rate_down: bool | None = None
    balance_rate_flat: bool | None = None


class GiftCell(CamelModel):
    value: float
    compare: str | None = None
    down: bool | None = None
    flat: bool | None = None


class GiftRow(CamelModel):
    """赠送卡矩阵一行：合计 / 酒水卡 / 台费卡 / 抵用券。"""
    label: str  # "新增" / "消费" / "余额"
    total: GiftCell
    liquor: GiftCell
    table_fee: GiftCell
    voucher: GiftCell


class RechargePanel(CamelModel):
    """预收资产板块：储值卡 5 指标 + 赠送卡 3×4 矩阵 + 全卡余额。"""
    actual_income: float
    first_charge: float
    renew_charge: float
    consumed: float
    card_balance: float
    gift_rows: list[GiftRow]  # 3 行
    all_card_balance: float
    # 储值卡各项环比字段
    actual_income_compare: str | None = None
    actual_income_down: bool | None = None
    actual_income_flat: bool | None = None
    first_charge_compare: str | None = None
    first_charge_down: bool | None = None
    first_charge_flat: bool | None = None
    renew_charge_compare: str | None = None
    renew_charge_down: bool | None = None
    renew_charge_flat: bool | None = None
    consumed_compare: str | None = None
    consumed_down: bool | None = None
    consumed_flat: bool | None = None
    card_balance_compare: str | None = None
    card_balance_down: bool | None = None
    card_balance_flat: bool | None = None
    # 全类别会员卡余额合计环比
    all_card_balance_compare: str | None = None
    all_card_balance_down: bool | None = None
    all_card_balance_flat: bool | None = None


class RevenueStructureRow(CamelModel):
    id: str
    name: str
    desc: str | None = None
    is_sub: bool = False
    amount: float
    discount: float
    booked: float
    booked_compare: str | None = None


class RevenueItem(CamelModel):
    label: str
    desc: str | None = None
    amount: float
    compare: str | None = None


class ChannelItem(CamelModel):
    label: str
    desc: str | None = None
    amount: float
    compare: str | None = None


class RevenuePanel(CamelModel):
    structure_rows: list[RevenueStructureRow]
    price_items: list[RevenueItem]
    total_occurrence: float
    total_occurrence_compare: str | None = None
    total_occurrence_down: bool | None = None
    total_occurrence_flat: bool | None = None
    discount_items: list[RevenueItem]
    # CHANGE 2026-03-28 | board-finance-phase2 bugfix | 优惠总计供前端展示
    discount_total: float = 0.0
    discount_total_compare: str | None = None
    discount_total_down: bool | None = None
    discount_total_flat: bool | None = None
    confirmed_total: float
    confirmed_total_compare: str | None = None
    confirmed_total_down: bool | None = None
    confirmed_total_flat: bool | None = None
    channel_items: list[ChannelItem]


class CashflowItem(CamelModel):
    label: str
    desc: str | None = None
    amount: float
    compare: str | None = None
    down: bool | None = None


class CashflowPanel(CamelModel):
    consume_items: list[CashflowItem]  # 3 项
    recharge_items: list[CashflowItem]  # 1 项
    total: float
    total_compare: str | None = None
    total_down: bool | None = None
    total_flat: bool | None = None


class ExpenseItem(CamelModel):
    label: str
    amount: float
    compare: str | None = None
    down: bool | None = None
    flat: bool | None = None


class ExpensePanel(CamelModel):
    operation_items: list[ExpenseItem]  # 3 项
    fixed_items: list[ExpenseItem]  # 4 项
    coach_items: list[ExpenseItem]  # 4 项
    platform_items: list[ExpenseItem]  # 3 项
    total: float
    total_compare: str | None = None
    total_down: bool | None = None
    total_flat: bool | None = None


class CoachAnalysisRow(CamelModel):
    level: str
    pay: float
    share: float
    hourly: float
    pay_compare: str | None = None
    pay_down: bool | None = None
    share_compare: str | None = None
    share_down: bool | None = None
    hourly_compare: str | None = None
    hourly_flat: bool | None = None


class CoachAnalysisTable(CamelModel):
    total_pay: float
    total_share: float
    avg_hourly: float
    total_pay_compare: str | None = None
    total_pay_down: bool | None = None
    total_share_compare: str | None = None
    total_share_down: bool | None = None
    avg_hourly_compare: str | None = None
    avg_hourly_flat: bool | None = None
    rows: list[CoachAnalysisRow]  # 4 行：初级/中级/高级/星级


class CoachAnalysisPanel(CamelModel):
    basic: CoachAnalysisTable  # 基础课/陪打
    incentive: CoachAnalysisTable  # 激励课/超休


class FinanceBoardResponse(CamelModel):
    overview: OverviewPanel
    recharge: RechargePanel | None  # area≠all 时为 null
    revenue: RevenuePanel
    cashflow: CashflowPanel | None  # area≠all 时为 null
    expense: ExpensePanel | None  # area≠all 时为 null
    coach_analysis: CoachAnalysisPanel
