import os

from rich.align import Align
from rich.console import Console
from rich.panel import Panel
from rich.text import Text

from .board import Board
from .game import Game
from .lang import color_name, t
from .pieces import Color, Position

COL_LETTERS = "abcdefghi"

# Styles
B = "yellow"       # outer border
G = "dim"           # inner grid / labels
RC = "red1"         # red pieces
BC = "green3"       # black pieces
SEL = "bold yellow on dark_goldenrod"
LAST = "on grey27"
CAP = "on dark_orange3"
DOT = "yellow"


class GameUI:
    def __init__(self, console: Console | None = None):
        self.console = console or Console()

    def clear(self):
        os.system("cls" if os.name == "nt" else "clear")

    # ══════════════════════════════════════════════════════════════════
    #  Board rendering  (double-border outer, single-line inner grid)
    # ══════════════════════════════════════════════════════════════════

    def render_board(
        self,
        board: Board,
        perspective: Color = Color.RED,
        selected: Position | None = None,
        valid_moves: list[Position] | None = None,
        last_move: tuple[Position, Position] | None = None,
    ) -> str:
        vm = valid_moves or []
        last_set = set(last_move) if last_move else set()

        is_red = perspective == Color.RED
        rows = list(range(10)) if is_red else list(range(9, -1, -1))
        cols = list(range(9)) if is_red else list(range(8, -1, -1))
        labels = [COL_LETTERS[c] for c in cols]
        L: list[str] = []

        col_hdr = "    ".join(labels)
        L.append(f"   [{G}]  {col_hdr}[/]")
        L.append(f"   [{B}]╔════╤════╤════╤════╤════╤════╤════╤════╤════╗[/]")

        for idx, row in enumerate(rows):
            cells = [self._cell(board, c, row, selected, vm, last_set) for c in cols]
            inner = f"[{G}]│[/]".join(f" {c} " for c in cells)
            L.append(f"[{G}]{row:>2} [{B}]║[/]{inner}[{B}]║[/]")

            if idx < 9:
                if idx == 4:
                    L.append(f"   [{B}]╠════╧════╧════╧════╧════╧════╧════╧════╧════╣[/]")
                    riv = self._river()
                    L.append(f"   [{B}]║[/]{riv}[{B}]║[/]")
                    L.append(f"   [{B}]╠════╤════╤════╤════╤════╤════╤════╤════╤════╣[/]")
                else:
                    L.append(
                        f"   [{B}]╟[/][{G}]────┼────┼────┼────┼────┼────┼────┼────┼────[/][{B}]╢[/]"
                    )

        L.append(f"   [{B}]╚════╧════╧════╧════╧════╧════╧════╧════╧════╝[/]")
        return "\n".join(L)

    @staticmethod
    def _river() -> str:
        # 44 visual columns between the two ║
        return (
            "          [bold yellow]楚  河[/]"
            "    [dim]════[/]    "
            "[bold yellow]漢  界[/]"
            "          "
        )

    @staticmethod
    def _cell(
        board: Board,
        col: int,
        row: int,
        selected: Position | None,
        vm: list[Position],
        last_set: set[Position],
    ) -> str:
        pos = Position(col, row)
        piece = board.get_piece(pos)
        if piece:
            base = RC if piece.color == Color.RED else BC
            if pos == selected:
                return f"[{SEL}]{piece.symbol}[/]"
            if pos in last_set:
                return f"[bold {base} {LAST}]{piece.symbol}[/]"
            if pos in vm:
                return f"[bold {base} {CAP}]{piece.symbol}[/]"
            return f"[bold {base}]{piece.symbol}[/]"
        if pos in vm:
            return f"[{DOT}]··[/]"
        return "  "

    # ══════════════════════════════════════════════════════════════════
    #  Game screen
    # ══════════════════════════════════════════════════════════════════

    def render_game_screen(
        self,
        game: Game,
        perspective: Color = Color.RED,
        selected: Position | None = None,
        valid_moves: list[Position] | None = None,
        last_move: tuple[Position, Position] | None = None,
        message: str = "",
        is_network: bool = False,
        my_color: Color | None = None,
    ):
        self.clear()
        con = self.console
        con.print()

        title = Text()
        title.append(f"  {t('title')} ", style="bold yellow")
        title.append("─ ", style="dim")
        title.append(t("subtitle"), style="italic dim")
        con.print(title)
        con.print()

        tc = RC if game.current_turn == Color.RED else BC
        tn = color_name(game.current_turn.value)
        line = f"  {t('turn')}: [bold {tc}]{tn}[/]"
        if is_network and my_color:
            tag = t("you_tag") if game.current_turn == my_color else t("opp_tag")
            style = "bold cyan" if game.current_turn == my_color else "dim"
            line += f"  [{style}]{tag}[/]"
        line += f"    {t('move_num')}: [bold]{game.move_count + 1}[/]"
        con.print(line)

        if game.red_captures:
            syms = " ".join(p.symbol for p in game.red_captures)
            con.print(f"  [{RC}]{t('red_cap')}:[/] {syms}")
        if game.black_captures:
            syms = " ".join(p.symbol for p in game.black_captures)
            con.print(f"  [{BC}]{t('black_cap')}:[/] {syms}")

        con.print()
        con.print(self.render_board(game.board, perspective, selected, valid_moves, last_move))
        con.print()

        if message:
            con.print(f"  [bold]{message}[/]")
            con.print()

    # ══════════════════════════════════════════════════════════════════
    #  Menus  (use Panel for perfect alignment)
    # ══════════════════════════════════════════════════════════════════

    def render_main_menu(self):
        self.clear()
        body = (
            f"\n  [bold cyan]1.[/]  {t('menu_lan')}"
            f"\n  [bold cyan]2.[/]  {t('menu_local')}"
            f"\n  [bold cyan]3.[/]  {t('menu_help')}"
            f"\n  [bold cyan]4.[/]  {t('menu_lang')}"
            f"\n  [bold cyan]5.[/]  {t('menu_quit')}\n"
        )
        panel = Panel(
            body,
            title=f"[bold yellow]{t('title')}[/] [bold red1]棋[/]",
            subtitle=f"[italic dim]{t('subtitle')}[/]",
            border_style="yellow",
            width=42,
            padding=(0, 1),
        )
        self.console.print()
        self.console.print(Align.center(panel))
        self.console.print()

    def render_network_menu(self):
        self.clear()
        body = (
            f"\n  [bold cyan]1.[/]  {t('net_create')}"
            f"\n  [bold cyan]2.[/]  {t('net_join')}"
            f"\n  [bold cyan]3.[/]  {t('net_back')}\n"
        )
        panel = Panel(
            body,
            title=f"[bold]{t('net_title')}[/]",
            border_style="cyan",
            width=42,
            padding=(0, 1),
        )
        self.console.print()
        self.console.print(Align.center(panel))
        self.console.print()

    def render_lang_menu(self):
        self.clear()
        body = "\n  [bold cyan]1.[/]  Tiếng Việt\n  [bold cyan]2.[/]  English\n"
        panel = Panel(
            body,
            title="[bold]NGÔN NGỮ / LANGUAGE[/]",
            border_style="magenta",
            width=42,
            padding=(0, 1),
        )
        self.console.print()
        self.console.print(Align.center(panel))
        self.console.print()

    # ── Help ───────────────────────────────────────────────────────────

    def render_help(self):
        self.clear()
        panel = Panel(
            t("help_text"),
            title=f"[bold yellow]{t('help_title')}[/]",
            border_style="yellow",
            width=64,
            padding=(1, 2),
        )
        self.console.print()
        self.console.print(Align.center(panel))
        self.console.print()
        self.console.input(f"  [dim]{t('back_enter')}[/]")

    # ── Game over ──────────────────────────────────────────────────────

    def render_game_over(self, game: Game):
        self.console.print()
        if game.draw:
            self.console.print(
                Align.center(
                    Panel(
                        f"[bold yellow]{t('draw_label')}[/]",
                        border_style="yellow",
                        padding=(1, 4),
                    )
                )
            )
        elif game.winner:
            wc = RC if game.winner == Color.RED else BC
            wn = color_name(game.winner.value)
            self.console.print(
                Align.center(
                    Panel(
                        f"[bold {wc}]{wn} {t('win_label')}[/]",
                        border_style=wc,
                        padding=(1, 4),
                    )
                )
            )
        self.console.print()

    # ── Room info ──────────────────────────────────────────────────────

    def render_room_info(self, room_id: str, ip: str, port: int):
        self.clear()
        addr = f"{ip}:{port}"
        body = (
            f"\n  {t('room_id')}:   [bold yellow]{room_id}[/]"
            f"\n  {t('room_addr')}:  [dim]{addr}[/]"
            f"\n"
            f"\n  [italic dim]{t('room_share')}[/]"
            f"\n  [italic]{t('room_waiting')}[/]\n"
        )
        panel = Panel(
            body,
            title=f"[bold green]{t('room_created')}[/]",
            border_style="cyan",
            width=46,
            padding=(0, 1),
        )
        self.console.print()
        self.console.print(Align.center(panel))
        self.console.print()

    # ── Connection ─────────────────────────────────────────────────────

    def render_connected(self, color: Color):
        cn = color_name(color.value)
        c = RC if color == Color.RED else BC
        self.console.print(
            f"\n  [bold green]{t('connected')}[/] {t('you_are', color=f'[{c}]{cn}[/]')}"
        )

    # ── Generic input ──────────────────────────────────────────────────

    def get_input(self, prompt: str = "  > ") -> str:
        try:
            return self.console.input(prompt).strip()
        except (EOFError, KeyboardInterrupt):
            return "q"
