use egui::{Modal, Id, Layout, Align, RichText};
use crate::ui::ui_helpers::PaddedWidget;

pub struct ConfirmDialog<T> {
    open: bool,
    title: String,
    message: String,
    action: Option<T>,
}

impl<T> ConfirmDialog<T> {
    pub fn new() -> Self {
        Self {
            open: false,
            title: String::new(),
            message: String::new(),
            action: None,
        }
    }

    pub fn open(&mut self, title: impl Into<String>, message: impl Into<String>, action: T) {
        self.open = true;
        self.title = title.into();
        self.message = message.into();
        self.action = Some(action);
    }

    pub fn show(&mut self, ctx: &egui::Context) -> Option<T> {
        if !self.open {
            return None;
        }

        let mut result = None;

        let modal = Modal::new(Id::new("confirm_dialog")).show(ctx, |ui| {
            ui.set_width(300.0);

            ui.vertical_centered(|ui| {
                ui.label(RichText::new(&self.title).strong().size(16.0));
                ui.add_space(6.0);
                ui.separator();
                ui.add_space(8.0);
                ui.label(&self.message);
            });

            ui.add_space(8.0);
            ui.separator();

            ui.with_layout(Layout::right_to_left(Align::Center), |ui| {

                if PaddedWidget::button("Confirm").ui(ui).clicked() {
                    result = Some(true);
                }

                ui.add_space(6.0);
                if PaddedWidget::button("Cancel").ui(ui).clicked() {
                    result = Some(false);
                }
            });
        });

        if modal.should_close() {
            self.open = false;
            self.action = None;
            return None;
        }

        if let Some(confirmed) = result {
            self.open = false;
            if confirmed {
                return self.action.take();
            }
            self.action = None;
        }

        None
    }
}

impl<T> Default for ConfirmDialog<T> {
    fn default() -> Self { Self::new() }
}