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


def kb(rows: list[list[tuple[str, str]]]) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text=t, callback_data=d) for t, d in row] for row in rows])


def login_kb() -> InlineKeyboardMarkup:
    return kb([[('🔐 ورود با رمز کشور', 'login')]])


def main_kb(is_admin: bool = False) -> InlineKeyboardMarkup:
    rows = [
        [('⚔️ لشکرکشی', 'menu_campaign'), ('🎯 حمله / محاصره', 'menu_attack')],
        [('🕊 توییت و فایل', 'menu_tweet'), ('↩️ خروج از بات', 'logout')],
    ]
    if is_admin:
        rows.append([('🛠 پنل ادمین', 'admin')])
    return kb(rows)


def campaign_kb() -> InlineKeyboardMarkup:
    return kb([[('پیاده', 'campaign:infantry'), ('سواره', 'campaign:cavalry'), ('دریایی', 'campaign:naval_campaign')], [('🔙 بازگشت', 'home')]])


def attack_kb() -> InlineKeyboardMarkup:
    return kb([
        [('حمله زمینی', 'attack:ground_attack'), ('حمله توپخانه‌ای', 'attack:artillery_attack')],
        [('حمله دریایی', 'attack:naval_attack')],
        [('محاصره زمینی', 'attack:ground_siege'), ('محاصره دریایی', 'attack:naval_siege')],
        [('🔙 بازگشت', 'home')],
    ])


def admin_kb() -> InlineKeyboardMarkup:
    return kb([
        [('🔑 رمز کشورها', 'admin_codes'), ('🖼 تنظیم عکس‌ها', 'admin_images')],
        [('📋 مقصد گزارش کامل', 'admin_report_chat'), ('🕊 مقصد خروجی توییت', 'admin_output_chat')],
        [('📢 کانال خبر عملیات', 'admin_news_chat')],
        [('👥 لیست ادمین‌ها', 'admin_list')],
        [('📋 فهرست کشورها', 'admin_countries'), ('🏠 منوی اصلی', 'home')],
    ])


def continent_kb(prefix: str) -> InlineKeyboardMarkup:
    return kb([[('🌍 ' + c, f'{prefix}:continent:{i}')] for i, c in enumerate(['Europe & Africa', 'Asia', 'America'])] + [[('🔙 بازگشت', 'admin')]])


def country_kb(
    prefix: str,
    countries: list[str],
    back_data: str,
    callback_context: str | None = None,
) -> InlineKeyboardMarkup:
    """Build a country keyboard with an optional immutable context.

    Image-admin callbacks include the continent index in ``callback_context``
    so a stale menu cannot resolve an index against a different continent.
    Existing callers without a context keep the old callback shape.
    """
    rows: list[list[tuple[str, str]]] = []

    def callback(index: int) -> str:
        if callback_context:
            return f'{prefix}:{callback_context}:{index}'
        return f'{prefix}:country:{index}'

    for i in range(0, len(countries), 2):
        rows.append([(countries[i], callback(i))])
        if i + 1 < len(countries):
            rows[-1].append((countries[i + 1], callback(i + 1)))
    rows.append([('🔙 بازگشت', back_data)])
    return kb(rows)


def image_section_kb(
    continent_index: int | None = None,
    country_index: int | None = None,
) -> InlineKeyboardMarkup:
    sections = [('پیاده', 'infantry'), ('سواره', 'cavalry'), ('دریایی', 'naval_campaign'), ('حمله زمینی', 'ground_attack'), ('توپخانه', 'artillery_attack'), ('حمله دریایی', 'naval_attack'), ('محاصره زمینی', 'ground_siege'), ('محاصره دریایی', 'naval_siege'), ('بک', 'back'), ('کمین', 'ambush'), ('توییت', 'tweet')]
    if continent_index is not None and country_index is not None:
        prefix = f'admin_img_section:{continent_index}:{country_index}'
    else:
        # Kept for compatibility with callers outside this project.  The bot's
        # country-image flow always supplies both indexes and rejects this
        # legacy callback shape as stale.
        prefix = 'admin_img_section'
    rows = [[(label, f'{prefix}:{key}')] for label, key in sections]
    rows.append([('🔙 بازگشت', 'admin_images')])
    return kb(rows)


def global_image_section_kb() -> InlineKeyboardMarkup:
    sections = [('حمله زمینی', 'ground_attack'), ('توپخانه', 'artillery_attack'),
                ('حمله دریایی', 'naval_attack'), ('محاصره زمینی', 'ground_siege'),
                ('محاصره دریایی', 'naval_siege'), ('بک', 'back'), ('کمین', 'ambush'),
                ('توییت', 'tweet')]
    rows = [[(label, f'admin_global_section:{key}')] for label, key in sections]
    rows.append([('🔙 بازگشت', 'admin_images')])
    return kb(rows)


def campaign_copy_kb(campaign_id: int) -> InlineKeyboardMarkup:
    # The owner receives the back action in the private operation card.  The
    # ambush action belongs under the public news post so every player can use
    # it against that exact campaign.
    return kb([[('↩️ بک لشکرکشی', f'back:{campaign_id}')]])


def campaign_news_kb(campaign_id: int) -> InlineKeyboardMarkup:
    """Action shown below a campaign's public news message."""
    return kb([[('⚠️ کمین', f'ambush:{campaign_id}')]])


def confirmation_kb(operation: str) -> InlineKeyboardMarkup:
    """Final confirmation controls bound to one pending FSM operation."""
    return kb([[
        ('✅ تأیید نهایی', f'op_confirm:{operation}'),
        ('❌ لغو عملیات', f'op_cancel:{operation}'),
    ]])
