from typing import Any

from aiogram.types import InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder

from bot.keyboards.common import back_button
from bot.services.texts import money, texts


async def categories_keyboard(categories: list[dict[str, Any]]) -> InlineKeyboardMarkup:
    builder = InlineKeyboardBuilder()
    builder.button(text=await texts.text("btn_recent_orders"), callback_data="menu:orders")
    for category in categories:
        icon = category.get("icon") or ""
        builder.button(
            text=f"{icon} {category['title']}".strip(), callback_data=f"cat:{category['id']}"
        )
    builder.button(text=await texts.text("btn_back"), callback_data="menu:main")
    builder.adjust(1, 2)
    return builder.as_markup()


async def products_keyboard(products: list[dict[str, Any]]) -> InlineKeyboardMarkup:
    builder = InlineKeyboardBuilder()
    for product in products:
        price = product.get("effective_price") or product.get("price")
        label = product["title"]
        if float(price or 0) > 0:
            label = f"{label} — {money(price)}"
        builder.button(text=label, callback_data=f"prod:{product['id']}")
    builder.button(text=await texts.text("btn_back"), callback_data="menu:buy")
    builder.adjust(1)
    return builder.as_markup()


async def step_keyboard(step: dict[str, Any], can_go_back: bool = True) -> InlineKeyboardMarkup:
    builder = InlineKeyboardBuilder()
    config = step.get("config", {})
    if config.get("self"):
        builder.button(text=await texts.text("btn_for_myself"), callback_data="step:self")
    if config.get("balance_calc"):
        builder.button(text=await texts.text("btn_balance_calc"), callback_data="step:balance")
    if step.get("optional"):
        builder.button(text=await texts.text("btn_skip"), callback_data="step:skip")
    if can_go_back:
        builder.button(text=await texts.text("btn_back"), callback_data="step:back")
    else:
        builder.button(text=await texts.text("btn_back"), callback_data="menu:buy")
    builder.adjust(1)
    return builder.as_markup()


async def confirm_keyboard(
    order_id: str, options: list[dict[str, Any]], input_data: dict[str, Any]
) -> InlineKeyboardMarkup:
    """Shared invoice screen: confirm / coupon / cancel / back + flow options."""
    builder = InlineKeyboardBuilder()
    builder.button(text=await texts.text("btn_confirm"), callback_data=f"ord:confirm:{order_id}")
    builder.button(text=await texts.text("btn_coupon"), callback_data=f"ord:coupon:{order_id}")

    for option in options:
        if option["type"] == "toggle":
            enabled = bool(input_data.get(option["key"], option.get("default", False)))
            label_key = "btn_hide_disable" if enabled else "btn_hide_enable"
            builder.button(
                text=await texts.text(label_key),
                callback_data=f"opt:{option['key']}:{int(not enabled)}:{order_id}",
            )
        elif option["type"] == "choice_text":
            builder.button(
                text=await texts.text("btn_set_comment"),
                callback_data=f"opt:{option['key']}:menu:{order_id}",
            )

    builder.button(
        text=await texts.text("btn_cancel_purchase"), callback_data=f"ord:cancel:{order_id}"
    )
    builder.button(text=await texts.text("btn_back"), callback_data="menu:buy")
    builder.adjust(2)
    return builder.as_markup()


async def comment_type_keyboard(
    order_id: str, choices: list[dict[str, Any]], premium_price: Any
) -> InlineKeyboardMarkup:
    builder = InlineKeyboardBuilder()
    for choice in choices:
        if choice["value"] == "premium":
            label = await texts.text("btn_comment_premium", price=money(premium_price))
        else:
            label = await texts.text("btn_comment_normal")
        builder.button(text=label, callback_data=f"cmt:{choice['value']}:{order_id}")
    builder.button(text=await texts.text("btn_back"), callback_data=f"ord:invoice:{order_id}")
    builder.adjust(1)
    return builder.as_markup()


async def orders_keyboard(orders: list[dict[str, Any]]) -> InlineKeyboardMarkup:
    builder = InlineKeyboardBuilder()
    for order in orders[:10]:
        builder.button(
            text=f"{order['order_number']} — {order['product_snapshot'].get('title', '')}",
            callback_data=f"ord:view:{order['id']}",
        )
    builder.row(await back_button("menu:main"))
    builder.adjust(1)
    return builder.as_markup()
