// src/state/app/buffer.rs

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AppView {
    Intro,
    Login,
    Register,
    Admin,
    AddTable,
    AddLogic,
    Form,
    Scratch,
}

impl AppView {
    /// Returns the display name for the view.
    /// For Form, pass the current table name to get dynamic naming.
    pub fn display_name(&self) -> &str {
        match self {
            AppView::Intro => "Intro",
            AppView::Login => "Login",
            AppView::Register => "Register",
            AppView::Admin => "Admin_Panel",
            AppView::AddTable => "Add_Table",
            AppView::AddLogic => "Add_Logic",
            AppView::Form => "Form",
            AppView::Scratch => "*scratch*",
        }
    }

    /// Returns the display name with dynamic context (for Form buffers)
    pub fn display_name_with_context(&self, current_table_name: Option<&str>) -> String {
        match self {
            AppView::Form => {
                current_table_name
                    .unwrap_or("Data Form")
                    .to_string()
            }
            _ => self.display_name().to_string(),
        }
    }
}

#[derive(Debug, Clone)]
pub struct BufferState {
    pub history: Vec<AppView>,
    pub active_index: usize,
}

impl Default for BufferState {
    fn default() -> Self {
        Self {
            history: vec![AppView::Intro],
            active_index: 0,
        }
    }
}

impl BufferState {
    pub fn update_history(&mut self, view: AppView) {
        let existing_pos = self.history.iter().position(|v| v == &view);
        match existing_pos {
            Some(pos) => self.active_index = pos,
            None => {
                self.history.push(view.clone());
                self.active_index = self.history.len() - 1;
            }
        }
    }

    pub fn get_active_view(&self) -> Option<&AppView> {
        self.history.get(self.active_index)
    }

    pub fn close_active_buffer(&mut self) -> bool {
        if self.history.is_empty() {
            self.history.push(AppView::Intro);
            self.active_index = 0;
            return false;
        }

        let current_index = self.active_index;
        self.history.remove(current_index);

        if self.history.is_empty() {
            self.history.push(AppView::Intro);
            self.active_index = 0;
        } else if self.active_index >= self.history.len() {
            self.active_index = self.history.len() - 1;
        }
        true
    }

    pub fn close_buffer_with_intro_fallback(&mut self, current_table_name: Option<&str>) -> String {
        let current_view_cloned = self.get_active_view().cloned();

        if let Some(AppView::Intro) = current_view_cloned {
            if self.history.len() == 1 {
                self.close_active_buffer();
                return "Intro buffer reset".to_string();
            }
        }

        let closed_name = current_view_cloned
            .as_ref()
            .map(|v| v.display_name_with_context(current_table_name))
            .unwrap_or_else(|| "Unknown".to_string());

        if self.close_active_buffer() {
            if self.history.len() == 1 && matches!(self.history.get(0), Some(AppView::Intro)) {
                format!("Closed '{}' - returned to Intro", closed_name)
            } else {
                format!("Closed '{}'", closed_name)
            }
        } else {
            format!("Buffer '{}' could not be closed", closed_name)
        }
    }
}
