"""
ChatUI — a polished, branded Gradio Blocks frontend for ArielAI chatbots.
"""

from __future__ import annotations

from typing import Optional

from .chatbot import Chatbot

ACCENT_COLORS: dict[str, str] = {
    "indigo": "#6366f1",
    "emerald": "#10b981",
    "rose": "#f43f5e",
    "amber": "#f59e0b",
    "blue": "#3b82f6",
    "violet": "#8b5cf6",
    "cyan": "#06b6d4",
    "slate": "#64748b",
}

_LIGHT_CSS = """
:root {{
    --accent: {accent};
    --accent-light: {accent}22;
    --bg: #f8fafc;
    --surface: #ffffff;
    --border: #e2e8f0;
    --text: #0f172a;
    --text-muted: #64748b;
    --radius: 12px;
    --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
}}
body, .gradio-container {{
    background: var(--bg) !important;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
}}
.ariel-header {{
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 12px;
    box-shadow: var(--shadow);
    border-radius: var(--radius) var(--radius) 0 0;
    margin-bottom: 0 !important;
}}
.ariel-brand {{
    font-size: 18px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.01em;
}}
.ariel-subtitle {{
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 1px;
}}
.ariel-status {{
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #22c55e;
    font-weight: 500;
}}
.ariel-status-dot {{
    width: 8px;
    height: 8px;
    background: #22c55e;
    border-radius: 50%;
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}}
@keyframes pulse {{
    0%, 100% {{ opacity: 1; }}
    50% {{ opacity: .5; }}
}}
.ariel-chat-wrap {{
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
}}
.message.bot {{
    background: var(--accent-light) !important;
    border-radius: 12px !important;
    border: 1px solid {accent}33 !important;
}}
.message.user {{
    background: var(--accent) !important;
    color: white !important;
    border-radius: 12px !important;
}}
footer, .footer {{ display: none !important; }}
.ariel-footer {{
    text-align: center;
    font-size: 11px;
    color: var(--text-muted);
    padding: 12px;
    border-top: 1px solid var(--border);
    background: var(--surface);
}}
.ariel-footer a {{ color: var(--accent); text-decoration: none; }}
{extra_css}
"""

_DARK_CSS = """
:root {{
    --accent: {accent};
    --accent-light: {accent}22;
    --bg: #0f172a;
    --surface: #1e293b;
    --border: #334155;
    --text: #f1f5f9;
    --text-muted: #94a3b8;
    --radius: 12px;
    --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.4);
}}
body, .gradio-container {{
    background: var(--bg) !important;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
    color: var(--text) !important;
}}
.ariel-header {{
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 12px;
    border-radius: var(--radius) var(--radius) 0 0;
    margin-bottom: 0 !important;
}}
.ariel-brand {{
    font-size: 18px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.01em;
}}
.ariel-subtitle {{
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 1px;
}}
.ariel-status {{
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #4ade80;
    font-weight: 500;
}}
.ariel-status-dot {{
    width: 8px;
    height: 8px;
    background: #4ade80;
    border-radius: 50%;
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}}
@keyframes pulse {{
    0%, 100% {{ opacity: 1; }}
    50% {{ opacity: .5; }}
}}
.ariel-chat-wrap {{
    background: var(--surface);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    overflow: hidden;
}}
.message.bot {{
    background: var(--accent-light) !important;
    border-radius: 12px !important;
    border: 1px solid {accent}44 !important;
    color: var(--text) !important;
}}
.message.user {{
    background: var(--accent) !important;
    color: white !important;
    border-radius: 12px !important;
}}
.gradio-container textarea, .gradio-container input {{
    background: #0f172a !important;
    color: var(--text) !important;
    border-color: var(--border) !important;
}}
footer, .footer {{ display: none !important; }}
.ariel-footer {{
    text-align: center;
    font-size: 11px;
    color: var(--text-muted);
    padding: 12px;
    border-top: 1px solid var(--border);
    background: var(--surface);
}}
.ariel-footer a {{ color: var(--accent); text-decoration: none; }}
{extra_css}
"""


