from __future__ import annotations

from dataclasses import dataclass
from string.templatelib import Template

from pyview import LiveView, LiveViewSocket, Depends
from pyview.events import AutoEventDispatch
from pyview.meta import PyViewMeta
from pyview.template import TemplateView

from ...data.models import Session, SessionMetadata
from ...data.session_store import SessionIndex, get_index
from ...rendering.content_blocks import render_messages


@dataclass
class SessionDetailContext:
    session: Session | None = None
    loading: bool = True
    error: str = ""


class SessionDetailView(AutoEventDispatch, TemplateView, LiveView[SessionDetailContext]):
    async def mount(self, socket: LiveViewSocket[SessionDetailContext], session):
        socket.context = SessionDetailContext(loading=True)

    async def handle_params(self, socket: LiveViewSocket[SessionDetailContext], project_dir: str = "", session_id: str = "", index: SessionIndex = Depends(get_index)):
        session_data = index.get_session(project_dir, session_id)
        if session_data is None:
            socket.context = SessionDetailContext(loading=False, error=f"Session not found: {session_id}")
        else:
            socket.context = SessionDetailContext(session=session_data, loading=False)
            socket.live_title = session_data.metadata.summary or "Session"

    def template(self, context: SessionDetailContext, meta: PyViewMeta) -> Template:
        if context.loading:
            return t"""<div class="loading">Loading\u2026</div>"""

        if context.error:
            return t"""<div class="app">
                <div class="top-bar">
                    <a href="/" class="back-link" data-phx-link="redirect" data-phx-link-state="push">&larr; sessions</a>
                </div>
                <div class="error-callout">{context.error}</div>
            </div>"""

        s = context.session
        m = s.metadata
        summary = m.summary or m.first_message_preview or "Session"
        msg_count = str(len(s.messages))
        project = m.project_short_name or m.project_path
        duration = m.duration_display
        branch_el = self._render_branch(m.git_branch)
        token_el = self._render_tokens(m.token_display)
        formatted_date = m.timestamp.strftime("%b %-d, %Y \u00b7 %-I:%M %p") if m.timestamp else ""

        message_templates = render_messages(s.messages)

        return t"""<div class="app">
            <div class="top-bar">
                <a href="/" class="back-link" data-phx-link="redirect" data-phx-link-state="push">&larr; sessions</a>
                <span class="top-bar-title"><span class="project-name">{project}</span></span>
            </div>
            <div class="session-header">
                <div class="session-title">{summary}</div>
                <div class="session-meta-bar">
                    {branch_el}
                    <span class="meta-pill">{msg_count} messages</span>
                    <span class="meta-sep">&middot;</span>
                    <span class="meta-pill">{duration}</span>
                    {token_el}
                    <span class="meta-sep">&middot;</span>
                    <span class="meta-pill">{formatted_date}</span>
                </div>
            </div>
            <div class="messages">
                {message_templates}
            </div>
        </div>"""

    def _render_branch(self, branch: str) -> Template:
        if not branch:
            return t""""""
        return t"""<span class="meta-pill branch">{branch}</span>
            <span class="meta-sep">&middot;</span>"""

    def _render_tokens(self, display: str) -> Template:
        if not display:
            return t""""""
        return t"""<span class="meta-sep">&middot;</span>
            <span class="meta-pill tokens">{display}</span>"""
