use std::fs;
use std::path::PathBuf;
use tauri::Manager;

/// Subdirectory under the user's Documents folder where pre-migration backups
/// are written by default. Keeping the location predictable makes it easy for
/// users to find their backup files even if the app is uninstalled.
const BACKUP_SUBDIR: &str = "Simpl-Resultat/backups";

fn resolve_backup_dir(app: &tauri::AppHandle) -> Result<PathBuf, String> {
    let documents = app
        .path()
        .document_dir()
        .map_err(|e| format!("Cannot resolve Documents directory: {}", e))?;
    Ok(documents.join(BACKUP_SUBDIR))
}

/// Resolve `~/Documents/Simpl-Resultat/backups/` and create it if missing.
/// Returns the absolute path as a string. Used by the pre-migration backup
/// flow to place SREF files in a predictable, user-visible location.
#[tauri::command]
pub fn ensure_backup_dir(app: tauri::AppHandle) -> Result<String, String> {
    let dir = resolve_backup_dir(&app)?;

    if !dir.exists() {
        fs::create_dir_all(&dir).map_err(|e| {
            // Surface permission issues explicitly — the TS layer maps this to
            // a user-facing i18n key.
            if e.kind() == std::io::ErrorKind::PermissionDenied {
                format!("permission_denied: {}", dir.to_string_lossy())
            } else {
                format!("create_dir_failed: {}: {}", dir.to_string_lossy(), e)
            }
        })?;
    }

    Ok(dir.to_string_lossy().to_string())
}

/// Return the size of a file on disk in bytes. Used to report the size of a
/// freshly-written backup to the UI. Returns a clear error if the file does
/// not exist or cannot be read.
#[tauri::command]
pub fn get_file_size(file_path: String) -> Result<u64, String> {
    let metadata =
        fs::metadata(&file_path).map_err(|e| format!("Cannot stat file {}: {}", file_path, e))?;
    Ok(metadata.len())
}

/// Return true when the given path points to an existing regular file. Used
/// by the post-migration restore flow to detect that the recorded backup
/// path is still reachable before opening the confirmation modal — when the
/// file was moved or deleted, the UI falls back to a manual file picker.
/// Never throws on a missing file (just returns `false`); only returns an
/// error for unexpected I/O conditions other than "not found".
#[tauri::command]
pub fn file_exists(file_path: String) -> Result<bool, String> {
    match fs::metadata(&file_path) {
        Ok(meta) => Ok(meta.is_file()),
        Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
        Err(e) => Err(format!("Cannot stat file {}: {}", file_path, e)),
    }
}
