"""Session output persistence — write invoke / dialog results to local files."""

from __future__ import annotations

import json as json_lib
from datetime import UTC, datetime
from pathlib import Path

from alice_cli.console import print_success
from alice_cli.models import SaveFormat


def _timestamp() -> str:
    return datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S UTC")


# ---------------------------------------------------------------------------
# invoke session
# ---------------------------------------------------------------------------


def _format_session_markdown(prompt: str, model: str, content: str) -> str:
    lines = [
        f"# ALiCE Session — {_timestamp()}",
        "",
        f"**Model:** {model}",
        "",
        f"**Prompt:** {prompt}",
        "",
        "---",
        "",
        content.strip(),
        "",
    ]
    return "\n".join(lines)


def _format_session_json(prompt: str, model: str, content: str) -> str:
    return (
        json_lib.dumps(
            {
                "timestamp": _timestamp(),
                "model": model,
                "prompt": prompt,
                "response": content.strip(),
            },
            indent=2,
        )
        + "\n"
    )


def _format_session_text(prompt: str, model: str, content: str) -> str:
    lines = [
        f"ALiCE Session — {_timestamp()}",
        f"Model: {model}",
        f"Prompt: {prompt}",
        "",
        content.strip(),
        "",
    ]
    return "\n".join(lines)


_SESSION_FORMATTERS = {
    SaveFormat.MARKDOWN: _format_session_markdown,
    SaveFormat.JSON: _format_session_json,
    SaveFormat.TEXT: _format_session_text,
}


def save_session(
    *,
    path: str,
    prompt: str,
    model: str,
    content: str,
    quiet: bool,
    fmt: SaveFormat = SaveFormat.MARKDOWN,
) -> Path:
    """Save an invoke session to a local file in the requested format."""
    formatter = _SESSION_FORMATTERS[fmt]
    dest = Path(path)
    dest.write_text(formatter(prompt, model, content), encoding="utf-8")
    print_success(f"Session saved to {dest}", quiet)
    return dest


# ---------------------------------------------------------------------------
# dialog session
# ---------------------------------------------------------------------------


def _format_dialog_markdown(
    prompt: str,
    model_a: str,
    model_b: str,
    rounds: int,
    transcript: list[tuple[str, str]],
) -> str:
    lines = [
        f"# ALiCE Dialog — {_timestamp()}",
        "",
        f"**Models:** {model_a} ↔ {model_b}  ",
        f"**Rounds:** {rounds}  ",
        f"**Prompt:** {prompt}",
        "",
        "---",
        "",
    ]
    for speaker, text in transcript:
        lines.append(f"## {speaker}")
        lines.append("")
        lines.append(text.strip())
        lines.append("")
    return "\n".join(lines)


def _format_dialog_json(
    prompt: str,
    model_a: str,
    model_b: str,
    rounds: int,
    transcript: list[tuple[str, str]],
) -> str:
    return (
        json_lib.dumps(
            {
                "timestamp": _timestamp(),
                "models": [model_a, model_b],
                "rounds": rounds,
                "prompt": prompt,
                "transcript": [
                    {"speaker": speaker, "text": text.strip()} for speaker, text in transcript
                ],
            },
            indent=2,
        )
        + "\n"
    )


def _format_dialog_text(
    prompt: str,
    model_a: str,
    model_b: str,
    rounds: int,
    transcript: list[tuple[str, str]],
) -> str:
    lines = [
        f"ALiCE Dialog — {_timestamp()}",
        f"Models: {model_a} / {model_b}",
        f"Rounds: {rounds}",
        f"Prompt: {prompt}",
        "",
    ]
    for speaker, text in transcript:
        lines.append(f"[{speaker}]")
        lines.append(text.strip())
        lines.append("")
    return "\n".join(lines)


_DIALOG_FORMATTERS = {
    SaveFormat.MARKDOWN: _format_dialog_markdown,
    SaveFormat.JSON: _format_dialog_json,
    SaveFormat.TEXT: _format_dialog_text,
}


def save_dialog_session(
    *,
    path: str,
    prompt: str,
    model_a: str,
    model_b: str,
    rounds: int,
    transcript: list[tuple[str, str]],
    quiet: bool,
    fmt: SaveFormat = SaveFormat.MARKDOWN,
) -> Path:
    """Save a dialog transcript to a local file in the requested format."""
    formatter = _DIALOG_FORMATTERS[fmt]
    dest = Path(path)
    dest.write_text(
        formatter(prompt, model_a, model_b, rounds, transcript),
        encoding="utf-8",
    )
    print_success(f"Dialog saved to {dest}", quiet)
    return dest
