//! Per-user reader preferences. Rows are lazily inserted on the first
//! upsert — a user that has never customised their settings has no row,
//! and reads fall back to the in-memory defaults in `UserPreferences::defaults_for`.

use sqlx::PgPool;
use uuid::Uuid;

use crate::domain::UserPreferences;
use crate::error::AppResult;

pub async fn find(pool: &PgPool, user_id: Uuid) -> AppResult<Option<UserPreferences>> {
    let row = sqlx::query_as::<_, UserPreferences>(
        r#"
        SELECT user_id, reader_mode, reader_page_gap, updated_at
        FROM user_preferences
        WHERE user_id = $1
        "#,
    )
    .bind(user_id)
    .fetch_optional(pool)
    .await?;
    Ok(row)
}

pub async fn upsert(
    pool: &PgPool,
    user_id: Uuid,
    reader_mode: &str,
    reader_page_gap: &str,
) -> AppResult<UserPreferences> {
    let row = sqlx::query_as::<_, UserPreferences>(
        r#"
        INSERT INTO user_preferences (user_id, reader_mode, reader_page_gap)
        VALUES ($1, $2, $3)
        ON CONFLICT (user_id) DO UPDATE
            SET reader_mode = EXCLUDED.reader_mode,
                reader_page_gap = EXCLUDED.reader_page_gap,
                updated_at = now()
        RETURNING user_id, reader_mode, reader_page_gap, updated_at
        "#,
    )
    .bind(user_id)
    .bind(reader_mode)
    .bind(reader_page_gap)
    .fetch_one(pool)
    .await?;
    Ok(row)
}
