"""
Strategy generation handlers for the bot.
"""
import asyncio
import contextlib
import logging
from typing import Dict, Any

from aiogram.types import CallbackQuery
from aiogram.fsm.context import FSMContext

from src.bot.services.strategy_service import StrategyService
from src.bot.services.steps_sanitizer import StepsSanitizer
from src.bot.utils.text_utils import strategy_without_day_blocks, extract_day_html
from src.bot.utils.typing_utils import typing_loop
from src.bot.keyboards.survey import kb_review
from src.bot.keyboards.daily import kb_daily_step
from src.database.db_methods.users import register_user, create_or_update_bot_settings
from src.database.session import SessionLocal

logger = logging.getLogger(__name__)


async def generate_strategy_for_survey(
    cb: CallbackQuery, 
    state: FSMContext, 
    data: Dict[str, Any], 
    tg_id: str
) -> None:
    """
    Generate strategy and steps for completed survey.
    
    Args:
        cb: Callback query object
        state: FSM context
        data: Survey data
        tg_id: Telegram user ID
    """
    stop_typing = asyncio.Event()
    typing_task = asyncio.create_task(typing_loop(cb.message.bot, cb.message.chat.id, stop_typing))

    try:
        # Register user in database
        async with session_scope() as session:
            await register_user(
                session,
                tg_id=tg_id,
                user_name=data["name"],
                user_gender=data["gender"],
                city=data["city"],
                where_practicing=data["place"],
                have_clients=data["clients"],
                massage_technique=data["technique"],
                social_skill=data["social"],
                communication_ease=data["comm"],
                raw_json=data,
            )
            
            # Create bot settings
            await create_or_update_bot_settings(
                session,
                tg_id=tg_id,
                bot_voice_gender=data.get("bot_gender"),
            )

        # Generate strategy and steps
        strategy_service = StrategyService()
        sanitizer = StepsSanitizer()
        
        # Create bot settings dict for strategy generation
        bot_settings = {
            "bot_voice_gender": data.get("bot_gender"),
            "bot_voice_name": None,  # Will be set later via /settings
        }
        
        strategy_text, raw_steps = await strategy_service.build_strategy_and_steps(data, bot_settings)
        steps = sanitizer.sanitize_steps(raw_steps, data)

        await state.update_data(
            draft_strategy_text=strategy_text,
            draft_steps=steps,
            survey_payload=data,
            user_tg_id=tg_id,
            edit_mode=None,
        )
    finally:
        stop_typing.set()
        with contextlib.suppress(Exception):
            await typing_task

    # Show strategy for review
    clean_strategy = strategy_without_day_blocks(strategy_text)
    await cb.message.answer(
        clean_strategy or "Стратегия пустая.",
        reply_markup=kb_review()
    )


@contextlib.asynccontextmanager
async def session_scope():
    """Database session context manager."""
    session = SessionLocal()
    try:
        yield session
        await session.commit()
    except Exception:
        await session.rollback()
        raise
    finally:
        await session.close()


# kb_review is imported from src.bot.keyboards.survey
