"""Account screen — observer profile, subscription, and billing management.

Shows:
  - Observer display name and provider
  - Subscription status and renewal date
  - Creature count / limit
  - Billing portal link
  - Logout button
"""

from __future__ import annotations

import asyncio
from datetime import datetime

from textual.app import ComposeResult
from textual.containers import Container, Horizontal, VerticalScroll
from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Label, Static

from sibilance.api.types import CreatureStatus
from sibilance.auth.credentials import delete_credentials


class AccountScreen(Screen):
    """View account info, subscription, and billing."""

    DEFAULT_CSS = """
    AccountScreen {
        layout: vertical;
    }

    #account-header {
        dock: top;
        height: 1;
        padding: 0 2;
        background: $surface;
        color: $primary;
        text-style: bold;
        border-bottom: solid $secondary;
    }

    #account-scroll {
        height: 1fr;
        background: $background;
        padding: 1 2;
        scrollbar-color: $secondary;
        scrollbar-color-hover: $text-muted;
        scrollbar-color-active: $primary;
    }

    #account-actions {
        dock: bottom;
        height: 3;
        padding: 0 2;
        background: $surface;
        border-top: solid $secondary;
    }

    #account-actions Button {
        margin: 0 1 0 0;
        min-width: 14;
        height: 1;
        background: $panel;
        color: $text-muted;
        border: none;
    }

    #account-actions Button:hover {
        background: $secondary;
        color: $foreground;
    }

    #btn-logout {
        color: #ff6b6b;
    }

    #btn-logout:hover {
        color: #ff6b6b;
        background: $secondary;
    }

    #btn-release {
        color: #ff6b6b;
    }

    #btn-release:hover {
        color: #ff6b6b;
        background: $secondary;
    }

    #release-confirm {
        display: none;
        height: auto;
        padding: 1 2;
        background: $surface;
        border-top: solid #ff6b6b;
    }

    #release-confirm Static {
        color: #ff6b6b;
        margin-bottom: 1;
    }

    #release-confirm Button {
        margin: 0 1 0 0;
        min-width: 14;
        height: 1;
        border: none;
    }

    #btn-release-yes {
        background: #ff6b6b;
        color: $background;
    }

    #btn-release-no {
        background: $panel;
        color: $text-muted;
    }
    """

    def compose(self) -> ComposeResult:
        yield Header(show_clock=True)
        yield Label("Account", id="account-header")
        yield VerticalScroll(id="account-scroll")
        with Container(id="release-confirm"):
            yield Static("This will permanently release your creature. Are you sure?")
            with Horizontal():
                yield Button("Yes, release", id="btn-release-yes")
                yield Button("Cancel", id="btn-release-no")
        with Container(id="account-actions"):
            yield Button("Manage Billing", id="btn-billing")
            yield Button("Switch Creature", id="btn-switch")
            yield Button("Release Creature", id="btn-release")
            yield Button("Logout", id="btn-logout")
        yield Footer()

    def on_mount(self) -> None:
        self.run_worker(self._load_account(), name="load-account")

    async def _load_account(self) -> None:
        scroll = self.query_one("#account-scroll", VerticalScroll)
        scroll.remove_children()

        api = self.app.api  # type: ignore[attr-defined]

        # Observer profile
        try:
            profile = await api.get_profile()
            scroll.mount(
                Static(
                    f"[bold #e8e8ff]{profile.display_name}[/]",
                    markup=True,
                )
            )
            provider = profile.provider or "unknown"
            scroll.mount(
                Static(
                    f"[#4a4a6a]Signed in via {provider}[/]",
                    markup=True,
                )
            )
            if profile.email:
                scroll.mount(
                    Static(
                        f"[#4a4a6a]{profile.email}[/]",
                        markup=True,
                    )
                )
        except Exception as exc:
            scroll.mount(Static(f"[#4a4a6a]Profile unavailable: {exc}[/]", markup=True))

        scroll.mount(Static(""))  # spacer

        # Subscription status
        try:
            sub = await api.get_subscription_status()
            if sub.has_subscription:
                status_color = "#6bcb77" if sub.status == "active" else "#ffd93d"
                scroll.mount(
                    Static(
                        f"[{status_color}]Subscription: {sub.status or 'active'}[/]",
                        markup=True,
                    )
                )
                if sub.creature_count is not None:
                    scroll.mount(
                        Static(
                            f"[#4a4a6a]Creatures: {sub.creature_count}[/]",
                            markup=True,
                        )
                    )
                if sub.current_period_end:
                    try:
                        dt = datetime.fromisoformat(
                            sub.current_period_end.replace("Z", "+00:00")
                        )
                        scroll.mount(
                            Static(
                                f"[#4a4a6a]Renews: {dt.strftime('%b %d, %Y')}[/]",
                                markup=True,
                            )
                        )
                    except (ValueError, AttributeError):
                        pass
            else:
                scroll.mount(
                    Static(
                        "[#ff6b6b]No active subscription[/]",
                        markup=True,
                    )
                )
        except Exception:
            scroll.mount(
                Static("[#4a4a6a]Subscription info unavailable[/]", markup=True)
            )

        scroll.mount(Static(""))  # spacer

        # Creature list
        try:
            creatures = await api.get_my_creatures()
            if creatures:
                scroll.mount(
                    Static(
                        f"[bold #8888aa]Creatures ({len(creatures)})[/]",
                        markup=True,
                    )
                )
                for c in creatures:
                    status = "[#6bcb77]active[/]" if c.is_active else "[#4a4a6a]dormant[/]"
                    emotion = ""
                    if c.emotion:
                        emotion = f"  [#4a4a6a]({c.emotion.primary})[/]"
                    scroll.mount(
                        Static(
                            f"  [#e8e8ff]{c.name}[/]  {status}{emotion}",
                            markup=True,
                        )
                    )
            else:
                scroll.mount(
                    Static("[#4a4a6a]No creatures yet[/]", markup=True)
                )
        except Exception:
            pass

    async def on_button_pressed(self, event: Button.Pressed) -> None:
        btn_id = event.button.id

        if btn_id == "btn-billing":
            await self._open_billing()
        elif btn_id == "btn-switch":
            await self.app.action_switch_screen("creatures")  # type: ignore[attr-defined]
        elif btn_id == "btn-release":
            self.query_one("#release-confirm").styles.display = "block"
        elif btn_id == "btn-release-yes":
            self.query_one("#release-confirm").styles.display = "none"
            self.run_worker(self._release_creature(), name="release")
        elif btn_id == "btn-release-no":
            self.query_one("#release-confirm").styles.display = "none"
        elif btn_id == "btn-logout":
            await self._logout()

    async def _open_billing(self) -> None:
        try:
            api = self.app.api  # type: ignore[attr-defined]
            portal = await api.create_portal_session()
            self.app.open_url(portal.url)
            self.notify("Opened billing portal in browser", timeout=3)
        except Exception as exc:
            self.notify(f"Error: {exc}", severity="error", timeout=5)

    async def _release_creature(self) -> None:
        """Release the active creature and restart the app."""
        creature: CreatureStatus | None = self.app.creature  # type: ignore[attr-defined]
        if creature is None:
            self.notify("No creature to release", severity="warning", timeout=3)
            return

        try:
            api = self.app.api  # type: ignore[attr-defined]
            await api.release_creature(creature.agent_id)
            self.app.creature = None  # type: ignore[attr-defined]
            self.notify("Creature released. Restarting...", timeout=2)
            await asyncio.sleep(1.5)
            # Clear credentials and exit — user relaunches to get hatching flow
            delete_credentials()
            self.app.exit()
        except Exception as exc:
            self.notify(f"Release failed: {exc}", severity="error", timeout=5)

    async def _logout(self) -> None:
        try:
            api = self.app.api  # type: ignore[attr-defined]
            await api.logout()
        except Exception:
            pass
        delete_credentials()
        self.notify("Logged out", timeout=2)
        await asyncio.sleep(1.0)
        self.app.exit()

    def refresh_from_creature(self, creature: CreatureStatus) -> None:
        pass
