import asyncio
import logging
import sys
import os

# Добавляем текущую директорию в путь для импортов
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
from aiogram.fsm.context import FSMContext

from config import BOT_TOKEN
from db import (
    create_db, add_user, get_languages,
    get_user_language, set_user_language,
    get_language_text, get_language_buttons,
    handle_referal, get_user_profile
)
from handlers.catalog import router as catalog_router  # button1 logic
from handlers.product_handlers import router as product_handlers_router  # product tags, districts, delivery
from handlers.payment_handlers import router as payment_handlers_router  # payment logic
from handlers.info import router as info_router  # button2 logic
from handlers.cryptobot import router as cryptobot_router  # button13 logic
from handlers.bank_card import router as bank_card_router  # button14 logic
from handlers.ref_sistema import router as ref_sistema_router  # button7 logic
from handlers.popolnit import router as popolnit_router  # button8 logic
from handlers.delivery import router as delivery_router  # button4 logic
from handlers.operator import router as operator_router  # button6 logic
from handlers.my_order import router as my_order_router  # button3 logic
from handlers.jobs import router as jobs_router  # button5 logic

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()

LANG_CB_PREFIX = "set_lang:"
MENU_CB_PREFIX = "menu:"        # menu:button1 ... menu:button9
BACK_KEY = f"{MENU_CB_PREFIX}button9"  # «назад»


def build_language_keyboard(langs: list[str]) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(inline_keyboard=[])
    if not langs:
        langs = ["Русский", "O'zbek", "English"]
    for name in langs:
        kb.inline_keyboard.append([
            types.InlineKeyboardButton(text=name, callback_data=f"{LANG_CB_PREFIX}{name}")
        ])
    return kb


def build_main_menu(lang: str) -> types.InlineKeyboardMarkup:
    texts = get_language_buttons(lang)  # {'button1': '...', ...}
    rows_spec = [
        ("button1", "button2"),
        ("button3", "button22"),  # Добавлена кнопка button22 (Мой профиль)
        ("button4", "button5"),
        ("button6", "button7"),
        ("button8",),
    ]
    inline_rows: list[list[types.InlineKeyboardButton]] = []
    for row in rows_spec:
        row_btns = []
        for key in row:
            label = texts.get(key)
            if label:
                row_btns.append(
                    types.InlineKeyboardButton(text=label, callback_data=f"{MENU_CB_PREFIX}{key}")
                )
        if row_btns:
            inline_rows.append(row_btns)
    return types.InlineKeyboardMarkup(inline_keyboard=inline_rows)


def build_back_button(lang: str) -> types.InlineKeyboardMarkup:
    texts = get_language_buttons(lang)
    back_label = texts.get("button9", "Назад")
    keyboard = [
        [types.InlineKeyboardButton(text=back_label, callback_data=BACK_KEY)]
    ]
    return types.InlineKeyboardMarkup(inline_keyboard=keyboard)


async def send_main_menu(user_id: int, chat_id: int) -> None:
    """
    Присылает главное меню: text1 + кнопки.
    """
    # Получаем текущий язык пользователя
    lang = get_user_language(user_id)
    
    # Если язык не установлен, устанавливаем русский по умолчанию
    if not lang:
        lang = "🇷🇺 Русский"
        set_user_language(user_id, lang)
    
    greet = get_language_text(lang, "text1") or "Добро пожаловать!"
    menu_kb = build_main_menu(lang)
    await bot.send_message(chat_id, greet, reply_markup=menu_kb)


@dp.message(Command("start"))
async def start_handler(message: Message):
    user = message.from_user
    user_id = user.id

    try:
        create_db()
        
        # Обработка реферальной ссылки
        referal_id = None
        if len(message.text.split()) > 1:
            referal_param = message.text.split()[1]
            if referal_param.isdigit():
                referal_id = int(referal_param)
                print(f"Referal detected: {referal_id} from user: {user_id}")
        
        # Добавляем пользователя и обрабатываем реферала
        add_user(user_id, user.first_name or "", user.last_name or "", user.username)
        
        # Устанавливаем русский язык по умолчанию ТОЛЬКО если у пользователя еще нет языка
        current_lang = get_user_language(user_id)
        if not current_lang:
            set_user_language(user_id, "🇷🇺 Русский")
            print(f"Set default language for new user {user_id}")
        
        # Если есть реферал, обрабатываем его
        if referal_id and referal_id != user_id:
            referal_processed = handle_referal(user_id, referal_id)
            if referal_processed:
                # Отправляем уведомление рефералу
                referal_lang = get_user_language(referal_id)
                text21 = get_language_text(referal_lang, "text21") or "По вашей ссылке зарегистрировался новый пользователь!"
                try:
                    await bot.send_message(referal_id, text21)
                    print(f"Sent referal notification to {referal_id}")
                except Exception as e:
                    print(f"Could not send referal notification: {e}")
        
    except Exception as e:
        logger.error(f"DB init/add_user error: {e}")

    await send_main_menu(user_id, message.chat.id)


