//! Export view — generate a `.envseal` mapping file from the current
//! vault.
//!
//! Shells out to the `envseal export` CLI subcommand. Output is shown
//! inline; the user can copy it and save it themselves, or pass an
//! output path for the CLI to write to.

use std::path::PathBuf;

use eframe::egui;

fn resolve_envseal_cli() -> PathBuf {
    if let Ok(exe) = std::env::current_exe() {
        if let Some(dir) = exe.parent() {
            let mut candidate = dir.join("envseal");
            #[cfg(windows)]
            {
                candidate.set_extension("exe");
            }
            if candidate.is_file() {
                return candidate;
            }
        }
    }
    PathBuf::from("envseal")
}

#[derive(Default)]
pub struct ExportState {
    pub output_path: String,
    pub result_text: Option<String>,
    pub success: Option<bool>,
}

pub fn render(ui: &mut egui::Ui, state: &mut ExportState) {
    ui.add_space(8.0);
    ui.horizontal(|ui| {
        ui.heading("Export");
        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
            let btn = ui.add(
                egui::Button::new("Export")
                    .fill(egui::Color32::from_rgb(0xe4, 0xe4, 0xe7))
                    .min_size(egui::vec2(100.0, 30.0))
                    .corner_radius(8.0),
            );
            if btn.clicked() {
                let mut cmd = std::process::Command::new(resolve_envseal_cli());
                cmd.arg("export");
                match cmd.output() {
                    Ok(output) => {
                        let stdout = String::from_utf8_lossy(&output.stdout).to_string();
                        let stderr = String::from_utf8_lossy(&output.stderr).to_string();

                        // If a target path is provided, write stdout to it.
                        let target = state.output_path.trim();
                        let write_err = if !target.is_empty() && output.status.success() {
                            std::fs::write(target, stdout.as_bytes())
                                .err()
                                .map(|e| format!("Could not write to {target}: {e}"))
                        } else {
                            None
                        };

                        state.success = Some(output.status.success() && write_err.is_none());

                        let mut combined = String::new();
                        if !stderr.is_empty() {
                            combined.push_str(&stderr);
                            combined.push('\n');
                        }
                        if let Some(e) = write_err {
                            combined.push_str(&e);
                            combined.push('\n');
                        } else if !target.is_empty() && output.status.success() {
                            combined
                                .push_str(&format!("Wrote {} bytes to {target}\n", stdout.len()));
                        } else {
                            combined.push_str(&stdout);
                        }
                        state.result_text = Some(combined);
                    }
                    Err(e) => {
                        state.success = Some(false);
                        state.result_text = Some(format!("Failed to run export: {e}"));
                    }
                }
            }
        });
    });
    ui.add_space(4.0);
    ui.label(
        egui::RichText::new(
            "Generate a .envseal mapping file listing every secret name in the vault.",
        )
        .weak(),
    );
    ui.add_space(12.0);

    egui::Frame::new()
        .fill(ui.visuals().faint_bg_color)
        .corner_radius(8.0)
        .inner_margin(12.0)
        .show(ui, |ui| {
            ui.label(egui::RichText::new("Output File (optional)").strong());
            ui.add(
                egui::TextEdit::singleline(&mut state.output_path)
                    .hint_text("Leave empty to show inline, or enter a path like .envseal")
                    .desired_width(f32::INFINITY),
            );
        });

    ui.add_space(12.0);

    match (&state.result_text, state.success) {
        (None, _) => {
            ui.add_space(30.0);
            ui.vertical_centered(|ui| {
                ui.label(egui::RichText::new("⇩").size(36.0));
                ui.label("No exports yet");
                ui.label(
                    egui::RichText::new("Click Export to generate a .envseal mapping.").weak(),
                );
            });
        }
        (Some(text), Some(true)) => {
            egui::Frame::new()
                .fill(egui::Color32::from_rgba_premultiplied(6, 78, 59, 40))
                .corner_radius(8.0)
                .inner_margin(12.0)
                .show(ui, |ui| {
                    ui.label(
                        egui::RichText::new("Export complete")
                            .color(egui::Color32::from_rgb(0x22, 0xc5, 0x5e))
                            .size(15.0),
                    );
                });
            ui.add_space(8.0);
            egui::ScrollArea::vertical().show(ui, |ui| {
                ui.label(egui::RichText::new(text).size(12.0).monospace());
            });
        }
        (Some(text), _) => {
            egui::Frame::new()
                .fill(egui::Color32::from_rgba_premultiplied(127, 29, 29, 40))
                .corner_radius(8.0)
                .inner_margin(12.0)
                .show(ui, |ui| {
                    ui.label(
                        egui::RichText::new("Export did not complete")
                            .color(egui::Color32::from_rgb(239, 68, 68))
                            .size(15.0),
                    );
                });
            ui.add_space(8.0);
            egui::ScrollArea::vertical().show(ui, |ui| {
                ui.label(egui::RichText::new(text).size(12.0));
            });
        }
    }
}
