from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Callable, Dict, List, Optional


@dataclass
class Widget:
    kind: str
    title: str
    data: Dict[str, Any] = field(default_factory=dict)


class Section:
    def __init__(self, title: str) -> None:
        self.title = title
        self.widgets: List[Widget] = []

    def add_paragraph(self, title: str, text: str) -> Widget:
        widget = Widget("paragraph", title, {"text": text})
        self.widgets.append(widget)
        return widget

    def add_button(self, title: str, callback: Optional[Callable[[], None]] = None, hotkey: Optional[str] = None) -> Widget:
        widget = Widget("button", title, {"callback": callback, "hotkey": hotkey})
        self.widgets.append(widget)
        return widget

    def add_input(self, title: str, placeholder: str = "", required: bool = False, input_type: str = "text") -> Widget:
        widget = Widget("input", title, {"placeholder": placeholder, "required": required, "input_type": input_type})
        self.widgets.append(widget)
        return widget

    def add_toggle(self, title: str, default: bool = False) -> Widget:
        widget = Widget("toggle", title, {"value": default})
        self.widgets.append(widget)
        return widget

    def add_table(self, title: str, columns: List[str], rows: List[List[str]], searchable: bool = False, editable: bool = False) -> Widget:
        widget = Widget(
            "table",
            title,
            {"columns": columns, "rows": rows, "searchable": searchable, "editable": editable},
        )
        self.widgets.append(widget)
        return widget

    def add_json_viewer(self, title: str, data: Any) -> Widget:
        widget = Widget("json", title, {"data": data})
        self.widgets.append(widget)
        return widget

    def add_log_viewer(self, title: str) -> Widget:
        widget = Widget("logs", title, {"entries": []})
        self.widgets.append(widget)
        return widget

    def add_stat(self, title: str, value: str, tone: str = "info") -> Widget:
        widget = Widget("stat", title, {"value": value, "tone": tone})
        self.widgets.append(widget)
        return widget

    def add_key_value(self, key: str, value: str) -> Widget:
        widget = Widget("key_value", key, {"value": value})
        self.widgets.append(widget)
        return widget

    def render(self) -> str:
        lines = [f"## {self.title}"]
        for widget in self.widgets:
            if widget.kind == "paragraph":
                lines.append(f"- {widget.title}: {widget.data['text']}")
            elif widget.kind == "stat":
                lines.append(f"- {widget.title}: {widget.data['value']} [{widget.data['tone']}]")
            elif widget.kind == "key_value":
                lines.append(f"- {widget.title}: {widget.data['value']}")
            elif widget.kind == "button":
                suffix = f" (hotkey: {widget.data['hotkey']})" if widget.data.get("hotkey") else ""
                lines.append(f"- [Button] {widget.title}{suffix}")
            elif widget.kind == "toggle":
                lines.append(f"- [Toggle] {widget.title} = {widget.data['value']}")
            elif widget.kind == "input":
                lines.append(f"- [Input:{widget.data['input_type']}] {widget.title}")
            elif widget.kind == "table":
                lines.append(f"- [Table] {widget.title} columns={widget.data['columns']} rows={len(widget.data['rows'])}")
            elif widget.kind == "json":
                lines.append(f"- [JSON] {widget.title}")
            elif widget.kind == "logs":
                lines.append(f"- [Logs] {widget.title}")
            else:
                lines.append(f"- [{widget.kind}] {widget.title}")
        return "\n".join(lines)


class Window:
    def __init__(self, title: str, subtitle: str = "") -> None:
        self.title = title
        self.subtitle = subtitle
        self.sections: List[Section] = []
        self.logs: List[tuple[str, str]] = []

    def create_section(self, title: str) -> Section:
        section = Section(title)
        self.sections.append(section)
        return section

    def log(self, *args: str) -> None:
        if len(args) == 1:
            level, message = "INFO", args[0]
        elif len(args) >= 2:
            level, message = args[0], args[1]
        else:
            level, message = "INFO", ""
        self.logs.append((level, message))

    def render(self) -> str:
        lines = [f"# {self.title}", self.subtitle] if self.subtitle else [f"# {self.title}"]
        if self.logs:
            lines.append("")
            lines.append("### Logs")
            for level, message in self.logs[-5:]:
                lines.append(f"- [{level}] {message}")
        if self.sections:
            lines.append("")
            for section in self.sections:
                lines.append(section.render())
                lines.append("")
        return "\n".join(lines).rstrip()

    def run(self) -> None:
        print(self.render())


class App:
    def __init__(self, theme: str = "aurora", icon_pack: str = "emoji") -> None:
        self.theme = theme
        self.icon_pack = icon_pack

    def create_window(self, title: str, subtitle: str = "") -> Window:
        return Window(title, subtitle)


def main() -> None:
    app = App()
    window = app.create_window("Nest UI", "CLI entrypoint")
    section = window.create_section("Overview")
    section.add_paragraph("Status", "Nest UI is installed correctly.")
    window.run()
