import logging

from sqlalchemy import delete as sa_delete, select

from fabledassistant.models import async_session
from fabledassistant.models.setting import Setting

logger = logging.getLogger(__name__)


async def get_setting(user_id: int, key: str, default: str = "") -> str:
    async with async_session() as session:
        result = await session.execute(
            select(Setting).where(Setting.user_id == user_id, Setting.key == key)
        )
        setting = result.scalar_one_or_none()
        return setting.value if setting else default


async def set_setting(user_id: int, key: str, value: str) -> None:
    async with async_session() as session:
        result = await session.execute(
            select(Setting).where(Setting.user_id == user_id, Setting.key == key)
        )
        setting = result.scalar_one_or_none()
        if setting:
            setting.value = value
        else:
            session.add(Setting(user_id=user_id, key=key, value=value))
        await session.commit()


async def set_settings_batch(user_id: int, settings: dict[str, str]) -> None:
    """Update multiple settings in a single transaction."""
    async with async_session() as session:
        for key, value in settings.items():
            result = await session.execute(
                select(Setting).where(Setting.user_id == user_id, Setting.key == key)
            )
            setting = result.scalar_one_or_none()
            if setting:
                setting.value = value
            else:
                session.add(Setting(user_id=user_id, key=key, value=value))
        await session.commit()
    logger.info("Batch-updated %d settings for user %d", len(settings), user_id)


async def delete_setting(user_id: int, key: str) -> None:
    """Remove a setting row so get_setting() returns its hardcoded default instead."""
    async with async_session() as session:
        await session.execute(
            sa_delete(Setting).where(Setting.user_id == user_id, Setting.key == key)
        )
        await session.commit()


async def get_all_settings(user_id: int) -> dict[str, str]:
    async with async_session() as session:
        result = await session.execute(
            select(Setting).where(Setting.user_id == user_id)
        )
        return {s.key: s.value for s in result.scalars().all()}
