import logging
import uuid

from fastapi import APIRouter, Depends
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth.dependencies import _get_user, get_current_user_id, get_db_session
from src.models import UserConfig
from src.schemas.user import UserConfigResponse, UserConfigUpdate

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/users/me", tags=["user-config"])


async def _get_or_create_config(
    session: AsyncSession, user_id: uuid.UUID
) -> UserConfig:
    """Get or create user config record.

    Args:
        session: Database session.
        user_id: UUID of the user.

    Returns:
        The user's config, creating a new one if it doesn't exist.
    """
    result = await session.execute(
        select(UserConfig).where(UserConfig.user_id == user_id)
    )
    config = result.scalar_one_or_none()
    if config is None:
        config = UserConfig(user_id=user_id, config={})
        session.add(config)
        await session.commit()
        await session.refresh(config)
    return config


@router.get(
    "/config",
    response_model=UserConfigResponse,
    summary="Get user config",
    description="Get the current user's configuration settings.",
)
async def get_user_config(
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> UserConfigResponse:
    """Get the current user's configuration.

    Args:
        user_id: ID of the authenticated user.
        session: Database session.

    Returns:
        The user's configuration settings.
    """
    _user = await _get_user(session, user_id)
    config = await _get_or_create_config(session, user_id)
    return UserConfigResponse.model_validate(config.config)


@router.patch(
    "/config",
    response_model=UserConfigResponse,
    summary="Update user config",
    description="Update the current user's configuration settings.",
)
async def update_user_config(
    data: UserConfigUpdate,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> UserConfigResponse:
    """Update the current user's configuration.

    Args:
        data: Configuration update data with optional fields.
        user_id: ID of the authenticated user.
        session: Database session.

    Returns:
        The updated user configuration.
    """
    _user = await _get_user(session, user_id)
    config = await _get_or_create_config(session, user_id)

    # Merge updates
    update_data = data.model_dump(exclude_unset=True)
    logger.debug("Updating user config for user %s: %s", user_id, update_data)
    # SQLAlchemy JSON doesn't track dict mutations, so we replace the whole dict
    config.config = {**config.config, **update_data}

    await session.commit()
    await session.refresh(config)
    logger.debug("Updated config: %s", config.config)
    return UserConfigResponse.model_validate(config.config)
