// src/state/pages/add_table.rs

use canvas::{DataProvider, AppMode};
use ratatui::widgets::TableState;
use serde::{Deserialize, Serialize};
use crate::movement::{move_focus, MovementAction};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ColumnDefinition {
    pub name: String,
    pub data_type: String,
    pub selected: bool,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IndexDefinition {
    pub name: String,
    pub selected: bool,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LinkDefinition {
    pub linked_table_name: String,
    pub is_required: bool,
    pub selected: bool,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum AddTableFocus {
    #[default]
    InputTableName, // Field 0 for CanvasState
    InputColumnName, // Field 1 for CanvasState
    InputColumnType, // Field 2 for CanvasState
    AddColumnButton,
    // Result Tables
    ColumnsTable,
    IndexesTable,
    LinksTable,
    // Inside Tables (Scrolling Focus)
    InsideColumnsTable,
    InsideIndexesTable,
    InsideLinksTable,
    // Buttons
    SaveButton,
    DeleteSelectedButton,
    CancelButton,
}

#[derive(Debug, Clone)]
pub struct AddTableState {
    pub profile_name: String,
    pub table_name: String,
    pub table_name_input: String,
    pub column_name_input: String,
    pub column_type_input: String,
    pub columns: Vec<ColumnDefinition>,
    pub indexes: Vec<IndexDefinition>,
    pub links: Vec<LinkDefinition>,
    pub current_focus: AddTableFocus,
    pub last_canvas_field: usize,
    pub column_table_state: TableState,
    pub index_table_state: TableState,
    pub link_table_state: TableState,
    pub table_name_cursor_pos: usize,
    pub column_name_cursor_pos: usize,
    pub column_type_cursor_pos: usize,
    pub has_unsaved_changes: bool,
    pub app_mode: canvas::AppMode,
}

impl Default for AddTableState {
    fn default() -> Self {
        AddTableState {
            profile_name: "default".to_string(),
            table_name: String::new(),
            table_name_input: String::new(),
            column_name_input: String::new(),
            column_type_input: String::new(),
            columns: Vec::new(),
            indexes: Vec::new(),
            links: Vec::new(),
            current_focus: AddTableFocus::InputTableName,
            last_canvas_field: 2,
            column_table_state: TableState::default(),
            index_table_state: TableState::default(),
            link_table_state: TableState::default(),
            table_name_cursor_pos: 0,
            column_name_cursor_pos: 0,
            column_type_cursor_pos: 0,
            has_unsaved_changes: false,
            app_mode: canvas::AppMode::Edit,
        }
    }
}

impl AddTableState {
    pub const INPUT_FIELD_COUNT: usize = 3;

    /// Helper method to add a column from current inputs
    pub fn add_column_from_inputs(&mut self) -> Option<String> {
        if self.column_name_input.trim().is_empty() || self.column_type_input.trim().is_empty() {
            return Some("Both column name and type are required".to_string());
        }

        // Check for duplicate column names
        if self.columns.iter().any(|col| col.name == self.column_name_input.trim()) {
            return Some("Column name already exists".to_string());
        }

        // Add the column
        self.columns.push(ColumnDefinition {
            name: self.column_name_input.trim().to_string(),
            data_type: self.column_type_input.trim().to_string(),
            selected: false,
        });

        // Clear inputs and reset focus to column name for next entry
        self.column_name_input.clear();
        self.column_type_input.clear();
        self.column_name_cursor_pos = 0;
        self.column_type_cursor_pos = 0;
        self.current_focus = AddTableFocus::InputColumnName;
        self.last_canvas_field = 1;
        self.has_unsaved_changes = true;

        Some(format!("Column '{}' added successfully", self.columns.last().unwrap().name))
    }

    /// Helper method to delete selected items
    pub fn delete_selected_items(&mut self) -> Option<String> {
        let mut deleted_items = Vec::new();

        // Remove selected columns
        let initial_column_count = self.columns.len();
        self.columns.retain(|col| {
            if col.selected {
                deleted_items.push(format!("column '{}'", col.name));
                false
            } else {
                true
            }
        });

        // Remove selected indexes
        let initial_index_count = self.indexes.len();
        self.indexes.retain(|idx| {
            if idx.selected {
                deleted_items.push(format!("index '{}'", idx.name));
                false
            } else {
                true
            }
        });

        // Remove selected links
        let initial_link_count = self.links.len();
        self.links.retain(|link| {
            if link.selected {
                deleted_items.push(format!("link to '{}'", link.linked_table_name));
                false
            } else {
                true
            }
        });

        if deleted_items.is_empty() {
            Some("No items selected for deletion".to_string())
        } else {
            self.has_unsaved_changes = true;
            Some(format!("Deleted: {}", deleted_items.join(", ")))
        }
    }
}

impl DataProvider for AddTableState {
    fn field_count(&self) -> usize {
        3 // Table name, Column name, Column type
    }

    fn field_name(&self, index: usize) -> &str {
        match index {
            0 => "Table name",
            1 => "Name",
            2 => "Type",
            _ => "",
        }
    }

    fn field_value(&self, index: usize) -> &str {
        match index {
            0 => &self.table_name_input,
            1 => &self.column_name_input,
            2 => &self.column_type_input,
            _ => "",
        }
    }

    fn set_field_value(&mut self, index: usize, value: String) {
        match index {
            0 => self.table_name_input = value,
            1 => self.column_name_input = value,
            2 => self.column_type_input = value,
            _ => {}
        }
        self.has_unsaved_changes = true;
    }

    fn supports_suggestions(&self, _field_index: usize) -> bool {
        false // AddTableState doesn’t use suggestions
    }
}


impl AddTableState {
    pub fn handle_movement(&mut self, action: MovementAction) -> bool {
        use AddTableFocus::*;

        // Linear outer focus order
        const ORDER: [AddTableFocus; 10] = [
            InputTableName,
            InputColumnName,
            InputColumnType,
            AddColumnButton,
            ColumnsTable,
            IndexesTable,
            LinksTable,
            SaveButton,
            DeleteSelectedButton,
            CancelButton,
        ];

        // Enter "inside" on Select from outer panes
        match (self.current_focus, action) {
            (ColumnsTable, MovementAction::Select) => {
                if !self.columns.is_empty() && self.column_table_state.selected().is_none() {
                    self.column_table_state.select(Some(0));
                }
                self.current_focus = InsideColumnsTable;
                return true;
            }
            (IndexesTable, MovementAction::Select) => {
                if !self.indexes.is_empty() && self.index_table_state.selected().is_none() {
                    self.index_table_state.select(Some(0));
                }
                self.current_focus = InsideIndexesTable;
                return true;
            }
            (LinksTable, MovementAction::Select) => {
                if !self.links.is_empty() && self.link_table_state.selected().is_none() {
                    self.link_table_state.select(Some(0));
                }
                self.current_focus = InsideLinksTable;
                return true;
            }
            _ => {}
        }

        // Handle "inside" states: Up/Down/Select/Esc; block outer movement keys
        match self.current_focus {
            InsideColumnsTable => {
                match action {
                    MovementAction::Up => {
                        if let Some(i) = self.column_table_state.selected() {
                            let next = i.saturating_sub(1);
                            self.column_table_state.select(Some(next));
                        } else if !self.columns.is_empty() {
                            self.column_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Down => {
                        if let Some(i) = self.column_table_state.selected() {
                            let last = self.columns.len().saturating_sub(1);
                            let next = if i < last { i + 1 } else { i };
                            self.column_table_state.select(Some(next));
                        } else if !self.columns.is_empty() {
                            self.column_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Select => {
                        if let Some(i) = self.column_table_state.selected() {
                            if let Some(col) = self.columns.get_mut(i) {
                                col.selected = !col.selected;
                                self.has_unsaved_changes = true;
                            }
                        }
                        return true;
                    }
                    MovementAction::Esc => {
                        self.column_table_state.select(None);
                        self.current_focus = ColumnsTable;
                        return true;
                    }
                    MovementAction::Next | MovementAction::Previous => return true, // block outer moves
                    _ => {}
                }
            }
            InsideIndexesTable => {
                match action {
                    MovementAction::Up => {
                        if let Some(i) = self.index_table_state.selected() {
                            let next = i.saturating_sub(1);
                            self.index_table_state.select(Some(next));
                        } else if !self.indexes.is_empty() {
                            self.index_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Down => {
                        if let Some(i) = self.index_table_state.selected() {
                            let last = self.indexes.len().saturating_sub(1);
                            let next = if i < last { i + 1 } else { i };
                            self.index_table_state.select(Some(next));
                        } else if !self.indexes.is_empty() {
                            self.index_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Select => {
                        if let Some(i) = self.index_table_state.selected() {
                            if let Some(ix) = self.indexes.get_mut(i) {
                                ix.selected = !ix.selected;
                                self.has_unsaved_changes = true;
                            }
                        }
                        return true;
                    }
                    MovementAction::Esc => {
                        self.index_table_state.select(None);
                        self.current_focus = IndexesTable;
                        return true;
                    }
                    MovementAction::Next | MovementAction::Previous => return true, // block outer moves
                    _ => {}
                }
            }
            InsideLinksTable => {
                match action {
                    MovementAction::Up => {
                        if let Some(i) = self.link_table_state.selected() {
                            let next = i.saturating_sub(1);
                            self.link_table_state.select(Some(next));
                        } else if !self.links.is_empty() {
                            self.link_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Down => {
                        if let Some(i) = self.link_table_state.selected() {
                            let last = self.links.len().saturating_sub(1);
                            let next = if i < last { i + 1 } else { i };
                            self.link_table_state.select(Some(next));
                        } else if !self.links.is_empty() {
                            self.link_table_state.select(Some(0));
                        }
                        return true;
                    }
                    MovementAction::Select => {
                        if let Some(i) = self.link_table_state.selected() {
                            if let Some(link) = self.links.get_mut(i) {
                                link.selected = !link.selected;
                                self.has_unsaved_changes = true;
                            }
                        }
                        return true;
                    }
                    MovementAction::Esc => {
                        self.link_table_state.select(None);
                        self.current_focus = LinksTable;
                        return true;
                    }
                    MovementAction::Next | MovementAction::Previous => return true, // block outer moves
                    _ => {}
                }
            }
            _ => {}
        }

        // Default: outer navigation via helper
        move_focus(&ORDER, &mut self.current_focus, action)
    }
}
