"""
Обработчики авторизации:
- bot_started — первый запуск / перезапуск
- /start команда
- Шаринг контакта
"""
import re

from maxapi.dispatcher import Router
from maxapi.filters import F
from maxapi.filters.contact import ContactFilter
from maxapi.types.attachments.attachment import ContactAttachmentPayload
from maxapi.types.attachments.contact import Contact as ContactAttachment
from maxapi.types.updates.bot_started import BotStarted
from maxapi.types.updates.message_created import MessageCreated
from maxapi.context import BaseContext
from maxapi.filters.command import Command

from bot.keyboards import contact_request_kb, main_menu_kb
from bot.logging_setup import get_logger
from bot.send_helper import bot_send
from bot.states import AuthStates

logger = get_logger("bot.handlers.start")
from database.queries.bot_users import (
    authorize_bot_user,
    block_bot_user,
    get_bot_user_by_max_id,
    upsert_bot_user,
)
from database.queries.org_users import find_by_phone
from database.queries.message_log import log_message

router = Router(router_id="start")


def normalize_phone(raw: str) -> str:
    """Убираем всё кроме цифр, заменяем ведущую 8 → 7."""
    digits = re.sub(r"\D", "", raw)
    if digits.startswith("8") and len(digits) == 11:
        digits = "7" + digits[1:]
    return digits


@router.bot_started()
async def on_bot_started(event: BotStarted, context: BaseContext) -> None:
    user = event.user
    bot_user = await upsert_bot_user(
        max_user_id=user.user_id,
        max_chat_id=event.chat_id,
        username=getattr(user, "username", None),
        first_name=getattr(user, "name", None),
    )

    if bot_user["is_blocked"]:
        logger.info("🚫 bot_started blocked | user_id=%s", user.user_id)
        await bot_send(
            event.bot,
            chat_id=event.chat_id,
            user_id=user.user_id,
            text=(
                "⛔ Ваш номер не найден в системе. Доступ заблокирован.\n"
                "Обратитесь к администратору для подключения."
            ),
        )
        return

    if bot_user["is_authorized"]:
        logger.info("✅ bot_started returning user | user_id=%s", user.user_id)
        await context.set_state(None)
        await bot_send(
            event.bot,
            chat_id=event.chat_id,
            user_id=user.user_id,
            text="👋 С возвращением! Выберите действие:",
            attachments=[main_menu_kb()],
        )
        return

    # Новый пользователь — запрашиваем контакт
    logger.info("👋 bot_started new user | user_id=%s", user.user_id)
    await context.set_state(AuthStates.waiting_contact)
    await bot_send(
        event.bot,
        chat_id=event.chat_id,
        user_id=user.user_id,
        text=(
            "👋 Добро пожаловать в систему технической поддержки!\n\n"
            "Для входа нажмите кнопку ниже и поделитесь своим номером телефона."
        ),
        attachments=[contact_request_kb()],
    )


@router.message_created(Command("start"))
async def on_start_command(event: MessageCreated, context: BaseContext) -> None:
    chat_id, user_id = event.get_ids()
    if user_id is None or chat_id is None:
        return

    bot_user = await get_bot_user_by_max_id(user_id)
    if bot_user is None:
        # Первый раз — как bot_started
        await upsert_bot_user(
            max_user_id=user_id,
            max_chat_id=chat_id,
            username=None,
            first_name=None,
        )
        await context.set_state(AuthStates.waiting_contact)
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text=(
                "👋 Добро пожаловать!\n\n"
                "Поделитесь номером телефона для доступа к системе."
            ),
            attachments=[contact_request_kb()],
        )
        return

    if bot_user["is_blocked"]:
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text="⛔ Доступ заблокирован. Обратитесь к администратору.",
        )
        return

    if not bot_user["is_authorized"]:
        await context.set_state(AuthStates.waiting_contact)
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text="Поделитесь номером телефона для доступа:",
            attachments=[contact_request_kb()],
        )
        return

    await context.set_state(None)
    await bot_send(
        event.bot,
        chat_id=chat_id,
        user_id=user_id,
        text="Главное меню:",
        attachments=[main_menu_kb()],
    )


@router.message_created(ContactFilter(), states=AuthStates.waiting_contact)
async def on_contact_shared(
    event: MessageCreated,
    contact: ContactAttachment,
    context: BaseContext,
) -> None:
    chat_id, user_id = event.get_ids()
    if user_id is None or chat_id is None:
        return

    # Извлекаем телефон из VCF
    payload = contact.payload
    if not isinstance(payload, ContactAttachmentPayload):
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text="Не удалось прочитать контакт. Попробуйте ещё раз.",
            attachments=[contact_request_kb()],
        )
        return

    vcf = payload.vcf
    raw_phone = vcf.phone
    if not raw_phone:
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text="В контакте не найден номер телефона. Попробуйте ещё раз.",
            attachments=[contact_request_kb()],
        )
        return

    phone = normalize_phone(raw_phone)
    display_name = vcf.full_name

    # Логируем входящий контакт
    await log_message(
        direction="in",
        max_user_id=user_id,
        max_chat_id=chat_id,
        message_id=None,
        text=f"[Контакт: {raw_phone}]",
    )

    # Ищем в белом списке
    org_user = await find_by_phone(phone)
    if org_user is None:
        logger.warning("🚫 phone not found, blocking | user_id=%s phone=%s", user_id, phone)
        await block_bot_user(max_user_id=user_id, phone=phone)
        await context.set_state(None)
        await bot_send(
            event.bot,
            chat_id=chat_id,
            user_id=user_id,
            text=(
                "⛔ Ваш номер не найден в системе.\n"
                "Доступ заблокирован. Обратитесь к администратору для подключения."
            ),
        )
        return

    # Авторизуем
    logger.info("✅ authorized | user_id=%s phone=%s org_id=%s", user_id, phone, org_user["org_id"])
    await authorize_bot_user(
        max_user_id=user_id,
        phone=phone,
        org_id=org_user["org_id"],
        first_name=display_name,
    )
    await context.set_state(None)

    await bot_send(
        event.bot,
        chat_id=chat_id,
        user_id=user_id,
        text="✅ Вы успешно авторизованы! Выберите действие:",
        attachments=[main_menu_kb()],
    )
