from __future__ import annotations

from textual import on, work
from textual.app import ComposeResult
from textual.containers import Vertical, VerticalScroll
from textual.events import Click, Key
from textual.screen import ModalScreen
from textual.timer import Timer
from textual.widgets import Button, Input, Label, ListItem, ListView, Static


class GroupUserResult(ListItem):
    def __init__(self, user: dict) -> None:
        super().__init__()
        self.user_data = user

    def compose(self) -> ComposeResult:
        u = self.user_data
        name = u.get("display_name") or u.get("username", "?")
        username = u.get("username", "")
        yield Static(f"{name} [dim]@{username}[/]")


class SelectedMember(Static):
    def __init__(self, user: dict) -> None:
        self.user_data = user
        name = user.get("display_name") or user.get("username", "?")
        super().__init__(f"[#7aa2f7]{name}[/] [dim]\u00d7[/]", classes="selected-member")


class GroupScreen(ModalScreen[dict | None]):

    def __init__(self) -> None:
        super().__init__()
        self._selected: list[dict] = []
        self._debounce_timer: Timer | None = None

    def compose(self) -> ComposeResult:
        with Vertical(id="group-modal"):
            yield Label("create group", id="modal-title")
            yield Input(placeholder="group name", id="group-name")
            yield Input(placeholder="search users to add...", id="group-search")
            yield ListView(id="group-results")
            yield Label("[dim]members:[/]", id="members-label")
            yield VerticalScroll(id="selected-members")
            yield Button("create", id="create-group-btn", variant="primary")

    def on_mount(self) -> None:
        self.query_one("#group-name", Input).focus()

    @on(Input.Changed, "#group-search")
    def on_search_changed(self, event: Input.Changed) -> None:
        if self._debounce_timer:
            self._debounce_timer.stop()
        self._debounce_timer = self.set_timer(
            0.3, lambda: self._search(event.value)
        )

    @work(exclusive=True)
    async def _search(self, query: str) -> None:
        results_view = self.query_one("#group-results", ListView)
        await results_view.clear()

        if not query.strip():
            return

        api = self.app.api
        try:
            users = await api.search_users(query.strip())
        except Exception:
            users = []

        selected_ids = {u["id"] for u in self._selected}
        for user in users:
            if user["id"] not in selected_ids:
                await results_view.append(GroupUserResult(user))

    @on(ListView.Selected, "#group-results")
    def on_user_selected(self, event: ListView.Selected) -> None:
        item = event.item
        if isinstance(item, GroupUserResult):
            self._add_member(item.user_data)

    @work(exclusive=False)
    async def _add_member(self, user: dict) -> None:
        if any(u["id"] == user["id"] for u in self._selected):
            return
        self._selected.append(user)
        container = self.query_one("#selected-members", VerticalScroll)
        await container.mount(SelectedMember(user))

    @on(Click)
    def on_member_click(self, event: Click) -> None:
        widget = event.widget
        if isinstance(widget, SelectedMember):
            self._selected = [
                u for u in self._selected if u["id"] != widget.user_data["id"]
            ]
            widget.remove()

    @on(Button.Pressed, "#create-group-btn")
    def on_create_pressed(self) -> None:
        self._create_group()

    @work(exclusive=True)
    async def _create_group(self) -> None:
        name = self.query_one("#group-name", Input).value.strip()
        if not name:
            self.notify("enter a group name", severity="warning")
            return
        if not self._selected:
            self.notify("add at least one member", severity="warning")
            return

        api = self.app.api
        member_ids = [u["id"] for u in self._selected]
        try:
            conv = await api.create_conversation("group", member_ids, name=name)
            self.dismiss(conv)
        except Exception as exc:
            self.notify(f"Error: {exc}", severity="error")

    @on(Input.Submitted, "#group-name")
    def on_name_submitted(self) -> None:
        self.query_one("#group-search", Input).focus()

    def on_key(self, event: Key) -> None:
        if event.key == "escape":
            event.stop()
            event.prevent_default()
            self.dismiss(None)
        elif event.key == "down":
            lv = self.query_one("#group-results", ListView)
            if lv.children:
                lv.focus()
