from __future__ import annotations

import argparse
from datetime import UTC, datetime
from typing import Any

from textual.app import App, ComposeResult
from textual.widgets import Header, RichLog, Static

from relay.tui.injector import TmuxInjector
from relay.tui.sse_client import SSEListener


class StatusBar(Static):
    DEFAULT_CSS = """
    StatusBar {
        dock: bottom;
        height: 1;
        background: $surface;
        color: $text-muted;
        padding: 0 1;
    }
    """


class RelayTUI(App[None]):
    TITLE = "Relay"

    CSS = """
    Screen {
        layout: vertical;
    }

    RichLog {
        height: 1fr;
        border: solid $accent;
        scrollbar-size: 1 1;
    }
    """

    BINDINGS = [
        ("q", "quit", "Quit"),
    ]

    def __init__(
        self,
        server_url: str,
        group_id: str,
        peer_id: str,
        target_pane: str,
        groups_header: str = "",
    ) -> None:
        super().__init__()
        self.server_url = server_url
        self.group_id = group_id
        self.peer_id = peer_id
        self.target_pane = target_pane
        self.all_groups = (
            [pair.split(":")[0] for pair in groups_header.split(",") if pair]
            if groups_header
            else [group_id]
        )
        self.listener = SSEListener(
            server_url=server_url,
            group_id=group_id,
            peer_id=peer_id,
            on_event=self.handle_event,
            groups_header=groups_header,
        )
        self.injector = TmuxInjector(target_pane=target_pane)

    def compose(self) -> ComposeResult:
        yield Header(show_clock=True)
        yield RichLog(highlight=True, markup=True, wrap=True, auto_scroll=True, id="chat-log")
        yield StatusBar("Connecting...", id="status-bar")

    async def on_mount(self) -> None:
        groups_label = ", ".join(self.all_groups)
        self.title = f"Also — {groups_label}"
        self.sub_title = ""
        await self.listener.start()
        self.set_interval(2.0, self._update_status)

    async def on_unmount(self) -> None:
        await self.listener.stop()

    async def handle_event(self, event: dict[str, Any]) -> None:
        log = self.query_one("#chat-log", RichLog)
        event_type = event.get("type", "unknown")
        timestamp = datetime.now(UTC).strftime("%H:%M:%S")

        if event_type == "message":
            sender = event.get("from_display", "unknown")
            content = event.get("preview", "")
            group = event.get("group_id", self.group_id)
            log.write(f"[dim]{timestamp}[/] [bold green]{group}[/] [bold]{sender}[/]: {content}")
            await self.injector.inject_notification(
                from_display=sender,
                group_id=group,
            )

        elif event_type == "peer_joined":
            peer_display = event.get("display_name", event.get("peer_id", "unknown"))
            group = event.get("group_id", self.group_id)
            log.write(f"[dim]{timestamp}[/] [bold green]{group}[/] [bold yellow]JOIN[/] {peer_display}")

        elif event_type == "peer_left":
            peer_display = event.get("display_name", event.get("peer_id", "unknown"))
            group = event.get("group_id", self.group_id)
            log.write(f"[dim]{timestamp}[/] [bold green]{group}[/] [bold red]LEFT[/] {peer_display}")

        else:
            log.write(f"[dim]{timestamp}[/] [dim]{event}[/]")

    async def _update_status(self) -> None:
        status = self.query_one("#status-bar", StatusBar)
        groups_label = ", ".join(self.all_groups)
        if self.listener.connected:
            status.update(f"[green]●[/] {groups_label}")
        else:
            status.update(f"[red]● Reconnecting...[/]")


def main() -> None:
    parser = argparse.ArgumentParser(description="Relay TUI")
    parser.add_argument("--server-url", required=True)
    parser.add_argument("--group-id", required=True)
    parser.add_argument("--peer-id", required=True)
    parser.add_argument("--target-pane", required=True)
    parser.add_argument("--groups-header", default="")
    args = parser.parse_args()

    app = RelayTUI(
        server_url=args.server_url,
        group_id=args.group_id,
        peer_id=args.peer_id,
        target_pane=args.target_pane,
        groups_header=args.groups_header,
    )
    app.run()


if __name__ == "__main__":
    main()
