from __future__ import annotations

from io import StringIO
from typing import Any

from rich.console import Console
from rich.table import Table


def _normalize_rows(data: Any) -> list[dict]:
    if isinstance(data, list):
        rows = []
        for item in data:
            if isinstance(item, dict):
                rows.append(item)
            else:
                rows.append({"value": item})
        return rows

    if isinstance(data, dict):
        return [data]

    return [{"value": data}]


def _is_account_table(rows: list[dict]) -> bool:
    return bool(rows) and any("account_uid" in row for row in rows)


def _ordered_columns(rows: list[dict]) -> list[str]:
    columns = {key for row in rows for key in row.keys()}
    if _is_account_table(rows):
        preferred = [
            "is_current",
            "account_uid",
            "nickname",
            "platform",
            "is_logged_in",
            "status",
            "last_active",
        ]
        ordered = [col for col in preferred if col in columns]
        ordered.extend(sorted(columns - set(ordered)))
        return ordered

    preferred = [
        "check",
        "ok",
        "id",
        "note_id",
        "user_id",
        "title",
        "name",
        "nickname",
        "author",
        "note_type",
        "red_id",
        "publish_time",
        "update_time",
        "fans",
        "follows",
        "interaction",
        "note_count",
        "notes_count",
        "profession",
        "verified",
        "followed",
        "is_self",
        "guest",
        "liked_count",
        "collected_count",
        "comment_count",
        "shared_count",
        "stage",
        "success",
        "message",
        "summary",
        "note_url",
        "user_url",
        "xsec_token",
    ]
    ordered = [col for col in preferred if col in columns]
    ordered.extend(sorted(columns - set(ordered)))
    return ordered


def _stringify_simple(value: Any) -> str:
    if isinstance(value, bool):
        return "true" if value else "false"
    return str(value if value is not None else "")


def _summarize_list_item(value: Any, *, depth: int) -> str:
    if isinstance(value, dict):
        for key in ("name", "text", "title", "display_title", "nickname", "nick_name", "red_id", "id", "type"):
            candidate = value.get(key)
            if isinstance(candidate, str) and candidate.strip():
                return candidate.strip()
        return _summarize_nested_value(value, depth=depth)
    return _summarize_nested_value(value, depth=depth)


def _summarize_nested_value(value: Any, *, depth: int = 0) -> str:
    if isinstance(value, (str, int, float, bool)) or value is None:
        return _stringify_simple(value)

    if isinstance(value, dict):
        if depth >= 1:
            return f"{len(value)} keys"
        parts = []
        for key, item in value.items():
            text = _summarize_nested_value(item, depth=depth + 1)
            if not text:
                continue
            parts.append(f"{key}={text}")
            if len(parts) >= 3:
                break
        if not parts:
            return f"{len(value)} keys"
        remaining = max(len(value) - len(parts), 0)
        if remaining:
            parts.append(f"+{remaining} more")
        return ", ".join(parts)

    if isinstance(value, list):
        if not value:
            return ""
        parts = []
        for item in value[:3]:
            text = _summarize_list_item(item, depth=depth + 1)
            if text:
                parts.append(text)
        if not parts:
            return f"{len(value)} items"
        remaining = max(len(value) - len(parts), 0)
        if remaining:
            parts.append(f"+{remaining} more")
        return ", ".join(parts)

    return str(value)


def _stringify_cell(column: str, value: Any) -> str:
    if column == "is_current":
        return "current" if bool(value) else ""
    return _summarize_nested_value(value)


def format_table(data: Any) -> str:
    rows = _normalize_rows(data)
    columns = _ordered_columns(rows)
    table = Table(show_header=True, header_style="bold cyan")
    for col in columns:
        table.add_column(col, overflow="fold")

    for row in rows:
        table.add_row(*[_stringify_cell(col, row.get(col, "")) for col in columns])

    buffer = StringIO()
    console = Console(file=buffer, force_terminal=False, color_system=None)
    console.print(table)
    return buffer.getvalue().rstrip()
