from utils.texts import (
    UNKNOWN_MAIN_CMD_TEXT,
    EMOJI_DIGITS,
    INSTRUCT_MAIN_MENU_TEXT,
    INSTRUCT_TRUECONF_TEXT,
    INSTRUCT_TRUECONF_WITH_AD,
    INSTRUCT_EMAIL_TEXT,
)
import logging
import asyncio
import os

from trueconf import Router, Message
from trueconf.types import FSInputFile

from utils.states import get_state, set_state, clear_state

# 🔌 Импортируем централизованную функцию сбора статистики из main
from utils.stats_logger import log_menu_stats

# 🔌 Импортируем рабочую функцию создания заявки из SD модуля
from service_desk.handlers import create_ticket_in_sd, get_ad_user_sync
from config.config import DEFAULT_REQUESTER

logger = logging.getLogger(__name__)

router = Router()

# Путь к файлу инструкции Trueconf
TRUECONF_INSTRUCT_PATH = os.path.join(os.path.dirname(__file__), "Проверка_наличия_и_авторизация_на_мобильном_устройстве_Trueconf.docx")


def get_user_cn(user_id: str) -> str | None:
    """
    Получить CN пользователя из AD по его user_id (email или логин).
    user_id из TrueConf — это обычно email, например 'ds.krivochenko@tcs.sibcem.ru'
    Заменяет tcs.sibcem.ru на sibcem.ru для поиска в AD.
    Ищет по всем OU из AD_BASES.
    """
    from utils.ad_search import search_by_user_id

    try:
        # Заменяем tcs.sibcem.ru на sibcem.ru
        search_id = user_id.replace("@tcs.sibcem.ru", "@sibcem.ru")
        short_username = search_id.split("@")[0] if "@" in search_id else user_id

        logger.info(f"AD lookup: user_id={user_id}, search_id={search_id}, short={short_username}")

        entries = search_by_user_id(search_id, ["cn", "sAMAccountName", "mail", "userPrincipalName"])

        if entries:
            entry = entries[0]
            cn = str(entry.cn)
            mail = str(entry.mail) if 'mail' in entry else "N/A"
            sam = str(entry.sAMAccountName) if 'sAMAccountName' in entry else "N/A"
            upn = str(entry.userPrincipalName) if 'userPrincipalName' in entry else "N/A"
            logger.info(f"AD found: cn={cn}, mail={mail}, sam={sam}, upn={upn}")
            return cn

        logger.warning(f"AD not found for user_id={user_id}, search_id={search_id}, short={short_username}")
    except Exception as e:
        logger.error(f"Ошибка получения CN из AD для {user_id}: {e}", exc_info=True)
    return user_id  # fallback — используем user_id как CN


@router.message()
async def instruct_router_handler(msg: Message):
    user_id = msg.from_user.id
    user_name = getattr(msg.from_user, 'name', 'N/A')
    user_username = getattr(msg.from_user, 'username', 'N/A')

    logger.info(f"Instruct: user_id={user_id}, name={user_name}, username={user_username}")

    current_state = get_state(user_id)

    if not msg.text:
        return

    cmd = msg.text.strip().lower()

    for raw_num, emoji_num in EMOJI_DIGITS.items():
        if cmd == emoji_num:
            cmd = raw_num
            break

    if current_state is None:
        from utils.menu import MENU_MAP
        if MENU_MAP.get(cmd) == "INSTRUCT":
            msg.handled = True
            set_state(user_id, "INSTRUCT_MODE")
            await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
            return
        return

    if current_state == "INSTRUCT_MODE":
        msg.handled = True
        if cmd == "0":
            log_menu_stats(user_id, "Инструкции", "Выход в главное меню")
            clear_state(user_id)
            from utils.menu import MENU_TEXT
            await msg.answer(MENU_TEXT, parse_mode="html")
        elif cmd == "1":
            log_menu_stats(user_id, "Инструкции", "Trueconf")
            set_state(user_id, "INSTRUCT_TRUECONF_VIEW")
            cn = get_user_cn(user_id)
            login = user_id.split("@")[0] if "@" in user_id else user_id
            ticket_id = None
            try:
                from utils.ad_checker import check_group_membership
                result = check_group_membership(cn, "2FA")
                if not result.get("in_group", True):
                    subject = f"Запрос доступа к Trueconf"
                    description = f"Пользователь {cn} ({user_id}) запросил инструкцию по Trueconf, но не имеет группы 2FA. Требуется выдача доступа."
                    # Ищем email пользователя в AD, как в service_desk
                    ad_user = await asyncio.to_thread(get_ad_user_sync, login)
                    requester_email = ad_user.get("mail") if ad_user and ad_user.get("mail") else DEFAULT_REQUESTER
                    ticket_id = await create_ticket_in_sd(requester_email, subject, description, "Кемерово")
                    logger.info(f"SD ticket created for {cn}: #{ticket_id}")
            except Exception as e:
                logger.error(f"Ошибка создания SD заявки: {e}", exc_info=True)
                ticket_id = None
            text = INSTRUCT_TRUECONF_WITH_AD(EMOJI_DIGITS, cn, ticket_id)
            await msg.answer(text, parse_mode="html")
            if os.path.isfile(TRUECONF_INSTRUCT_PATH):
                await msg.answer_document(FSInputFile(TRUECONF_INSTRUCT_PATH))
        elif cmd == "2":
            log_menu_stats(user_id, "Инструкции", "Почта")
            set_state(user_id, "INSTRUCT_EMAIL_VIEW")
            await msg.answer(INSTRUCT_EMAIL_TEXT, parse_mode="html")
        else:
            await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")

    elif current_state in ["INSTRUCT_TRUECONF_VIEW", "INSTRUCT_EMAIL_VIEW"]:
        msg.handled = True
        if cmd == "0":
            clear_state(user_id)
            from utils.menu import MENU_TEXT
            await msg.answer(MENU_TEXT, parse_mode="html")
        elif cmd == "9":
            set_state(user_id, "INSTRUCT_MODE")
            await msg.answer(INSTRUCT_MAIN_MENU_TEXT, parse_mode="html")
        else:
            await msg.answer(UNKNOWN_MAIN_CMD_TEXT, parse_mode="html")
