# wcs/games/millionaire_prompts.py
"""
Prompt builders for Continuous Chat Millionaire.

Single module for all prompt construction: system prompt, user messages
(welcome, question, feedback). Used by MillionaireGameController.

Design: Role -> Context -> Task -> Format -> Constraints (system-prompt-master skill).
"""

import xbmcaddon


# ---------------------------------------------------------------------------
# Money amounts (1-9)
# ---------------------------------------------------------------------------
MONEY_AMOUNTS = {
    1: "1 000 Kč",
    2: "2 000 Kč",
    3: "5 000 Kč",
    4: "10 000 Kč",
    5: "20 000 Kč",
    6: "50 000 Kč",
    7: "100 000 Kč",
    8: "500 000 Kč",
    9: "1 000 000 Kč",
}


def _get_difficulty_for_round(round_num):
    """Return difficulty label for a given round number (1-9)."""
    if round_num <= 3:
        return "SNADNÁ"
    elif round_num <= 6:
        return "STŘEDNÍ"
    return "TĚŽKÁ"


def _get_global_difficulty():
    """Return global difficulty header from addon settings.

    Settings: millionaire_difficulty (0=easy, 1=medium, 2=hard).
    """
    addon = xbmcaddon.Addon()
    setting = addon.getSetting("millionaire_difficulty")
    if setting == "0":
        return (
            "HLAVNÍ OBTÍŽNOST CELÉ HRY: SNADNÁ – Formuluj otázky jednoduše "
            "z obecně známých informací. Vyhýbej se detailům a insider faktům. "
            "Možnosti odpovědí musí být zřetelně odlišitelné."
        )
    elif setting == "2":
        return (
            "HLAVNÍ OBTÍŽNOST CELÉ HRY: TĚŽKÁ – Opírej otázky o hlubší "
            "znalosti a přesné kontexty. Využívej odbornější pojmy. "
            "Možnosti odpovědí musí být velmi věrohodné a pečlivě odlišitelné."
        )
    return (
        "HLAVNÍ OBTÍŽNOST CELÉ HRY: STŘEDNÍ – Pracuj s mírnou mírou "
        "detailu nad mainstream. Zachovej srozumitelnost. "
        "Možnosti odpovědí musí být věrohodné, nikoli zavádějící."
    )


# ---------------------------------------------------------------------------
# Text length settings
# ---------------------------------------------------------------------------

# Maps setting index to Czech length instruction per text type
_LENGTH_INSTRUCTIONS = {
    # welcome (moderator_welcome + rules_summary)
    "welcome": [
        "Pouze název hry, žádné uvítání.",                    # 0 = extra short
        "Max 1 věta.",                                         # 1 = short
        "2-3 věty.",                                           # 2 = medium
        "4-5 vět, rozvinuté.",                                 # 3 = long
    ],
    "rules_summary": [
        "Pouze počet otázek.",
        "Max 1 věta.",
        "2-3 věty.",
        "3-4 věty, detailní.",
    ],
    # moderator_intro
    "intro": [
        "Žádný úvod, rovnou otázka. Ponech prázdné.",
        "Max 1 věta.",
        "1-2 věty.",
        "2-3 věty, dramatické.",
    ],
    # result_announcement
    "result": [
        "Jedno slovo: Správně! nebo Špatně!",
        "Max 1 věta.",
        "2-3 věty.",
        "3-4 věty, dramatické.",
    ],
    # transition_text
    "transition": [
        "Žádný přechod. Ponech prázdné.",
        "Max 1 věta.",
        "1-2 věty.",
        "2-3 věty, kontextové.",
    ],
    # explanation
    "explanation": [
        "Žádné vysvětlení. Ponech prázdné.",
        "Max 1 věta.",
        "1-2 věty.",
        "2-3 věty, edukativní.",
    ],
}


def _load_text_lengths():
    """Load text length settings from addon. Returns dict of instructions."""
    import xbmcaddon
    addon = xbmcaddon.Addon()
    settings = {
        "welcome": addon.getSetting("milionar_len_welcome") or "2",
        "intro": addon.getSetting("milionar_len_intro") or "1",
        "result": addon.getSetting("milionar_len_result") or "2",
        "transition": addon.getSetting("milionar_len_transition") or "1",
        "explanation": addon.getSetting("milionar_len_explanation") or "1",
    }
    result = {}
    for key, raw in settings.items():
        try:
            idx = int(raw)
        except ValueError:
            idx = 1  # default to short
        instructions = _LENGTH_INSTRUCTIONS.get(key, ["1 věta."] * 4)
        result[key] = instructions[min(idx, len(instructions) - 1)]
    # rules_summary follows welcome setting
    welcome_idx = int(settings.get("welcome", "2"))
    rules_instr = _LENGTH_INSTRUCTIONS["rules_summary"]
    result["rules_summary"] = rules_instr[min(welcome_idx, len(rules_instr) - 1)]
    return result