# Обработчик кнопки "Мой профиль" (button22)
@dp.callback_query(F.data == f"{MENU_CB_PREFIX}button22")
async def my_profile_handler(cb: CallbackQuery):
    user_id = cb.from_user.id
    lang = get_user_language(user_id)
    
    # Получаем данные профиля пользователя
    profile_data = get_user_profile(user_id)
    
    if profile_data:
        # Формируем текст профиля
        profile_text = get_language_text(lang, "text28") or """🧑🏼‍💻 Ваш профиль:
➖➖➖➖➖➖
🌐Логин: {username} {first_name}
🌀ID: {user_id}
💰Баланс: {balance}

♻️Личная Статистика: 
├Заказы: {orders}
└Рефералы: {referals}"""
        
        # Заменяем плейсхолдеры на реальные данные
        formatted_text = profile_text.format(
            username=profile_data['username'] or '',
            first_name=profile_data['first_name'] or '',
            user_id=profile_data['user_id'],
            balance=profile_data['balance'],
            orders=profile_data['orders'],
            referals=profile_data['referals']
        )
        
        # Создаем клавиатуру с кнопкой "Назад"
        back_kb = build_back_button(lang)
        
        # Удаляем предыдущее сообщение и отправляем профиль
        try:
            await cb.message.delete()
        except Exception:
            pass
        
        await bot.send_message(cb.message.chat.id, formatted_text, reply_markup=back_kb)
    else:
        # Если данные профиля не найдены
        error_text = get_language_text(lang, "text28") or "Профиль не найден"
        back_kb = build_back_button(lang)
        
        try:
            await cb.message.delete()
        except Exception:
            pass
        
        await bot.send_message(cb.message.chat.id, error_text, reply_markup=back_kb)
    
    await cb.answer()


# Возврат «назад» в главное меню (button9) — очищаем состояние и показываем главное меню
@dp.callback_query(F.data == BACK_KEY)
async def go_back_to_main(cb: CallbackQuery, state: FSMContext):
    try:
        await cb.message.delete()  # удаляем экран каталога (или другой раздел)
    except Exception:
        pass
    await state.clear()
    await send_main_menu(cb.from_user.id, cb.message.chat.id)
    await cb.answer()


# Фолбэк: ЛОВИТ ВСЕ menu:* КРОМЕ button1, button2, button3, button4, button5, button6, button7, button8, button22 и button9 (назад)
@dp.callback_query(
    F.data.startswith(MENU_CB_PREFIX)
    & (F.data != f"{MENU_CB_PREFIX}button1")
    & (F.data != f"{MENU_CB_PREFIX}button2")  # Исключаем button2 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button3")  # Исключаем button3 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button4")  # Исключаем button4 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button5")  # Исключаем button5 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button6")  # Исключаем button6 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button7")  # Исключаем button7 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button8")  # Исключаем button8 из фолбэка
    & (F.data != f"{MENU_CB_PREFIX}button22")  # Исключаем button22 из фолбэка
    & (F.data != BACK_KEY)
)
async def menu_fallback(cb: CallbackQuery):
    key = cb.data[len(MENU_CB_PREFIX):]
    logging.info(f"Fallback for key={key} from user={cb.from_user.id}")

    # удаляем старое сообщение и присылаем новое
    try:
        await cb.message.delete()
    except Exception:
        pass
    await bot.send_message(cb.message.chat.id, "Скоро будет доступно.")
    await cb.answer()


async def main():
    create_db()
    dp.include_router(catalog_router)  # button1
    dp.include_router(product_handlers_router)  # product tags, districts, delivery
    dp.include_router(payment_handlers_router)  # payment logic
    dp.include_router(info_router)  # button2
    dp.include_router(cryptobot_router)  # button13
    dp.include_router(bank_card_router)  # button14
    dp.include_router(ref_sistema_router)  # button7
    dp.include_router(popolnit_router)  # button8
    dp.include_router(delivery_router)  # button4
    dp.include_router(operator_router)  # button6
    dp.include_router(my_order_router)  # button3
    dp.include_router(jobs_router)  # button5
    logging.info("Bot started")
    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())