"""Terminal görünümü: banner, akışlı yanıt yazıcı, araç panelleri, onay istemi."""

from __future__ import annotations

from rich.console import Console
from rich.panel import Panel
from rich.rule import Rule
from rich.syntax import Syntax
from rich.table import Table
from rich.text import Text

console = Console(highlight=False, soft_wrap=False)

THEME = {
    "user": "bold cyan",
    "model": "white",
    "tool": "bold yellow",
    "ok": "bold green",
    "err": "bold red",
    "dim": "grey58",
    "think": "grey42",
}

LANG_BY_EXT = {
    "py": "python", "js": "javascript", "ts": "typescript", "tsx": "tsx",
    "jsx": "jsx", "php": "php", "html": "html", "css": "css", "json": "json",
    "sh": "bash", "bash": "bash", "ps1": "powershell", "sql": "sql",
    "yml": "yaml", "yaml": "yaml", "md": "markdown", "go": "go", "rs": "rust",
    "java": "java", "c": "c", "cpp": "cpp", "rb": "ruby",
}


def banner(model: str, base_url: str, workspace: str, tool_mode: str, yolo: bool) -> None:
    t = Table.grid(padding=(0, 2))
    t.add_column(style=THEME["dim"], justify="right")
    t.add_column()
    t.add_row("model", f"[bold]{model}[/bold]")
    t.add_row("endpoint", base_url)
    t.add_row("dizin", workspace)
    t.add_row("araç modu", tool_mode + ("  [red]YOLO (onay yok)[/red]" if yolo else ""))
    console.print(
        Panel(
            t,
            title="[bold cyan]qwen-cli[/bold cyan]",
            subtitle="[grey58]/help ile komutlar · Ctrl+C iptal · Ctrl+D çıkış[/grey58]",
            border_style="cyan",
            padding=(1, 2),
        )
    )


def info(msg: str) -> None:
    console.print(f"[{THEME['dim']}]{msg}[/]")


def ok(msg: str) -> None:
    console.print(f"[{THEME['ok']}]OK[/] {msg}")


def error(msg: str) -> None:
    console.print(f"[{THEME['err']}]HATA[/] {msg}")


def warn(msg: str) -> None:
    console.print(f"[yellow]![/yellow] {msg}")


def rule(label: str = "") -> None:
    console.print(Rule(label, style="grey30"))


# ------------------------------------------------------------------ akış yazıcı

class StreamRenderer:
    """Model çıktısını token token yazar; ``` blokları içinde renk değiştirir.

    Live/Markdown yerine satır tamponlu düz yazım kullanılıyor: uzun yanıtlarda
    ekranı yeniden çizmediği için Windows terminallerinde titremiyor ve kaydırma
    geçmişi bozulmuyor.
    """

    def __init__(self) -> None:
        self._buf = ""
        self._in_code = False
        self._started = False
        self._wrote_any = False
        self._in_tool = False
        # prompt modunda <tool_call> bloklarını kullanıcıya ham göstermeyelim
        self.hide_tool_calls = False

    def _print(self, line: str) -> None:
        stripped = line.lstrip()
        if stripped.startswith("```"):
            self._in_code = not self._in_code
            console.print(Text(line, style="grey42"))
            return
        style = "bright_green" if self._in_code else THEME["model"]
        console.print(Text(line, style=style))

    def _emit_line(self, line: str) -> None:
        if not self.hide_tool_calls:
            self._print(line)
            return
        while line:
            if self._in_tool:
                end = line.find("</tool_call>")
                if end == -1:
                    return
                self._in_tool = False
                line = line[end + len("</tool_call>"):]
                continue
            start = line.find("<tool_call>")
            if start == -1:
                if line.strip():
                    self._print(line)
                return
            head = line[:start]
            if head.strip():
                self._print(head)
            self._in_tool = True
            line = line[start + len("<tool_call>"):]

    def write(self, chunk: str) -> None:
        if not chunk:
            return
        if not self._started:
            console.print()
            self._started = True
        self._wrote_any = True
        self._buf += chunk
        while "\n" in self._buf:
            line, self._buf = self._buf.split("\n", 1)
            self._emit_line(line)

    def reasoning(self, chunk: str) -> None:
        """Bazı sunucular reasoning_content döndürür; soluk göster."""
        if not chunk:
            return
        console.print(Text(chunk.replace("\n", " "), style=THEME["think"]), end="")

    def finish(self) -> None:
        if self._buf:
            self._emit_line(self._buf)
            self._buf = ""
        if self._wrote_any:
            console.print()
        self._started = False
        self._wrote_any = False


# ------------------------------------------------------------------ araç görünümü

