"""
ui.py — ANSI colour helpers, display primitives, and input prompts.
Shared by all ES24N workflows.
"""

import ipaddress
import sys


# ── ANSI colour helpers ───────────────────────────────────────────────────────
class C:
    RED   = "\033[0;31m"
    GRN   = "\033[0;32m"
    YEL   = "\033[1;33m"
    CYN   = "\033[0;36m"
    WHT   = "\033[1;37m"
    DIM   = "\033[2m"
    BOLD  = "\033[1m"
    RESET = "\033[0m"
    CLEAR = "\033[2J\033[H"


def _c(colour: str, text: str) -> str:
    return f"{colour}{text}{C.RESET}"


def info(msg: str):  print(f"  {_c(C.CYN,  'i')}  {msg}")
def ok(msg: str):    print(f"  {_c(C.GRN,  'OK')} {msg}")
def warn(msg: str):  print(f"  {_c(C.YEL,  '!')}  {msg}")
def error(msg: str): print(f"  {_c(C.RED,  'X')}  {msg}")


def banner():
    print(C.CLEAR, end="")
    w = 60
    print(_c(C.CYN, "  +" + "-" * w + "+"))
    print(_c(C.CYN, "  |") + _c(C.WHT + C.BOLD,
          "      TrueNAS ES24N IOM Configuration Tool          ") + _c(C.CYN, "  |"))
    print(_c(C.CYN, "  |") + _c(C.DIM,
          "       Serial Config & Firmware Updates              ") + _c(C.CYN, "  |"))
    print(_c(C.CYN, "  +" + "-" * w + "+"))
    print()


def rule(title: str = ""):
    width = 60
    if title:
        pad   = max(0, width - len(title) - 2)
        left  = pad // 2
        right = pad - left
        line  = f"{'-' * left} {title} {'-' * right}"
    else:
        line = "-" * width
    print(f"\n  {_c(C.YEL, line)}\n")


def draw_table(headers: list, rows: list, col_widths: list):
    sep = "  +-" + "-+-".join("-" * w for w in col_widths) + "-+"

    def fmt_row(cells):
        return "  | " + " | ".join(
            str(c).ljust(w) for c, w in zip(cells, col_widths)
        ) + " |"

    print(_c(C.DIM, sep))
    print(_c(C.BOLD, fmt_row(headers)))
    print(_c(C.DIM, sep))
    for row in rows:
        print(fmt_row(row))
    print(_c(C.DIM, sep))


def draw_box(lines: list, colour: str = C.CYN):
    width = max(len(l) for l in lines) + 4
    print(f"  {_c(colour, '+' + '-' * width + '+')}")
    for line in lines:
        pad = width - len(line) - 2
        print(f"  {_c(colour, '|')}  {line}{' ' * pad}  {_c(colour, '|')}")
    print(f"  {_c(colour, '+' + '-' * width + '+')}")


# ── Input helpers ─────────────────────────────────────────────────────────────
def prompt(label: str, default: str = "") -> str:
    display = f"  {_c(C.CYN, label)}"
    if default:
        display += f" {_c(C.DIM, f'[{default}]')}"
    display += ": "

    sys.stdout.write(display)
    sys.stdout.flush()
    val = sys.stdin.readline().strip()
    return val if val else default


def prompt_ip(label: str) -> str:
    while True:
        val = prompt(label)
        try:
            ipaddress.IPv4Address(val)
            return val
        except ValueError:
            warn(f"'{val}' is not a valid IPv4 address — please try again.")


def prompt_yn(label: str, default: bool = True) -> bool:
    hint = "Y/n" if default else "y/N"
    val  = prompt(f"{label} [{hint}]").strip().lower()
    if not val:
        return default
    return val in ("y", "yes")


def prompt_password() -> str:
    while True:
        val = prompt(
            "Admin password (BMC/chassis serial, e.g. MXE3000043CHA007)",
        )
        if val:
            return val
        warn("Password cannot be empty.")