class ChatUI:
    """
    A polished, branded Gradio Blocks frontend for ArielAI chatbots.

    Provides a custom header, color themes, dark/light mode, and an optional
    footer — all with zero extra dependencies.

    Basic usage::

        from arielai import Chatbot, ChatUI

        bot = Chatbot("microsoft/DialoGPT-medium")
        ui = ChatUI(bot, brand_name="MyBot", accent="indigo")
        ui.launch()

    Available accents: indigo, emerald, rose, amber, blue, violet, cyan, slate
    """

    def __init__(
        self,
        chatbot: Chatbot,
        *,
        brand_name: str = "ArielAI",
        brand_logo: Optional[str] = None,
        tagline: str = "Powered by open-source AI",
        accent: str = "indigo",
        dark_mode: bool = False,
        show_footer: bool = True,
        footer_text: str = "Built with ArielAI",
        footer_link: Optional[str] = "https://github.com/arielai/arielai",
        extra_css: str = "",
    ) -> None:
        """
        Args:
            chatbot: An ArielAI Chatbot instance.
            brand_name: Name shown in the header (e.g. "My Assistant").
            brand_logo: Optional path or URL to a logo image (shown in header).
            tagline: Short subtitle shown below the brand name.
            accent: Color accent. One of: indigo, emerald, rose, amber, blue,
                    violet, cyan, slate. Or any valid hex color (e.g. "#ff6b6b").
            dark_mode: Use a dark color scheme.
            show_footer: Show a small branding footer below the chat.
            footer_text: Text shown in the footer.
            footer_link: URL the footer text links to.
            extra_css: Any additional raw CSS to inject.
        """
        self._bot = chatbot
        self.brand_name = brand_name
        self.brand_logo = brand_logo
        self.tagline = tagline
        self.accent = ACCENT_COLORS.get(accent, accent)
        self.dark_mode = dark_mode
        self.show_footer = show_footer
        self.footer_text = footer_text
        self.footer_link = footer_link
        self.extra_css = extra_css
        self._demo: object = None

    def build(self):
        """
        Build and return the Gradio Blocks app without launching.
        Use this to embed ChatUI in a larger Gradio app.

        Returns:
            A ``gr.Blocks`` instance.
        """
        try:
            import gradio as gr
        except ImportError as e:
            raise ImportError(
                "gradio is required. Install it with: pip install arielai"
            ) from e

        css_template = _DARK_CSS if self.dark_mode else _LIGHT_CSS
        self._css = css_template.format(accent=self.accent, extra_css=self.extra_css)
        self._theme = gr.themes.Soft() if not self.dark_mode else gr.themes.Monochrome()

        with gr.Blocks(title=self.brand_name) as demo:
            with gr.Column(elem_classes=["ariel-header"]):
                with gr.Row():
                    if self.brand_logo:
                        gr.Image(
                            value=self.brand_logo,
                            show_label=False,
                            container=False,
                            height=36,
                            width=36,
                        )
                    with gr.Column(scale=10):
                        gr.HTML(
                            f'<div class="ariel-brand">{self.brand_name}</div>'
                            f'<div class="ariel-subtitle">{self.tagline}</div>'
                        )
                    gr.HTML(
                        '<div class="ariel-status">'
                        '<div class="ariel-status-dot"></div>Online'
                        "</div>"
                    )

            with gr.Column(elem_classes=["ariel-chat-wrap"]):
                chat = gr.ChatInterface(
                    fn=self._bot.chat,
                    chatbot=gr.Chatbot(
                        height=480,
                        render=False,
                    ),
                    textbox=gr.Textbox(
                        placeholder=self._bot.placeholder,
                        container=False,
                        scale=7,
                        render=False,
                    ),
                    examples=self._bot.examples,
                )

            if self.show_footer:
                if self.footer_link:
                    footer_html = (
                        f'<div class="ariel-footer">'
                        f'<a href="{self.footer_link}" target="_blank">'
                        f"{self.footer_text}</a></div>"
                    )
                else:
                    footer_html = (
                        f'<div class="ariel-footer">{self.footer_text}</div>'
                    )
                gr.HTML(footer_html)

        self._demo = demo
        return demo

    def launch(
        self,
        share: bool = False,
        server_name: str = "0.0.0.0",
        server_port: Optional[int] = None,
        inbrowser: bool = True,
        **gradio_kwargs,
    ) -> None:
        """
        Build and launch the polished ChatUI.

        Args:
            share: Create a public Gradio share link.
            server_name: Bind address.
            server_port: Port (auto-selected if None).
            inbrowser: Open the browser automatically.
            **gradio_kwargs: Extra kwargs passed to ``demo.launch()``.
        """
        demo = self.build()
        demo.launch(
            share=share,
            server_name=server_name,
            server_port=server_port,
            inbrowser=inbrowser,
            css=self._css,
            theme=self._theme,
            **gradio_kwargs,
        )

    def close(self) -> None:
        """Shut down the Gradio server."""
        if self._demo is not None:
            self._demo.close()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    @staticmethod
    def list_accents() -> dict[str, str]:
        """Return available accent names and their hex values."""
        return dict(ACCENT_COLORS)
