package storage

import (
	"database/sql"
	"errors"
	"fmt"
)

// UserPrefs is one signed-in user's stored state. Prefs is an opaque JSON blob
// owned by the web frontend (disabled feeds, weather location, toggles, …) —
// the backend just persists and returns it, keyed by the OIDC subject.
type UserPrefs struct {
	Sub       string
	Prefs     string
	Username  string
	Email     string
	UpdatedAt int64
}

// GetUserPrefs returns the stored prefs blob for an OIDC subject. It returns
// ("", nil) when the user has no record yet (first sign-in).
func GetUserPrefs(sub string) (string, error) {
	var prefs string
	err := Get().QueryRow(`SELECT prefs FROM user_preferences WHERE user_sub = ?`, sub).Scan(&prefs)
	if errors.Is(err, sql.ErrNoRows) {
		return "", nil
	}
	if err != nil {
		return "", fmt.Errorf("get user prefs: %w", err)
	}
	return prefs, nil
}

// PutUserPrefs upserts a user's prefs blob along with identity hints (username,
// email) for later features. The prefs string is stored verbatim.
func PutUserPrefs(sub, prefs, username, email string) error {
	_, err := Get().Exec(`
		INSERT INTO user_preferences (user_sub, prefs, username, email, updated_at)
		VALUES (?, ?, ?, ?, ?)
		ON CONFLICT(user_sub) DO UPDATE SET
			prefs      = excluded.prefs,
			username   = excluded.username,
			email      = excluded.email,
			updated_at = excluded.updated_at`,
		sub, prefs, username, email, nowUnix())
	if err != nil {
		return fmt.Errorf("put user prefs: %w", err)
	}
	return nil
}
