from __future__ import annotations

import html
from typing import Any



def preview_text(value: Any, limit: int = 700) -> str:
    text = str(value or "")
    if len(text) > limit:
        text = text[:limit] + "…"
    return html.escape(text)


preview_html = preview_text



def _code(value: Any) -> str:
    return f"<code>{html.escape(str(value))}</code>"



def _tool_result_state(result: Any) -> tuple[str, str, str | None]:
    if not isinstance(result, dict):
        return "✅", "completed", preview_text(result, 260)
    if result.get("error"):
        return "⚠️", "handled error", preview_text(result.get("error"), 260)
    if result.get("timed_out"):
        return "⏱️", "timed out", preview_text(result, 260)
    exit_code = result.get("exit_code")
    if isinstance(exit_code, int) and exit_code != 0:
        preview_source = result.get("stderr") or result.get("stdout") or result
        return "⚠️", f"exit code {exit_code}", preview_text(preview_source, 260)
    return "✅", "completed", preview_text(result, 260)



def build_progress_status(payload: dict[str, Any]) -> str | None:
    event = payload.get("event")
    if event == "agent_iteration_started":
        return "\n".join(
            [
                "<b>🤖 Agent is thinking</b>",
                f"• iteration: {_code(payload.get('iteration'))}",
                f"• provider: {_code(payload.get('provider'))}",
                f"• model: {_code(payload.get('model'))}",
            ]
        )
    if event == "provider_generate_error" and not payload.get("will_retry"):
        return "\n".join(
            [
                "<b>❌ Provider error</b>",
                f"• iteration: {_code(payload.get('iteration'))}",
                f"• provider: {_code(payload.get('provider'))}",
                f"• error: {preview_text(payload.get('error'), 260)}",
            ]
        )
    if event == "tool_call_started":
        return "\n".join(
            [
                "<b>🛠️ Tool call</b>",
                f"• iteration: {_code(payload.get('iteration'))}",
                f"• tool: {_code(payload.get('tool'))}",
                "• status: <i>running…</i>",
            ]
        )
    if event == "tool_call_finished":
        icon, status, preview = _tool_result_state(payload.get("result"))
        lines = [
            f"<b>{icon} Tool result</b>",
            f"• iteration: {_code(payload.get('iteration'))}",
            f"• tool: {_code(payload.get('tool'))}",
            f"• status: {html.escape(status)}",
        ]
        if preview:
            lines.append(f"• preview: {preview}")
        return "\n".join(lines)
    if event == "provider_retry_scheduled":
        delay = payload.get("delay_sec")
        retry_in = f"{delay:.1f}s" if isinstance(delay, (int, float)) else str(delay)
        return "\n".join(
            [
                "<b>🔁 Provider retry</b>",
                f"• iteration: {_code(payload.get('iteration'))}",
                f"• provider: {_code(payload.get('provider'))}",
                f"• attempt: {_code(payload.get('attempt'))}/{_code(payload.get('max_attempts'))}",
                f"• retry in: {_code(retry_in)}",
                f"• reason: {preview_text(payload.get('error'), 220)}",
            ]
        )
    if event == "agent_finished":
        return render_progress_finish(
            {
                "iterations": payload.get("iteration"),
                "session_closed": payload.get("session_closed"),
                "security_mode": payload.get("security_mode"),
            }
        )
    return None


render_progress_status = build_progress_status



def render_progress_finish(payload: dict[str, Any]) -> str:
    session_closed = bool(payload.get("session_closed"))
    icon = "🏁" if session_closed else "✅"
    status = "session closed" if session_closed else "waiting for next message"
    return "\n".join(
        [
            f"<b>{icon} Agent Mode finished</b>",
            f"• iterations: {_code(payload.get('iterations'))}",
            f"• session closed: {_code(payload.get('session_closed'))}",
            f"• mode: {_code(payload.get('security_mode'))}",
            f"• next state: {html.escape(status)}",
        ]
    )


__all__ = [
    "preview_text",
    "preview_html",
    "build_progress_status",
    "render_progress_status",
    "render_progress_finish",
]