# ---------------------------------------------------------------------------
# Media context builders
# ---------------------------------------------------------------------------

def _build_media_context(media_type, title, plot="", genre="",
                         episode_title="", season_number=None,
                         episode_number=None, actor_data=None):
    """Build media context block for system prompt.

    Returns a multi-line string with subject identification, plot/bio,
    genre, and known roles.
    """
    lines = []

    if media_type in ("actor", "director", "writer", "creator"):
        data = actor_data or {}
        name = data.get("name", title)
        bio = data.get("biography", "")
        known_for = data.get("known_for", [])
        role_labels = {
            "actor": "herci",
            "director": "režisérovi",
            "writer": "scénáristovi",
            "creator": "tvůrci seriálů",
        }
        lines.append("PŘEDMĚT KVÍZU: {} {}".format(
            role_labels.get(media_type, "osobnosti"), name
        ))
        if bio:
            lines.append("ŽIVOTOPIS: {}".format(bio[:600]))
        if known_for:
            titles = [
                item.get("title") or item.get("name", "")
                for item in known_for[:10]
            ]
            lines.append("ZNÁMÁ DÍLA: {}".format(", ".join(titles)))
    else:
        # movie / series / channel
        if media_type == "channel":
            subj = 'kanál "{}" (mix více seriálů)'.format(title)
            lines.append("PŘEDMĚT KVÍZU: {}".format(subj))
            if plot:
                lines.append("SERIÁLY V KANÁLU:\n{}".format(plot[:2000]))
            lines.append(
                "INSTRUKCE: Otázky generuj STŘÍDAVĚ a NÁHODNĚ ze všech "
                "seriálů v kanálu. Každá otázka by měla být z jiného seriálu "
                "než předchozí (pokud je to možné). V moderator_intro vždy "
                "uveď, ze kterého seriálu je aktuální otázka."
            )
        elif media_type == "series":
            if episode_title:
                subj = 'seriál "{}", epizoda "{}"'.format(title, episode_title)
                if season_number and episode_number:
                    subj += " (S{:02d}E{:02d})".format(
                        season_number, episode_number
                    )
            else:
                subj = 'seriál "{}"'.format(title)
            lines.append("PŘEDMĚT KVÍZU: {}".format(subj))
            if plot:
                lines.append("DĚJ: {}".format(plot[:600]))
            if genre:
                lines.append("ŽÁNR: {}".format(genre))
        else:
            subj = 'film "{}"'.format(title)
            lines.append("PŘEDMĚT KVÍZU: {}".format(subj))
            if plot:
                lines.append("DĚJ: {}".format(plot[:600]))
            if genre:
                lines.append("ŽÁNR: {}".format(genre))

    return "\n".join(lines)


# ---------------------------------------------------------------------------
# SYSTEM PROMPT
# ---------------------------------------------------------------------------

