import re
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import ContextTypes
from asgiref.sync import sync_to_async
from webapp.models import BindingRequest, Client, Invoice
from draw.models import DrawResult
from bot.state import BINDING_PENDING
from bot.models import BotConfig


@sync_to_async
def get_client_by_telegram_id(telegram_id: int):
    try:
        return Client.objects.get(telegram_id=str(telegram_id))
    except Client.DoesNotExist:
        return None

@sync_to_async
def get_invoices_for_client(client):
    return list(Invoice.objects.filter(client_club_card_number=client.club_card_number))

@sync_to_async
def get_draws_for_client(client):
    return list(
        DrawResult.objects.filter(participant__invoice__client_club_card_number=client.club_card_number)
        .select_related('lottery', 'prize', 'participant__invoice')
    )

@sync_to_async
def create_binding_request(telegram_chat_id, client_card):
    return BindingRequest.objects.create(
        telegram_chat_id=str(telegram_chat_id),
        client_card=client_card
    )


async def whoami(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message:
        return

    chat_id = update.message.chat_id
    client = await get_client_by_telegram_id(chat_id)
    if not client:
        await update.message.reply_text(
            "❌ Пользователь не найден. Возможно, Вы ещё не привязали свою клубную карту."
        )
        return

    invoices = await get_invoices_for_client(client)
    draws = await get_draws_for_client(client)

    message_text = f"👤 *Профиль клиента:*\n" \
                   f"• *Имя:* {client.name}\n" \
                   f"• *Клубная карта:* {client.club_card_number}\n\n"

    message_text += "💳 *Счета:*\n"
    if invoices:
        show_all = len(invoices) > 5
        displayed_invoices = invoices[:5] if show_all else invoices
        for inv in displayed_invoices:
            message_text += f"  • ID {inv.id} (*{inv.sum}*)\n"
    else:
        message_text += "  _Нет счетов_\n"

    message_text += "\n🎉 *Розыгрыши и выигранные призы:*\n"
    if draws:
        for draw in draws:
            lottery_name = draw.lottery.name if draw.lottery else "неизвестно"
            invoice_info = getattr(draw.participant.invoice, 'id', 'неизвестно') if draw.participant else 'неизвестно'
            prize_info = getattr(draw.prize, 'reward', 'неизвестно')
            message_text += f"  • Лотерея: *{lottery_name}*\n    Счет: _{invoice_info}_\n    Выигрыш: *{prize_info}*\n\n"
    else:
        message_text += "  _Нет результатов розыгрышей_\n"

    reply_markup = None
    if invoices and len(invoices) > 5:
        reply_markup = InlineKeyboardMarkup([
            [InlineKeyboardButton("Показать все счета", callback_data="show_all_invoices")]
        ])

    await update.message.reply_text(message_text, parse_mode="Markdown", reply_markup=reply_markup)


async def handle_client_card(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message:
        return

    telegram_chat_id = update.message.chat_id
    client = await get_client_by_telegram_id(telegram_chat_id)
    if client:
        await update.message.reply_text("✅ Вы уже привязаны!")
        return

    BINDING_PENDING.add(telegram_chat_id)
    await update.message.reply_text("Введите номер вашей клубной карты (КК):")
    await send_event_message("binding_started", update, context)

async def process_binding_input(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message or not update.message.text:
        return

    client_card = update.message.text.strip()
    telegram_chat_id = update.message.chat_id

    if not re.fullmatch(r'\d{3,}', client_card):
        await update.message.reply_text("❌ Неверный формат клиентской карты. Пожалуйста, введите минимум 3 цифры.")
        return

    await create_binding_request(telegram_chat_id, client_card)
    BINDING_PENDING.discard(telegram_chat_id)
    await update.message.reply_text("✅ Заявка отправлена. После подтверждения вы сможете участвовать в чате.")


async def show_all_invoices_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()
    chat_id = query.message.chat_id
    client = await get_client_by_telegram_id(chat_id)
    if not client:
        await query.edit_message_text("❌ Пользователь не найден. Возможно, Вы ещё не привязали свою клубную карту.")
        return

    invoices = await get_invoices_for_client(client)
    message_text = "💳 *Все счета:*\n"
    if invoices:
        for inv in invoices:
            message_text += f"  • ID {inv.ext_id} (*{inv.sum}*)\n"
    else:
        message_text += "  _Нет счетов_\n"

    await query.edit_message_text(message_text, parse_mode="Markdown")


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message:
        return
    bot_config = await sync_to_async(BotConfig.objects.filter(is_active=True).first)()
    if bot_config and bot_config.active_welcome:
        await update.message.reply_text(bot_config.active_welcome.welcome_message)
    else:
        await update.message.reply_text("Привет! Бот работает.")
