// Tauri commands for onboarding flow + opt-in activation log.
//
// These are thin adapters over the storage helpers — no business logic lives
// here. Every sqlx::Error is mapped to a String so Tauri can serialise it
// to the frontend as a rejected Promise.

use std::time::{SystemTime, UNIX_EPOCH};

use lumotia_storage::{
    clear_lumotia_events as db_clear_lumotia_events,
    has_completed_onboarding as db_has_completed_onboarding,
    insert_lumotia_event as db_insert_lumotia_event,
    insert_onboarding_event as db_insert_onboarding_event,
    list_lumotia_events as db_list_lumotia_events,
    list_onboarding_events as db_list_onboarding_events, LumotiaEventRow, OnboardingEventRow,
};

use crate::AppState;

/// Record a single onboarding step.
///
/// `event` — short snake_case identifier, e.g. `"started"`, `"completed"`, `"skipped"`.
/// `version` — app version string, e.g. `"0.1.0"`.
/// `skipped` — `true` if the user bypassed this step.
/// `notes` — optional freeform annotation.
#[tauri::command]
pub async fn record_onboarding_event(
    state: tauri::State<'_, AppState>,
    event: String,
    version: String,
    skipped: bool,
    notes: Option<String>,
) -> Result<(), String> {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|d| d.as_secs() as i64)
        .unwrap_or(0);
    db_insert_onboarding_event(&state.db, &event, &version, skipped, notes.as_deref(), now)
        .await
        .map_err(|e| e.to_string())
}

/// List all recorded onboarding events, oldest first.
#[tauri::command]
pub async fn list_onboarding_events(
    state: tauri::State<'_, AppState>,
) -> Result<Vec<OnboardingEventRow>, String> {
    db_list_onboarding_events(&state.db)
        .await
        .map_err(|e| e.to_string())
}

/// Returns `true` if the user has ever recorded a `completed` or `skipped`
/// onboarding event — i.e. first-run onboarding should not be shown again.
#[tauri::command]
pub async fn has_completed_onboarding(state: tauri::State<'_, AppState>) -> Result<bool, String> {
    db_has_completed_onboarding(&state.db)
        .await
        .map_err(|e| e.to_string())
}

/// Append a single entry to the opt-in local activation log.
///
/// `kind` — event kind, e.g. `"app_launched"`, `"recording_started"`.
/// `payload` — optional JSON blob with event-specific context.
#[tauri::command]
pub async fn record_lumotia_event(
    state: tauri::State<'_, AppState>,
    kind: String,
    payload: Option<String>,
) -> Result<(), String> {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|d| d.as_secs() as i64)
        .unwrap_or(0);
    db_insert_lumotia_event(&state.db, &kind, payload.as_deref(), now)
        .await
        .map_err(|e| e.to_string())
}

/// List all activation log events, oldest first.
#[tauri::command]
pub async fn list_lumotia_events(
    state: tauri::State<'_, AppState>,
) -> Result<Vec<LumotiaEventRow>, String> {
    db_list_lumotia_events(&state.db)
        .await
        .map_err(|e| e.to_string())
}

/// Delete all rows from the activation log.
#[tauri::command]
pub async fn clear_lumotia_events(state: tauri::State<'_, AppState>) -> Result<(), String> {
    db_clear_lumotia_events(&state.db)
        .await
        .map_err(|e| e.to_string())
}
