//! Policy view — displays binary access rules. Pure rendering;
//! the App layer owns vault interactions.

use eframe::egui;

use crate::worker::ReqId;
use envseal::ops::PolicyRuleView;

#[derive(Default)]
pub struct PolicyState {
    pub rules: Vec<PolicyRuleView>,
    pending: Option<ReqId>,
    pub error: Option<String>,
}

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

    pub fn apply_loaded(&mut self, id: ReqId, rules: Vec<PolicyRuleView>) {
        if self.pending != Some(id) {
            return;
        }
        self.pending = None;
        self.rules = rules;
        self.error = None;
    }

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

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

#[derive(Default)]
pub struct PolicyAction {
    pub revoke_binary: Option<String>,
    pub refresh: bool,
}

pub fn render(ui: &mut egui::Ui, state: &mut PolicyState) -> PolicyAction {
    let mut action = PolicyAction::default();

    ui.add_space(10.0);
    ui.horizontal(|ui| {
        ui.heading("Access Policy");
        if state.is_loading() {
            ui.add_space(8.0);
            ui.spinner();
        }
        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
            if ui.button("Refresh").clicked() {
                action.refresh = true;
            }
        });
    });
    ui.label(
        egui::RichText::new("Approved binaries with vault access. Revoke to require re-approval.")
            .size(12.0)
            .weak(),
    );
    ui.add_space(12.0);

    if let Some(err) = &state.error {
        ui.colored_label(egui::Color32::from_rgb(0xf5, 0x9e, 0x0b), err);
        return action;
    }

    if state.rules.is_empty() && !state.is_loading() {
        ui.add_space(40.0);
        ui.vertical_centered(|ui| {
            ui.label(
                egui::RichText::new("No approved binaries.")
                    .size(14.0)
                    .weak(),
            );
            ui.add_space(4.0);
            ui.label(
                egui::RichText::new(
                    "Run a CLI command that needs a secret; \
                     the GUI approval popup will register the binary here.",
                )
                .size(12.0)
                .weak(),
            );
        });
        return action;
    }

    egui::ScrollArea::vertical().show(ui, |ui| {
        for rule in &state.rules {
            egui::Frame::new()
                .fill(ui.visuals().faint_bg_color)
                .corner_radius(8.0)
                .inner_margin(12.0)
                .show(ui, |ui| {
                    ui.vertical(|ui| {
                        ui.horizontal(|ui| {
                            ui.label(
                                egui::RichText::new(&rule.binary)
                                    .strong()
                                    .size(13.0)
                                    .monospace(),
                            );
                            ui.with_layout(
                                egui::Layout::right_to_left(egui::Align::Center),
                                |ui| {
                                    if ui.button("Revoke").clicked() {
                                        action.revoke_binary = Some(rule.binary.clone());
                                    }
                                },
                            );
                        });
                        ui.label(
                            egui::RichText::new(format!(
                                "secret = {}    scope = {}",
                                rule.secret, rule.scope
                            ))
                            .size(11.0)
                            .weak(),
                        );
                    });
                });
            ui.add_space(4.0);
        }
    });

    action
}