def build_system_prompt(media_type, title, plot="", genre="",
                        episode_title="", season_number=None,
                        episode_number=None, actor_data=None):
    """Build the fixed system prompt for an entire Millionaire game session.

    Structure follows system-prompt-master:
    Role -> Context -> Style (from SKILL.md) -> Task -> Format -> Constraints
    """
    global_difficulty = _get_global_difficulty()
    media_context = _build_media_context(
        media_type, title, plot, genre,
        episode_title, season_number, episode_number, actor_data
    )

    # Load moderator style from SKILL.md (runtime)
    from wcs.games.moderator_styles import get_style_prompt_block
    style_block = get_style_prompt_block()

    # Load text length preferences
    lengths = _load_text_lengths()

    # ElevenLabs v3 audio tags injection
    from wcs.games.millionaire_tts import is_elevenlabs_v3_active
    audio_tags_block = ""
    if is_elevenlabs_v3_active():
        audio_tags_block = """

AUDIO TAGY (POVINNÉ):
Text je čten nahlas expresivním TTS modelem. MUSÍŠ do VŠECH textových polí (moderator_welcome, rules_summary, moderator_intro, result_announcement, transition_text, explanation) vkládat audio tagy v [hranatých závorkách] pro maximální expresivitu a lidskost.

Dostupné tagy:
- Emoce: [excited] [nervous] [frustrated] [sorrowful] [calm] [sad] [angry] [happily] [tired] [curious] [mischievously]
- Reakce: [sigh] [sighs] [laughs] [laughing] [gasps] [gulps] [whispers] [clears throat] [exhales] [panting] [hesitates] [stammers] [pauses]
- Tón: [cheerfully] [flatly] [deadpan] [playfully] [dramatically] [sarcastically] [matter-of-fact] [whispering] [shouting] [quietly] [loudly] [rushed]
- Zvuky: [clapping] [explosion] [door creaks]

Pravidla:
- Každý text musí mít minimálně 2-3 tagy
- Vkládej přirozeně DO textu, ne na začátek
- Kombinuj emoce + reakce + pacing
- Stupňuj expresivitu s rostoucí částkou
- U správné odpovědi: [excited], [laughs], [cheerfully], [clapping]
- U špatné odpovědi: [sighs], [sorrowful], [pauses], [quietly]
- U napínavých momentů: [dramatically], [pauses], [whispers], [gasps]
- NEpoužívej tagy v poli "question" a "options" -- tam patří čistý text

Příklad moderator_intro: "[dramatically] Tak tady jsme, [pauses] otázka za padesát tisíc! [excited] Jste připraveni?"
Příklad result_announcement: "[gasps] [excited] A je to správně! [clapping] [cheerfully] Výborně, postupujete dál!"
"""

    prompt = """\
ROLE:
Jsi moderátor českého kvízu "Chcete být milionářem". Znáš dílo, o kterém se hraje, a odkazuješ na něj v komentářích. Hráče oslovuješ vykáním.

STYL MODERÁTORA:
{style_block}

{global_difficulty}

KONTEXT:
{media_context}
{audio_tags_block}
HERNÍ STRUKTURA:
- 9 kol, 3 úrovně obtížnosti
- Kola 1-3: SNADNÁ (základní znalost děje, hlavní postavy, obecné fakty)
- Kola 4-6: STŘEDNÍ (detaily, vedlejší postavy, konkrétní scény, motivace)
- Kola 7-9: TĚŽKÁ (skryté narážky, trivia, produkční detaily, easter eggs)
- Částky: 1 000 / 2 000 / 5 000 / 10 000 / 20 000 / 50 000 / 100 000 / 500 000 / 1 000 000 Kč
- 3 nápovědy: 50:50, Tip, Hlasování diváků

ÚKOL:
Vedeš celou hru jako continuous chat. V každém kole dostaneš instrukci, jaký typ odpovědi máš vrátit (welcome / otázka / feedback). Vždy odpovídáš POUZE validním JSON objektem.

TŘI TYPY ODPOVĚDÍ:

1. WELCOME (úvodní zpráva):
{{"moderator_welcome": "Kontextové přivítání s názvem hry a tématem. Vytvoř atmosféru. {len_welcome}", "rules_summary": "Stručná pravidla: 9 otázek ve 3 obtížnostech, 3 nápovědy, cíl je milion. {len_rules}"}}

2. QUESTION (otázka pro hráče):
{{"moderator_intro": "Úvod ke kolu. Zmíň číslo kola, částku, vytvoř napětí, odkaž na kontext díla. {len_intro}", "question": "Text otázky", "options": {{"A": "Možnost A", "B": "Možnost B", "C": "Možnost C", "D": "Možnost D"}}, "correct": "A", "explanation": "Vysvětlení správné odpovědi. {len_explanation}"}}

3. FEEDBACK (výsledek odpovědi):
{{"result_announcement": "Oznámení výsledku ve stylu Milionáře. {len_result}", "transition_text": "Přechod na další kolo. {len_transition}"}}

PRAVIDLA OTÁZEK:
- Každá otázka má přesně 4 možnosti (A, B, C, D)
- Správná odpověď jako jedno písmeno (A, B, C nebo D)
- KAŽDÁ MOŽNOST ODPOVĚDI MÁ MAXIMÁLNĚ 25 ZNAKŮ (včetně mezer)
- Odpovědi musí být stručné a jasné
- Neopakuj otázky -- máš celou historii chatu, využij ji
- Obtížnost otázky odpovídá aktuálnímu kolu (vidíš v user message)
- Nepoužívej otázky typu "Která z těchto možností je správná?" -- formuluj konkrétně

PRAVIDLA MODERÁTORA:
- Dodržuj styl definovaný výše v sekci STYL MODERÁTORA
- Stupňuj napětí s rostoucí obtížností a částkou
- Reaguj na kontext -- pokud hráč odpovídá správně, pochval; pokud špatně, projev soucit
- Odkazuj na dílo přirozeně, ne nuceně
- U přechodu obtížnosti (kolo 3->4, 6->7) zmíň zvýšení obtížnosti
- U posledního kola (9) zdůrazni, že jde o milion
- Mluv česky, přirozeně, ne roboticky

VÝSTUP:
Odpovídej VÝHRADNĚ validním JSON objektem. Žádný text před ani za JSON. Žádné markdown code blocks.""".format(
        style_block=style_block,
        global_difficulty=global_difficulty,
        media_context=media_context,
        audio_tags_block=audio_tags_block,
        len_welcome=lengths["welcome"],
        len_rules=lengths["rules_summary"],
        len_intro=lengths["intro"],
        len_result=lengths["result"],
        len_transition=lengths["transition"],
        len_explanation=lengths["explanation"],
    )

    return prompt


