"""Social dynamics and relationship engine."""

from __future__ import annotations

from collections import defaultdict

from bot.services.emotion import detect_emotion
from bot.infra.db.memory_repository import memory_repository
from bot.services.memory_graph import learn_topics


RELATIONSHIPS: dict[int, dict[int, dict]] = defaultdict(dict)
GROUP_MOOD: dict[int, list[str]] = defaultdict(list)
SOCIAL_PATTERNS: dict[int, dict] = defaultdict(dict)


INSIDE_JOKE_PATTERNS = (
    "😂",
    "🤣",
    "شوخی",
    "خفن",
    "لول",
)


def track_interaction(chat_id: int, user_id: int, text: str) -> None:
    rel = RELATIONSHIPS[chat_id].setdefault(
        user_id,
        {
            "messages": 0,
            "affinity": 0,
            "trust": 0,
            "dominant_emotion": "neutral",
            "inside_jokes": [],
            "favorite_topics": set(),
            "memory_fragments": [],
        },
    )

    rel["messages"] += 1

    emotion = detect_emotion(text)
    rel["dominant_emotion"] = emotion

    if emotion in {"happy", "technical"}:
        rel["affinity"] += 1
        rel["trust"] += 1

    elif emotion == "angry":
        rel["affinity"] -= 1
        rel["trust"] -= 1

    lowered = text.lower()

    learn_topics(user_id, lowered)

    if any(pattern in lowered for pattern in INSIDE_JOKE_PATTERNS):
        jokes = rel["inside_jokes"]

        jokes.append(text[:80])

        if len(jokes) > 5:
            jokes.pop(0)

    if any(word in lowered for word in ("پایتون", "کد", "ربات", "سرور")):
        rel["favorite_topics"].add("tech")

    if any(word in lowered for word in ("میم", "شوخی", "ترول")):
        rel["favorite_topics"].add("fun")

    fragments = rel["memory_fragments"]

    memorable = (
        len(text) > 25
        or emotion in {"happy", "sad", "angry"}
    )

    if memorable:
        fragments.append(text[:120])

        if len(fragments) > 8:
            fragments.pop(0)


async def remember_event(chat_id: int, user_id: int, text: str) -> None:
    emotion = detect_emotion(text)

    event_type = "conversation"

    if emotion == "happy":
        event_type = "fun"
    elif emotion == "technical":
        event_type = "technical"
    elif emotion == "sad":
        event_type = "emotional"

    await memory_repository.add_memory_event(
        chat_id,
        user_id,
        event_type,
        text,
    )

    moods = GROUP_MOOD[chat_id]
    moods.append(emotion)

    if len(moods) > 50:
        moods.pop(0)

    social = SOCIAL_PATTERNS[chat_id]

    social.setdefault("active_users", {})
    social.setdefault("conflicts", 0)
    social.setdefault("humor", 0)
    social.setdefault("technical", 0)

    social["active_users"][user_id] = rel["messages"]

    if emotion == "angry":
        social["conflicts"] += 1

    elif emotion == "happy":
        social["humor"] += 1

    elif emotion == "technical":
        social["technical"] += 1


def get_group_mood(chat_id: int) -> str:
    moods = GROUP_MOOD.get(chat_id, [])

    if not moods:
        return "neutral"

    return max(set(moods), key=moods.count)


def build_relationship_context(chat_id: int, user_id: int) -> str:
    rel = RELATIONSHIPS.get(chat_id, {}).get(user_id)

    if not rel:
        return ""

    affinity = rel.get("affinity", 0)

    if affinity >= 10:
        vibe = "کاربر صمیمی و قدیمی"
    elif affinity >= 3:
        vibe = "کاربر آشنا"
    elif affinity <= -3:
        vibe = "کاربر پرتنش"
    else:
        vibe = "کاربر عادی"

    return (
        "اطلاعات رابطه اجتماعی:\n"
        f"- vibe: {vibe}\n"
        f"- affinity: {affinity}\n"
        f"- trust: {rel.get('trust', 0)}\n"
        f"- dominant emotion: {rel.get('dominant_emotion', 'neutral')}\n"
        f"- favorite topics: {', '.join(rel.get('favorite_topics', [])) or 'unknown'}\n"
        f"- inside jokes: {len(rel.get('inside_jokes', []))}\n"
        f"- shared memories: {len(rel.get('memory_fragments', []))}"
    )


def relationship_snapshot(chat_id: int, user_id: int) -> dict:
    return RELATIONSHIPS.get(chat_id, {}).get(user_id, {})


def social_summary(chat_id: int) -> str:
    social = SOCIAL_PATTERNS.get(chat_id)

    if not social:
        return ""

    active_users = social.get("active_users", {})

    dominant_user = None

    if active_users:
        dominant_user = max(active_users.items(), key=lambda item: item[1])[0]

    vibe = "متعادل"

    if social.get("conflicts", 0) > social.get("humor", 0):
        vibe = "پرتنش"

    elif social.get("technical", 0) > social.get("humor", 0):
        vibe = "فنی"

    elif social.get("humor", 0) >= 5:
        vibe = "شوخ و پرانرژی"

    return (
        "تحلیل اجتماعی گروه:\n"
        f"- vibe کلی: {vibe}\n"
        f"- کاربر فعال: {dominant_user or 'unknown'}\n"
        f"- سطح تنش: {social.get('conflicts', 0)}\n"
        f"- سطح شوخی: {social.get('humor', 0)}"
    )


def recall_memory(chat_id: int, user_id: int) -> str:
    rel = RELATIONSHIPS.get(chat_id, {}).get(user_id)

    if not rel:
        return ""

    memories = rel.get("memory_fragments", [])

    if not memories:
        return ""

    recent = memories[-3:]

    return (
        "چیزهایی که از تعاملات قبلی یادت میاد:\n"
        + "\n".join(f"- {item}" for item in recent)
    )


async def timeline_memory(chat_id: int, user_id: int) -> str:
    events = await memory_repository.recent_events(chat_id, user_id)

    if not events:
        return ""

    lines = ["خاطرات بلندمدت از این کاربر:"]

    for event in events:
        content = event[1] if not isinstance(event, dict) else event["content"]
        event_type = event[0] if not isinstance(event, dict) else event["event_type"]

        lines.append(f"- ({event_type}) {content[:80]}")

    return "\n".join(lines)


async def persist_relationship(chat_id: int, user_id: int) -> None:
    rel = RELATIONSHIPS.get(chat_id, {}).get(user_id)

    if not rel:
        return

    payload = {
        "messages": rel.get("messages", 0),
        "affinity": rel.get("affinity", 0),
        "trust": rel.get("trust", 0),
        "dominant_emotion": rel.get("dominant_emotion", "neutral"),
        "inside_jokes": rel.get("inside_jokes", []),
        "favorite_topics": list(rel.get("favorite_topics", [])),
        "memory_fragments": rel.get("memory_fragments", []),
    }

    await memory_repository.save_memory(chat_id, user_id, payload)


async def hydrate_relationship(chat_id: int, user_id: int) -> None:
    existing = RELATIONSHIPS.get(chat_id, {}).get(user_id)

    if existing:
        return

    payload = await memory_repository.load_memory(chat_id, user_id)

    if not payload:
        return

    RELATIONSHIPS[chat_id][user_id] = {
        **payload,
        "favorite_topics": set(payload.get("favorite_topics", [])),
    }
