from sqlalchemy.orm.attributes import flag_modified

from backend import schemas
from backend.database.base import db
from backend.database.models import Preference


def _get_db_preference(user_id: str) -> Preference:
    if not user_id:
        return None
    return db.session.query(Preference).filter(Preference.user_id == user_id).first()


def get_preferences(user_id: str) -> schemas.PreferenceRead:
    with db.session.begin():
        db_pref = _get_db_preference(user_id=user_id)
        if db_pref:
            return schemas.PreferenceRead.model_validate(db_pref).prefs
        return None


def create_preference(preference: schemas.PreferenceCreate) -> schemas.PreferenceRead:
    with db.session.begin():
        new_preference = Preference(**preference.model_dump())
        db.session.add(new_preference)
        db.session.flush()
        return schemas.PreferenceRead.model_validate(new_preference)


def update_preferences(user_id: str, preference_update: schemas.PreferenceUpdate) -> schemas.PreferenceRead:
    with db.session.begin():
        db_preference = _get_db_preference(user_id)
        if db_preference:
            # Update existing - merge new prefs with existing ones
            current_prefs = dict(db_preference.prefs or {})
        else:
            # Create new
            current_prefs = {}

        update_data = preference_update.model_dump(exclude_unset=True)
        current_prefs.update(update_data.get("prefs", {}))

        # merge() handles both insert (new) and update (existing) cases
        db_preference = db.session.merge(Preference(user_id=user_id, prefs=current_prefs))
        db.session.flush()
        return schemas.PreferenceRead.model_validate(db_preference)
