//! Health view — secret age monitoring and rotation compliance.

use crate::worker::{HealthView, ReqId};
use eframe::egui;

pub struct HealthState {
    pub max_age_days: u32,
    pub results: Option<HealthResults>,
    pending: Option<ReqId>,
}

pub struct HealthResults {
    pub healthy: usize,
    pub aging: usize,
    pub overdue: usize,
    pub secrets: Vec<SecretHealthView>,
}

pub struct SecretHealthView {
    pub name: String,
    pub age_days: u64,
    pub status: HealthStatus,
}

pub enum HealthStatus {
    Ok,
    Aging,
    Overdue,
}

impl Default for HealthState {
    fn default() -> Self {
        Self {
            max_age_days: 90,
            results: None,
            pending: None,
        }
    }
}

impl HealthState {
    pub fn start_refresh(&mut self, id: ReqId) {
        self.pending = Some(id);
    }

    pub fn apply_loaded(&mut self, id: ReqId, report: HealthView) {
        if self.pending != Some(id) {
            return;
        }
        self.pending = None;
        let max_age = self.max_age_days as u64;
        let mut healthy = 0usize;
        let mut aging = 0usize;
        let mut overdue = 0usize;
        let secrets: Vec<SecretHealthView> = report
            .secrets
            .into_iter()
            .map(|s| {
                let status = if s.needs_rotation {
                    overdue += 1;
                    HealthStatus::Overdue
                } else if s.age_days > max_age * 3 / 4 {
                    aging += 1;
                    HealthStatus::Aging
                } else {
                    healthy += 1;
                    HealthStatus::Ok
                };
                SecretHealthView {
                    name: s.name,
                    age_days: s.age_days,
                    status,
                }
            })
            .collect();
        self.results = Some(HealthResults {
            healthy,
            aging,
            overdue,
            secrets,
        });
    }

    pub fn apply_error(&mut self, id: ReqId) {
        if self.pending == Some(id) {
            self.pending = None;
        }
    }

    fn is_loading(&self) -> bool {
        self.pending.is_some()
    }
}

pub fn render(ui: &mut egui::Ui, state: &mut HealthState) -> bool {
    let mut want_refresh = false;

    ui.add_space(8.0);
    ui.horizontal(|ui| {
        ui.heading("Secret Health");
        if state.is_loading() {
            ui.add_space(8.0);
            ui.spinner();
        }
        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
            let btn = ui.add(
                egui::Button::new("💓 Run Health Check")
                    .fill(egui::Color32::from_rgb(0xe4, 0xe4, 0xe7))
                    .min_size(egui::vec2(140.0, 30.0))
                    .corner_radius(8.0),
            );
            if btn.clicked() {
                want_refresh = true;
            }
        });
    });
    ui.add_space(4.0);
    ui.label(egui::RichText::new("Monitor secret age and rotation compliance.").weak());
    ui.add_space(12.0);

    // Max age config.
    ui.horizontal(|ui| {
        ui.label("Max secret age (days):");
        ui.add(egui::DragValue::new(&mut state.max_age_days).range(1..=365));
    });
    ui.add_space(12.0);

    match &state.results {
        None => {
            ui.add_space(30.0);
            ui.vertical_centered(|ui| {
                ui.label(egui::RichText::new("💓").size(36.0));
                ui.label("No health data yet");
                ui.label(
                    egui::RichText::new("Click \"Run Health Check\" to audit secret ages").weak(),
                );
            });
        }
        Some(results) => {
            // Summary cards.
            ui.horizontal(|ui| {
                health_stat(
                    ui,
                    &results.healthy.to_string(),
                    "Healthy",
                    egui::Color32::from_rgb(0x22, 0xc5, 0x5e),
                );
                health_stat(
                    ui,
                    &results.aging.to_string(),
                    "Aging",
                    egui::Color32::from_rgb(251, 191, 36),
                );
                health_stat(
                    ui,
                    &results.overdue.to_string(),
                    "Overdue",
                    egui::Color32::from_rgb(239, 68, 68),
                );
            });
            ui.add_space(12.0);

            egui::ScrollArea::vertical().show(ui, |ui| {
                for secret in &results.secrets {
                    let (color, icon) = match secret.status {
                        HealthStatus::Ok => (egui::Color32::from_rgb(0x22, 0xc5, 0x5e), "✅"),
                        HealthStatus::Aging => (egui::Color32::from_rgb(251, 191, 36), "⚠"),
                        HealthStatus::Overdue => (egui::Color32::from_rgb(239, 68, 68), "🔴"),
                    };
                    egui::Frame::new()
                        .fill(ui.visuals().faint_bg_color)
                        .corner_radius(6.0)
                        .inner_margin(10.0)
                        .show(ui, |ui| {
                            ui.horizontal(|ui| {
                                ui.label(icon);
                                ui.label(egui::RichText::new(&secret.name).strong());
                                ui.with_layout(
                                    egui::Layout::right_to_left(egui::Align::Center),
                                    |ui| {
                                        ui.colored_label(
                                            color,
                                            format!("{} days", secret.age_days),
                                        );
                                    },
                                );
                            });
                        });
                    ui.add_space(2.0);
                }
            });
        }
    }
    want_refresh
}

fn health_stat(ui: &mut egui::Ui, value: &str, label: &str, color: egui::Color32) {
    egui::Frame::new()
        .fill(color.linear_multiply(0.12))
        .corner_radius(8.0)
        .inner_margin(14.0)
        .show(ui, |ui| {
            ui.set_min_width(80.0);
            ui.vertical_centered(|ui| {
                ui.colored_label(color, egui::RichText::new(value).size(24.0).strong());
                ui.label(egui::RichText::new(label).size(12.0));
            });
        });
}