def tool_header(name: str, args: dict, index: int) -> None:
    bits = []
    for k, v in (args or {}).items():
        s = str(v).replace("\n", "\\n")
        if len(s) > 60:
            s = s[:57] + "..."
        bits.append(f"{k}={s}")
    line = Text()
    line.append(f"  [{index}] ", style=THEME["dim"])
    line.append(name, style=THEME["tool"])
    if bits:
        line.append("  " + ", ".join(bits), style=THEME["dim"])
    console.print(line)


def tool_result(summary: str, failed: bool = False) -> None:
    mark = "x" if failed else "+"
    style = THEME["err"] if failed else THEME["ok"]
    console.print(Text(f"      {mark} {summary}", style=style))


def preview_panel(kind: str, body: str, title: str) -> None:
    if kind == "diff":
        content = Syntax(body, "diff", theme="ansi_dark", word_wrap=False,
                         background_color="default")
    elif kind == "shell":
        content = Syntax(body, "bash", theme="ansi_dark", word_wrap=True,
                         background_color="default")
    else:
        lang = LANG_BY_EXT.get(title.rsplit(".", 1)[-1].lower(), "text")
        content = Syntax(body, lang, theme="ansi_dark", line_numbers=True,
                         word_wrap=False, background_color="default")
    console.print(Panel(content, title=f"[bold]{title}[/bold]",
                        border_style="yellow", padding=(0, 1)))


def approve(action: str) -> str:
    """Onay ister. Döner: 'yes' | 'no' | 'always' | 'abort'."""
    prompt = Text()
    prompt.append("  ? ", style="bold yellow")
    prompt.append(action, style="bold")
    prompt.append("\n    [e]vet  [h]ayır  [t]ümü (bu araca hep izin ver)  [i]ptal > ",
                  style=THEME["dim"])
    while True:
        try:
            console.print(prompt, end="")
            answer = input().strip().lower()
        except (EOFError, KeyboardInterrupt):
            console.print()
            return "abort"
        if answer in ("e", "evet", "y", "yes", ""):
            return "yes"
        if answer in ("h", "hayir", "hayır", "n", "no"):
            return "no"
        if answer in ("t", "tum", "tüm", "tumu", "tümü", "a", "always"):
            return "always"
        if answer in ("i", "iptal", "q", "abort"):
            return "abort"
        console.print("    [grey58]e / h / t / i yazın[/grey58]")


def usage_line(prompt_tokens: int, completion_tokens: int, steps: int,
               seconds: float) -> None:
    console.print(
        f"[{THEME['dim']}]  {prompt_tokens:,} girdi + {completion_tokens:,} çıktı token"
        f" · {steps} adım · {seconds:.1f}s[/]"
    )


def help_table() -> None:
    t = Table(box=None, padding=(0, 2))
    t.add_column("komut", style="bold cyan", no_wrap=True)
    t.add_column("açıklama", style="white")
    rows = [
        ("/help", "bu yardım"),
        ("/model [ad]", "modeli göster veya değiştir"),
        ("/models", "endpoint'teki model listesini çek"),
        ("/clear", "sohbet geçmişini sıfırla"),
        ("/history", "geçmişteki mesaj sayısı ve token tahmini"),
        ("/cd <dizin>", "çalışma dizinini değiştir"),
        ("/pwd", "çalışma dizinini göster"),
        ("/yolo", "onay istemeyi aç/kapat"),
        ("/tools", "araç listesini göster"),
        ("/undo", "ajanın son dosya değişikliğini geri al"),
        ("/save <dosya>", "son yanıtı dosyaya kaydet"),
        ("/setup", "API anahtarı / endpoint sihirbazını çalıştır"),
        ("/exit", "çık (Ctrl+D de olur)"),
    ]
    for a, b in rows:
        t.add_row(a, b)
    console.print(Panel(t, title="[bold]komutlar[/bold]", border_style="grey30",
                        padding=(1, 1)))
    console.print(
        "[grey58]  Çok satırlı giriş: satır sonuna \\ koyun veya Alt+Enter.[/grey58]\n"
    )


def tools_table(schemas: list[dict]) -> None:
    t = Table(box=None, padding=(0, 2))
    t.add_column("araç", style="bold yellow", no_wrap=True)
    t.add_column("onay", no_wrap=True)
    t.add_column("açıklama")
    from .tools import READ_ONLY

    for s in schemas:
        f = s["function"]
        need = "[green]gerekmez[/green]" if f["name"] in READ_ONLY else "[yellow]gerekir[/yellow]"
        t.add_row(f["name"], need, f["description"])
    console.print(Panel(t, title="[bold]araçlar[/bold]", border_style="grey30",
                        padding=(1, 1)))
