"""Employee behavior profile tags and radar scoring."""

from __future__ import annotations

from collections.abc import Iterable, Mapping
from typing import Any

from app.algorithem.employee_behavior_profile import LEVEL_LABELS, level_from_score
from app.algorithem.employee_behavior_profile_tag_rules import (
    PROFILE_TAG_ALGORITHM_VERSION,
    append_ai_tags,
    append_approval_tags,
    append_expense_tags,
    append_process_tags,
    append_travel_entertainment_tags,
    clamp_score,
    component,
    number,
    profile_index,
    scene_priority,
    tag_score,
)

APPROVAL_RADAR_CODES = {
    "expense_intensity",
    "application_rhythm",
    "travel_entertainment",
    "material_completeness",
    "process_pressure",
}

RADAR_LABELS = {
    "expense_intensity": "费用强度",
    "application_rhythm": "申请节奏",
    "travel_entertainment": "差旅招待",
    "material_completeness": "材料完整度压力",
    "process_pressure": "流程压力",
    "ai_collaboration": "AI 协作强度",
    "approval_efficiency": "审批效率特征",
    "approval_control": "审批把关特征",
}


def build_profile_tags(
    profiles: Iterable[Mapping[str, Any]],
    *,
    scene: str = "approval",
) -> list[dict[str, Any]]:
    payloads = list(profiles)
    index = profile_index(payloads)
    tags: list[dict[str, Any]] = []
    append_expense_tags(tags, index)
    append_travel_entertainment_tags(tags, index)
    append_process_tags(tags, index)
    append_ai_tags(tags, index)
    append_approval_tags(tags, index)

    active_tags = [
        tag
        for tag in tags
        if int(tag["score"]) >= 60 and float(tag["confidence"]) >= 0.55
    ]
    active_tags.sort(
        key=lambda item: (
            scene_priority(item, scene),
            float(item["confidence"]),
            int(item["score"]),
        ),
        reverse=True,
    )
    return active_tags[:12 if scene == "approval" else 24]


def build_profile_radar(
    profiles: Iterable[Mapping[str, Any]],
    profile_tags: Iterable[Mapping[str, Any]],
    *,
    scene: str = "approval",
) -> dict[str, Any]:
    payloads = list(profiles)
    index = profile_index(payloads)
    tags = list(profile_tags)
    dimensions = [
        _dimension(
            "expense_intensity",
            [
                component(index, "expense", "amount_occupancy_score"),
                component(index, "expense", "peer_deviation_score"),
                component(index, "expense", "current_claim_deviation_score"),
                tag_score(tags, "expense_king"),
                tag_score(tags, "large_amount_deviation"),
            ],
            tags,
        ),
        _dimension(
            "application_rhythm",
            [
                component(index, "expense", "frequency_score"),
                tag_score(tags, "high_frequency_applicant"),
                tag_score(tags, "micro_high_frequency"),
                tag_score(tags, "expense_type_wide"),
                tag_score(tags, "holiday_expense_active"),
            ],
            tags,
        ),
        _dimension(
            "travel_entertainment",
            [
                tag_score(tags, "long_trip_master"),
                tag_score(tags, "travel_frequent"),
                tag_score(tags, "travel_daily_high"),
                tag_score(tags, "hotel_high_standard"),
                tag_score(tags, "transport_high_cost"),
                tag_score(tags, "entertainment_active"),
                tag_score(tags, "entertainment_unit_high"),
                tag_score(tags, "repeat_client_host"),
            ],
            tags,
        ),
        _dimension(
            "material_completeness",
            [
                component(index, "process_quality", "missing_attachment_score"),
                component(index, "process_quality", "invoice_mismatch_score"),
                component(index, "process_quality", "missing_business_context_score"),
                tag_score(tags, "material_patch"),
                tag_score(tags, "invoice_unstable"),
                tag_score(tags, "reason_thin"),
                tag_score(tags, "clean_first_pass", invert=True),
            ],
            tags,
        ),
        _dimension(
            "process_pressure",
            [
                component(index, "process_quality", "return_count_score"),
                component(index, "process_quality", "resubmit_duration_score"),
                tag_score(tags, "return_frequent"),
                tag_score(tags, "adjustment_frequent"),
                tag_score(tags, "resubmit_slow"),
                tag_score(tags, "repeat_issue"),
                tag_score(tags, "large_return_amount"),
            ],
            tags,
        ),
        _dimension(
            "ai_collaboration",
            [
                component(index, "ai_usage", "ai_call_count_score"),
                component(index, "ai_usage", "token_cost_score"),
                component(index, "ai_usage", "failed_ai_call_score"),
                tag_score(tags, "ai_heavy"),
                tag_score(tags, "token_high"),
                tag_score(tags, "ai_dependency_unimproved"),
            ],
            tags,
        ),
        _dimension(
            "approval_efficiency",
            [
                component(index, "approval", "avg_review_duration_score"),
                component(index, "approval", "sla_overdue_score"),
                tag_score(tags, "speed_reviewer"),
                tag_score(tags, "high_risk_fast_pass"),
                tag_score(tags, "sla_delayer"),
            ],
            tags,
        ),
        _dimension(
            "approval_control",
            [
                component(index, "approval", "direct_approve_ratio_score"),
                component(index, "approval", "high_risk_approve_score"),
                component(index, "approval", "system_advice_override_score"),
                tag_score(tags, "cautious_reviewer"),
                tag_score(tags, "gatekeeper"),
                tag_score(tags, "steady_reviewer"),
            ],
            tags,
        ),
    ]
    if scene == "approval":
        dimensions = [item for item in dimensions if item["code"] in APPROVAL_RADAR_CODES]
    return {
        "algorithm_version": PROFILE_TAG_ALGORITHM_VERSION,
        "dimensions": dimensions,
    }


def _dimension(code: str, values: list[float], tags: list[Mapping[str, Any]]) -> dict[str, Any]:
    valid_values = [max(0, min(100, number(value))) for value in values if number(value) > 0]
    score = clamp_score(sum(valid_values) / len(valid_values)) if valid_values else 0
    top_tags = [
        str(tag.get("code"))
        for tag in sorted(
            [tag for tag in tags if code in (tag.get("radar_dimensions") or [])],
            key=lambda item: (int(item.get("score") or 0), float(item.get("confidence") or 0)),
            reverse=True,
        )[:3]
    ]
    level = level_from_score(score)
    return {
        "code": code,
        "label": RADAR_LABELS.get(code, code),
        "score": score,
        "level": level,
        "level_label": LEVEL_LABELS.get(level, level),
        "top_tags": top_tags,
    }
