from __future__ import annotations

from typing import Any, Iterable

from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup


_PROVIDER_LABELS = {
    "openai": "OpenAI",
    "openrouter": "OpenRouter",
    "gemini": "Gemini",
    "claude": "Claude",
}



def chunk_inline_buttons(buttons: list[InlineKeyboardButton], row_size: int) -> list[list[InlineKeyboardButton]]:
    if row_size <= 0:
        raise ValueError("row_size must be greater than zero")
    return [buttons[index : index + row_size] for index in range(0, len(buttons), row_size)]



def _provider_label(name: str) -> str:
    cleaned = str(name or "").strip()
    return _PROVIDER_LABELS.get(cleaned.lower(), cleaned.title() or "Unknown")



def _normalise_providers(providers: Iterable[dict[str, Any]], *, current_provider: str) -> list[dict[str, Any]]:
    indexed: list[tuple[int, dict[str, Any]]] = []
    for index, item in enumerate(providers):
        name = str(item.get("name") or "").strip()
        if not name:
            continue
        payload = dict(item)
        payload["name"] = name
        indexed.append((index, payload))
    indexed.sort(key=lambda entry: (entry[1]["name"] != current_provider, entry[0]))
    return [item for _, item in indexed]



def _truncate_label(value: str, *, limit: int = 16) -> str:
    text = str(value or "").strip()
    if not text:
        return "Set model"
    if len(text) <= limit:
        return text
    return text[: limit - 1] + "…"



def _provider_button_text(item: dict[str, Any], *, current_provider: str) -> str:
    name = str(item.get("name") or "")
    label = _provider_label(name)
    if not item.get("enabled", True):
        prefix = "⛔"
    elif name == current_provider:
        prefix = "🟢"
    elif item.get("is_default"):
        prefix = "⭐"
    else:
        prefix = "⚪"
    return f"{prefix} {label}"



def _key_button_text(item: dict[str, Any]) -> str:
    if not item.get("enabled", True):
        return "🔒 Disabled"
    return "✅ Key" if item.get("has_api_key") else "🔑 Add key"



def _model_button_text(item: dict[str, Any], *, current_provider: str, current_model: str) -> str:
    if not item.get("enabled", True):
        return "🧠 Disabled"
    name = str(item.get("name") or "")
    model_name = current_model if name == current_provider else str(item.get("default_model") or "")
    return f"🧠 {_truncate_label(model_name)}"



def build_settings_action_rows() -> list[list[InlineKeyboardButton]]:
    return [
        [
            InlineKeyboardButton(text="↻ Refresh", callback_data="settings:refresh"),
            InlineKeyboardButton(text="♻ Reload", callback_data="settings:reload"),
            InlineKeyboardButton(text="❓ Help", callback_data="settings:help"),
        ]
    ]



def build_settings_keyboard(providers: list[dict[str, Any]], *, current_provider: str, current_model: str) -> InlineKeyboardMarkup:
    rows: list[list[InlineKeyboardButton]] = []
    for item in _normalise_providers(providers, current_provider=current_provider):
        name = str(item["name"])
        rows.append(
            [
                InlineKeyboardButton(
                    text=_provider_button_text(item, current_provider=current_provider),
                    callback_data=f"settings:provider:{name}",
                ),
                InlineKeyboardButton(
                    text=_key_button_text(item),
                    callback_data=f"settings:key:{name}",
                ),
                InlineKeyboardButton(
                    text=_model_button_text(item, current_provider=current_provider, current_model=current_model),
                    callback_data=f"settings:model:{name}",
                ),
            ]
        )
    rows.extend(build_settings_action_rows())
    return InlineKeyboardMarkup(inline_keyboard=rows)