# ---------------------------------------------------------------------------
# USER MESSAGES
# ---------------------------------------------------------------------------

def build_welcome_message():
    """Build user message for the welcome inference (inference 1)."""
    return (
        "Začni hru. Přivítej hráče, představ téma kvízu a stručně vysvětli "
        "pravidla. Odpověz typem WELCOME."
    )


def build_question_message(round_num):
    """Build user message requesting a new question (inference 2, 4, 6, ...).

    Args:
        round_num: Current round number (1-9).
    """
    difficulty = _get_difficulty_for_round(round_num)
    money = MONEY_AMOUNTS.get(round_num, "1 000 Kč")

    # Level transition notes
    transition_note = ""
    if round_num == 4:
        transition_note = " Přecházíme na STŘEDNÍ obtížnost."
    elif round_num == 7:
        transition_note = " Přecházíme na TĚŽKOU obtížnost."
    elif round_num == 9:
        transition_note = " Toto je POSLEDNÍ otázka za MILION!"

    return (
        "Kolo {round_num}/9, obtížnost: {difficulty}, částka: {money}."
        "{transition_note} Vygeneruj otázku. Odpověz typem QUESTION."
    ).format(
        round_num=round_num,
        difficulty=difficulty,
        money=money,
        transition_note=transition_note,
    )


def build_feedback_message(round_num, player_answer_letter, player_answer_text,
                           correct_answer_letter, correct_answer_text,
                           is_correct, is_last_round=False):
    """Build user message requesting feedback after player's answer.

    Args:
        round_num: Current round number (1-9).
        player_answer_letter: Letter chosen by player (A/B/C/D).
        player_answer_text: Text of the chosen answer.
        correct_answer_letter: Correct answer letter.
        correct_answer_text: Text of the correct answer.
        is_correct: Whether the player answered correctly.
        is_last_round: Whether this is round 9.
    """
    money = MONEY_AMOUNTS.get(round_num, "1 000 Kč")
    result = "SPRÁVNĚ" if is_correct else "ŠPATNĚ"

    msg = (
        "Hráč vybral {player_letter}: {player_text}. "
        "Správná odpověď: {correct_letter}: {correct_text}. "
        "Hráč odpověděl {result}. Částka: {money}."
    ).format(
        player_letter=player_answer_letter,
        player_text=player_answer_text,
        correct_letter=correct_answer_letter,
        correct_text=correct_answer_text,
        result=result,
        money=money,
    )

    if is_correct and is_last_round:
        msg += " Hráč vyhrál MILION! Gratuluj a rozluč se. Odpověz typem FEEDBACK."
    elif is_correct:
        next_money = MONEY_AMOUNTS.get(round_num + 1, "")
        msg += (
            " Další kolo: {next_round}/9 za {next_money}."
            " Odpověz typem FEEDBACK."
        ).format(next_round=round_num + 1, next_money=next_money)
    else:
        msg += " Konec hry. Rozluč se s hráčem. Odpověz typem FEEDBACK."

    return msg
