#![allow(dead_code)]

//! Doctor screen state — health check results.
//!
//! Displays a list of environment health checks with pass/warn/fail
//! indicators. Checks are synchronous (config, DB, projects, FTS) —
//! network checks (GitLab auth, Ollama) are not run from the TUI.

// ---------------------------------------------------------------------------
// HealthStatus
// ---------------------------------------------------------------------------

/// Status of a single health check.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HealthStatus {
    Pass,
    Warn,
    Fail,
}

impl HealthStatus {
    /// Human-readable label for display.
    #[must_use]
    pub fn label(self) -> &'static str {
        match self {
            Self::Pass => "PASS",
            Self::Warn => "WARN",
            Self::Fail => "FAIL",
        }
    }
}

// ---------------------------------------------------------------------------
// HealthCheck
// ---------------------------------------------------------------------------

/// A single health check result for display.
#[derive(Debug, Clone)]
pub struct HealthCheck {
    /// Check category name (e.g., "Config", "Database").
    pub name: String,
    /// Pass/warn/fail status.
    pub status: HealthStatus,
    /// Human-readable detail (e.g., path, version, count).
    pub detail: String,
}

// ---------------------------------------------------------------------------
// DoctorState
// ---------------------------------------------------------------------------

/// State for the Doctor screen.
#[derive(Debug, Default)]
pub struct DoctorState {
    /// Health check results (empty until loaded).
    pub checks: Vec<HealthCheck>,
    /// Whether checks have been loaded at least once.
    pub loaded: bool,
}

impl DoctorState {
    /// Apply loaded health check results.
    pub fn apply_checks(&mut self, checks: Vec<HealthCheck>) {
        self.checks = checks;
        self.loaded = true;
    }

    /// Overall status — worst status across all checks.
    #[must_use]
    pub fn overall_status(&self) -> HealthStatus {
        if self.checks.iter().any(|c| c.status == HealthStatus::Fail) {
            HealthStatus::Fail
        } else if self.checks.iter().any(|c| c.status == HealthStatus::Warn) {
            HealthStatus::Warn
        } else {
            HealthStatus::Pass
        }
    }

    /// Count of checks by status.
    #[must_use]
    pub fn count_by_status(&self, status: HealthStatus) -> usize {
        self.checks.iter().filter(|c| c.status == status).count()
    }
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

#[cfg(test)]
mod tests {
    use super::*;

    fn sample_checks() -> Vec<HealthCheck> {
        vec![
            HealthCheck {
                name: "Config".into(),
                status: HealthStatus::Pass,
                detail: "/home/user/.config/lore/config.json".into(),
            },
            HealthCheck {
                name: "Database".into(),
                status: HealthStatus::Pass,
                detail: "schema v12".into(),
            },
            HealthCheck {
                name: "Projects".into(),
                status: HealthStatus::Warn,
                detail: "0 projects configured".into(),
            },
            HealthCheck {
                name: "FTS Index".into(),
                status: HealthStatus::Fail,
                detail: "No documents indexed".into(),
            },
        ]
    }

    #[test]
    fn test_default_state() {
        let state = DoctorState::default();
        assert!(state.checks.is_empty());
        assert!(!state.loaded);
    }

    #[test]
    fn test_apply_checks() {
        let mut state = DoctorState::default();
        state.apply_checks(sample_checks());
        assert!(state.loaded);
        assert_eq!(state.checks.len(), 4);
    }

    #[test]
    fn test_overall_status_fail_wins() {
        let mut state = DoctorState::default();
        state.apply_checks(sample_checks());
        assert_eq!(state.overall_status(), HealthStatus::Fail);
    }

    #[test]
    fn test_overall_status_all_pass() {
        let mut state = DoctorState::default();
        state.apply_checks(vec![
            HealthCheck {
                name: "Config".into(),
                status: HealthStatus::Pass,
                detail: "ok".into(),
            },
            HealthCheck {
                name: "Database".into(),
                status: HealthStatus::Pass,
                detail: "ok".into(),
            },
        ]);
        assert_eq!(state.overall_status(), HealthStatus::Pass);
    }

    #[test]
    fn test_overall_status_warn_without_fail() {
        let mut state = DoctorState::default();
        state.apply_checks(vec![
            HealthCheck {
                name: "Config".into(),
                status: HealthStatus::Pass,
                detail: "ok".into(),
            },
            HealthCheck {
                name: "Ollama".into(),
                status: HealthStatus::Warn,
                detail: "not running".into(),
            },
        ]);
        assert_eq!(state.overall_status(), HealthStatus::Warn);
    }

    #[test]
    fn test_overall_status_empty_is_pass() {
        let state = DoctorState::default();
        assert_eq!(state.overall_status(), HealthStatus::Pass);
    }

    #[test]
    fn test_count_by_status() {
        let mut state = DoctorState::default();
        state.apply_checks(sample_checks());
        assert_eq!(state.count_by_status(HealthStatus::Pass), 2);
        assert_eq!(state.count_by_status(HealthStatus::Warn), 1);
        assert_eq!(state.count_by_status(HealthStatus::Fail), 1);
    }

    #[test]
    fn test_health_status_labels() {
        assert_eq!(HealthStatus::Pass.label(), "PASS");
        assert_eq!(HealthStatus::Warn.label(), "WARN");
        assert_eq!(HealthStatus::Fail.label(), "FAIL");
    }
}
