"""
Survey flow handlers for the bot.
"""
import logging
from typing import Optional

from aiogram import Router, F
from aiogram.filters import CommandStart
from aiogram.types import Message, CallbackQuery
from aiogram.fsm.context import FSMContext

from src.bot.states.survey import SurveyFSM
from src.bot.keyboards.survey import (
    kb_gender, kb_bot_gender, kb_place, kb_clients, kb_technique, kb_social, kb_comm
)
from src.bot.keyboards.main import kb_confirm_wipe
from src.database.enums import Gender, PracticePlace, ClientsExperience, MassageTechnique, SocialSkill, CommunicationEase
from src.database.db_methods.users import is_user_registered

logger = logging.getLogger(__name__)
router = Router(name="survey_handlers")


@router.message(CommandStart())
async def start_survey(message: Message, state: FSMContext):
    """
    Start survey flow or show wipe confirmation if user already exists.
    """
    tg_id = str(message.from_user.id)

    # Check if user is already registered
    from src.database.session import SessionLocal
    import contextlib
    
    @contextlib.asynccontextmanager
    async def session_scope():
        session = SessionLocal()
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()

    async with session_scope() as session:
        registered = await is_user_registered(session, tg_id)

    if registered:
        await message.answer(
            "Ты уже проходил анкету. Хочешь удалить старые данные и начать заново?",
            reply_markup=kb_confirm_wipe()
        )
        return

    await state.clear()
    await state.set_state(SurveyFSM.name)
    await message.answer("Как тебя зовут ? Впиши полное имя.")


@router.message(SurveyFSM.name)
async def handle_name(message: Message, state: FSMContext):
    """
    Handle name input and move to gender selection.
    """
    name = (message.text or "").strip()
    if len(name) < 2:
        await message.answer("Похоже, что ты ошибся, впиши полное имя")
        return
    
    await state.update_data(name=name)
    await state.set_state(SurveyFSM.gender)
    await message.answer("Твой пол:", reply_markup=kb_gender())


@router.callback_query(SurveyFSM.gender, F.data.startswith("gender:"))
async def handle_gender(cb: CallbackQuery, state: FSMContext):
    """
    Handle gender selection and move to city input.
    """
    try:
        value = cb.data.split(":", 1)[1]
        gender = Gender(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(gender=gender.value)
    await state.set_state(SurveyFSM.city)
    await cb.message.edit_text("В каком городе ты живёшь? Введи в формате Город/область")
    await cb.answer()


@router.message(SurveyFSM.city)
async def handle_city(message: Message, state: FSMContext):
    """
    Handle city input and move to practice place selection.
    """
    city = (message.text or "").strip()
    if not city:
        await message.answer("Введи корректный город.")
        return
    
    await state.update_data(city=city)
    await state.set_state(SurveyFSM.place)
    await message.answer("Где вы сейчас практикуете массаж?", reply_markup=kb_place())


@router.callback_query(SurveyFSM.place, F.data.startswith("place:"))
async def handle_place(cb: CallbackQuery, state: FSMContext):
    """
    Handle practice place selection and move to clients experience.
    """
    try:
        value = cb.data.split(":", 1)[1]
        place = PracticePlace(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(place=place.value)
    await state.set_state(SurveyFSM.clients)
    await cb.message.edit_text("У тебя уже были клиенты?")
    await cb.message.edit_reply_markup(reply_markup=kb_clients())
    await cb.answer()


@router.callback_query(SurveyFSM.clients, F.data.startswith("clients:"))
async def handle_clients(cb: CallbackQuery, state: FSMContext):
    """
    Handle clients experience and move to technique selection.
    """
    try:
        value = cb.data.split(":", 1)[1]
        clients = ClientsExperience(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(clients=clients.value)
    await state.set_state(SurveyFSM.technique)
    await cb.message.edit_text("Какую технику массажа ты практикуешь чаще всего?")
    await cb.message.edit_reply_markup(reply_markup=kb_technique())
    await cb.answer()


@router.callback_query(SurveyFSM.technique, F.data.startswith("tech:"))
async def handle_technique(cb: CallbackQuery, state: FSMContext):
    """
    Handle technique selection and move to social skills.
    """
    try:
        value = cb.data.split(":", 1)[1]
        tech = MassageTechnique(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(technique=tech.value)
    await state.set_state(SurveyFSM.social)
    await cb.message.edit_text("Насколько уверенно ты пользуешься соцсетями?")
    await cb.message.edit_reply_markup(reply_markup=kb_social())
    await cb.answer()


@router.callback_query(SurveyFSM.social, F.data.startswith("social:"))
async def handle_social(cb: CallbackQuery, state: FSMContext):
    """
    Handle social skills and move to communication ease.
    """
    try:
        value = cb.data.split(":", 1)[1]
        social = SocialSkill(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(social=social.value)
    await state.set_state(SurveyFSM.comm)
    await cb.message.edit_text("Насколько легко ты взаимодействуешь с незнакомыми людьми?")
    await cb.message.edit_reply_markup(reply_markup=kb_comm())
    await cb.answer()


@router.callback_query(SurveyFSM.comm, F.data.startswith("comm:"))
async def handle_communication(cb: CallbackQuery, state: FSMContext):
    """
    Handle communication ease and move to bot gender selection.
    """
    try:
        value = cb.data.split(":", 1)[1]
        comm = CommunicationEase(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(comm=comm.value)
    await state.set_state(SurveyFSM.bot_gender)
    await cb.message.edit_text("Какой пол должен быть у бота? Это повлияет на то, как бот будет обращаться к тебе.")
    await cb.message.edit_reply_markup(reply_markup=kb_bot_gender())
    await cb.answer()


@router.callback_query(SurveyFSM.bot_gender, F.data.startswith("bot_gender:"))
async def handle_bot_gender(cb: CallbackQuery, state: FSMContext):
    """
    Handle bot gender selection and complete survey.
    """
    try:
        value = cb.data.split(":", 1)[1]
        bot_gender = Gender(value)
    except Exception:
        await cb.answer("Неверное значение", show_alert=True)
        return

    await state.update_data(bot_gender=bot_gender.value)
    data = await state.get_data()
    tg_id = str(cb.from_user.id)

    await cb.answer()
    await cb.message.edit_text(f"{data['name']}, анкета сохранена. Формирую персональную стратегию...")

    # Import strategy generation logic
    from src.bot.handlers.strategy_generation import generate_strategy_for_survey
    
    try:
        await generate_strategy_for_survey(cb, state, data, tg_id)
    except Exception as e:
        logger.exception("Error generating strategy: %s", e)
        await cb.message.answer("Произошла ошибка при генерации стратегии. Попробуйте ещё раз.")
