#![forbid(unsafe_code)]

//! Gitlore TUI — terminal interface for exploring GitLab data locally.
//!
//! Built on FrankenTUI (Elm architecture): Model, update, view.
//! The `lore` CLI spawns `lore-tui` via PATH lookup at runtime.

use anyhow::Result;

// Phase 0 modules.
pub mod clock; // Clock trait: SystemClock + FakeClock (bd-2lg6)
pub mod message; // Msg, Screen, EntityKey, AppError, InputMode (bd-c9gk)

pub mod safety; // Terminal safety: sanitize + URL policy + redact (bd-3ir1)

pub mod db; // DbManager: read pool + dedicated writer (bd-2kop)
pub mod theme; // Flexoki theme: build_theme, state_color, label_style (bd-5ofk)

pub mod app; // LoreApp Model trait impl (Phase 0 proof: bd-2emv, full: bd-6pmy)

// Phase 1 modules.
pub mod commands; // CommandRegistry: keybindings, help, palette (bd-38lb)
pub mod crash_context; // CrashContext ring buffer + panic hook (bd-2fr7)
pub mod layout; // Responsive layout: breakpoints, columns, preview pane (bd-1pzj)
pub mod navigation; // NavigationStack: back/forward/jump list (bd-1qpp)
pub mod state; // AppState, LoadState, ScreenIntent, per-screen states (bd-1v9m)
pub mod task_supervisor; // TaskSupervisor: dedup + cancel + generation IDs (bd-3le2)
pub mod view; // View layer: render_screen + common widgets (bd-26f2)

// Phase 2 modules.
pub mod action; // Data-fetching actions for TUI screens (bd-35g5+)
pub mod filter_dsl; // Filter DSL tokenizer for list screen filter bars (bd-18qs)

// Phase 4 modules.
pub mod entity_cache; // Bounded LRU entity cache for detail view reopens (bd-2og9)
pub mod render_cache; // Bounded render cache for expensive per-frame computations (bd-2og9)
pub mod scope; // Global scope context: SQL helpers + project listing (bd-1ser)

// Phase 5 modules.
pub mod instance_lock; // Single-instance advisory lock for TUI (bd-3h00)
pub mod session; // Session state persistence: save/load/quarantine (bd-3h00)
pub mod text_width; // Unicode-aware text width measurement + truncation (bd-3h00)

/// Options controlling how the TUI launches.
#[derive(Debug, Clone)]
pub struct LaunchOptions {
    /// Path to lore config file.
    pub config_path: Option<String>,
    /// Run a background sync before displaying data.
    pub sync_on_start: bool,
    /// Clear cached TUI state and start fresh.
    pub fresh: bool,
    /// Render backend: "crossterm" or "native".
    pub render_mode: String,
    /// Use ASCII-only box drawing characters.
    pub ascii: bool,
    /// Disable alternate screen (render inline).
    pub no_alt_screen: bool,
}

/// Launch the TUI in browse mode (no sync).
///
/// Loads config from `options.config_path` (or default location),
/// opens the database read-only, and enters the FrankenTUI event loop.
///
/// ## Preflight sequence
///
/// 1. **Schema preflight** — validate the database schema version before
///    creating the app. If incompatible, print an actionable error and exit
///    with a non-zero code.
/// 2. **Data readiness** — check whether the database has any entity data.
///    If empty, start on the Bootstrap screen; otherwise start on Dashboard.
pub fn launch_tui(options: LaunchOptions) -> Result<()> {
    let _options = options;
    // Phase 1 will wire this to LoreApp + App::fullscreen().run()
    eprintln!("lore-tui: browse mode not yet implemented (Phase 1)");
    Ok(())
}

/// Run the schema preflight check.
///
/// Returns `Ok(())` if the schema is compatible, or an error with an
/// actionable message if it's not. The caller should exit non-zero on error.
pub fn schema_preflight(conn: &rusqlite::Connection) -> Result<()> {
    use state::bootstrap::SchemaCheck;

    match action::check_schema_version(conn, action::MINIMUM_SCHEMA_VERSION) {
        SchemaCheck::Compatible { .. } => Ok(()),
        SchemaCheck::NoDB => {
            anyhow::bail!(
                "No lore database found.\n\
                 Run 'lore init' to create a config, then 'lore sync' to fetch data."
            );
        }
        SchemaCheck::Incompatible { found, minimum } => {
            anyhow::bail!(
                "Database schema version {found} is too old (minimum: {minimum}).\n\
                 Run 'lore migrate' to upgrade, or 'lore sync' to rebuild."
            );
        }
    }
}

/// Launch the TUI with an initial sync pass.
///
/// Runs `lore sync` in the background while displaying a progress screen,
/// then transitions to browse mode once sync completes.
pub fn launch_sync_tui(options: LaunchOptions) -> Result<()> {
    let _options = options;
    // Phase 2 will implement the sync progress screen
    eprintln!("lore-tui: sync mode not yet implemented (Phase 2)");
    Ok(())
}
