"""사주 궁합 — 두 사주 일주(일간 오행 + 일지) 매칭 → 점수 + breakdown.

saju-web/app/compatibility/result/page.tsx의 `calculateCompatibility()` 로직과 1:1 매핑.

알고리즘 (saju-web TS):
    score = 50 (base)
    # 일간 오행 관계
    if element1 == element2:               score += 10  # same
    elif relation in (produce, produced):  score += 25  # 상생
    else:                                  score -= 10  # 상극 (overcome/overcomed)
    # 일지 관계
    if 六合 (sixHarmony):                  score += 20
    if 三合 (threeHarmony):                score += 15
    if 沖 (conflict):                      score -= 20
    score = clamp(score, 0, 100)

breakdown은 saju-lab 자체 확장 — 각 카테고리별 (score_delta, description) 제공.
"""
from __future__ import annotations

from typing import Any, Dict

from .constants import FIVE_ELEMENTS


# ─── 오행 상생/상극 맵 (saju-web과 동일) ──────────────────────────────
_PRODUCE_MAP = {"木": "火", "火": "土", "土": "金", "金": "水", "水": "木"}
_OVERCOME_MAP = {"木": "土", "火": "金", "土": "水", "金": "木", "水": "火"}


# ─── 지지 6합/6충 (saju-web과 동일) ───────────────────────────────────
_SIX_HARMONY: dict[str, str] = {
    "子": "丑", "丑": "子",
    "寅": "亥", "亥": "寅",
    "卯": "戌", "戌": "卯",
    "辰": "酉", "酉": "辰",
    "巳": "申", "申": "巳",
    "午": "未", "未": "午",
}

# 삼합 그룹 (saju-web threeHarmonyGroups)
_THREE_HARMONY_GROUPS = [
    {"申", "子", "辰"},
    {"寅", "午", "戌"},
    {"亥", "卯", "未"},
    {"巳", "酉", "丑"},
]

_CONFLICT: dict[str, str] = {
    "子": "午", "午": "子",
    "丑": "未", "未": "丑",
    "寅": "申", "申": "寅",
    "卯": "酉", "酉": "卯",
    "辰": "戌", "戌": "辰",
    "巳": "亥", "亥": "巳",
}


# ─── 헬퍼 ─────────────────────────────────────────────────────────
def _get_element_relation(el1: str, el2: str) -> str:
    """오행 관계 판별 — 'same' | 'produce' | 'produced' | 'overcome' | 'overcomed'.

    saju-web getElementRelation()과 1:1 매핑.
    """
    if el1 == el2:
        return "same"
    if _PRODUCE_MAP.get(el1) == el2:
        return "produce"      # el1 → el2 (el1이 el2를 생함)
    if _PRODUCE_MAP.get(el2) == el1:
        return "produced"     # el2 → el1 (el1이 el2로부터 생을 받음)
    if _OVERCOME_MAP.get(el1) == el2:
        return "overcome"     # el1 → el2 (el1이 el2를 극함)
    return "overcomed"        # el2 → el1 (el1이 el2로부터 극을 받음)


def _get_branch_relation(b1: str, b2: str) -> dict:
    """지지 관계 — {six_harmony, three_harmony, conflict}.

    saju-web getBranchRelation()과 1:1 매핑.
    """
    is_three = any(b1 in g and b2 in g and b1 != b2 for g in _THREE_HARMONY_GROUPS)
    return {
        "six_harmony": _SIX_HARMONY.get(b1) == b2,
        "three_harmony": is_three,
        "conflict": _CONFLICT.get(b1) == b2,
    }


def _day_master_element_delta(el1: str, el2: str) -> tuple[int, str, str]:
    """일간 오행 매칭 delta + relation tag + description."""
    relation = _get_element_relation(el1, el2)
    if relation == "same":
        return 10, "same", f"일간 동일 오행 ({el1}={el2}) — 안정적이나 자극은 약함"
    if relation in ("produce", "produced"):
        return 25, relation, f"일간 상생 관계 ({el1}↔{el2}) — 서로 도움"
    # overcome / overcomed
    return -10, relation, f"일간 상극 관계 ({el1}↔{el2}) — 갈등 가능"


def _branch_interaction_delta(b1: str, b2: str) -> tuple[int, dict, str]:
    """일지 6합/3합/충 delta + flags + description."""
    rel = _get_branch_relation(b1, b2)
    delta = 0
    parts: list[str] = []
    if rel["six_harmony"]:
        delta += 20
        parts.append(f"일지 6합 ({b1}+{b2})")
    if rel["three_harmony"]:
        delta += 15
        parts.append(f"일지 3합 ({b1}+{b2})")
    if rel["conflict"]:
        delta -= 20
        parts.append(f"일지 충 ({b1}↔{b2})")
    if not parts:
        parts.append(f"일지 중립 ({b1}, {b2})")
    return delta, rel, " · ".join(parts)


# ─── 메인 ─────────────────────────────────────────────────────────
def calculate_compatibility(saju_a: Dict[str, Any], saju_b: Dict[str, Any]) -> Dict[str, Any]:
    """두 사주 궁합 점수 (0~100) + breakdown.

    Args:
        saju_a: calculate_saju() 결과 — `saju["day"]["stem"|"branch"|"element"]` 사용
        saju_b: 두 번째 사주

    Returns:
        {
            "score": int (0~100),
            "breakdown": {
                "day_master_element": {"score": int, "relation": str, "description": str},
                "branch_interaction": {"score": int, "flags": dict, "description": str},
                "base": 50,
            }
        }
    """
    day_a = saju_a["day"]
    day_b = saju_b["day"]

    el1 = day_a.get("element") or FIVE_ELEMENTS[day_a["stem"]]
    el2 = day_b.get("element") or FIVE_ELEMENTS[day_b["stem"]]
    b1 = day_a["branch"]
    b2 = day_b["branch"]

    elem_delta, elem_relation, elem_desc = _day_master_element_delta(el1, el2)
    branch_delta, branch_flags, branch_desc = _branch_interaction_delta(b1, b2)

    raw = 50 + elem_delta + branch_delta
    score = max(0, min(100, raw))

    return {
        "score": score,
        "breakdown": {
            "base": 50,
            "day_master_element": {
                "score": elem_delta,
                "relation": elem_relation,
                "element_a": el1,
                "element_b": el2,
                "description": elem_desc,
            },
            "branch_interaction": {
                "score": branch_delta,
                "flags": branch_flags,
                "branch_a": b1,
                "branch_b": b2,
                "description": branch_desc,
            },
        },
    }
