// src/state/pages/add_table.rs
use canvas::canvas::{CanvasState, ActionContext, CanvasAction}; // External library
use ratatui::widgets::TableState;
use serde::{Deserialize, Serialize};

#[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,
}

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,
        }
    }
}

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(", ")))
        }
    }
}

// Implement external library's CanvasState for AddTableState
impl CanvasState for AddTableState {
    fn current_field(&self) -> usize {
        match self.current_focus {
            AddTableFocus::InputTableName => 0,
            AddTableFocus::InputColumnName => 1,
            AddTableFocus::InputColumnType => 2,
            // If focus is elsewhere, return the last canvas field used
            _ => self.last_canvas_field,
        }
    }

    fn current_cursor_pos(&self) -> usize {
        match self.current_focus {
            AddTableFocus::InputTableName => self.table_name_cursor_pos,
            AddTableFocus::InputColumnName => self.column_name_cursor_pos,
            AddTableFocus::InputColumnType => self.column_type_cursor_pos,
            _ => 0, // Default if focus is not on an input field
        }
    }

    fn set_current_field(&mut self, index: usize) {
        // Update both current focus and last canvas field
        self.current_focus = match index {
            0 => {
                self.last_canvas_field = 0;
                AddTableFocus::InputTableName
            },
            1 => {
                self.last_canvas_field = 1;
                AddTableFocus::InputColumnName
            },
            2 => {
                self.last_canvas_field = 2;
                AddTableFocus::InputColumnType
            },
            _ => self.current_focus, // Stay on current focus if index is out of bounds
        };
    }

    fn set_current_cursor_pos(&mut self, pos: usize) {
        match self.current_focus {
            AddTableFocus::InputTableName => self.table_name_cursor_pos = pos,
            AddTableFocus::InputColumnName => self.column_name_cursor_pos = pos,
            AddTableFocus::InputColumnType => self.column_type_cursor_pos = pos,
            _ => {} // Do nothing if focus is not on an input field
        }
    }

    fn get_current_input(&self) -> &str {
        match self.current_focus {
            AddTableFocus::InputTableName => &self.table_name_input,
            AddTableFocus::InputColumnName => &self.column_name_input,
            AddTableFocus::InputColumnType => &self.column_type_input,
            _ => "", // Should not happen if called correctly
        }
    }

    fn get_current_input_mut(&mut self) -> &mut String {
        match self.current_focus {
            AddTableFocus::InputTableName => &mut self.table_name_input,
            AddTableFocus::InputColumnName => &mut self.column_name_input,
            AddTableFocus::InputColumnType => &mut self.column_type_input,
            _ => &mut self.table_name_input, // Fallback
        }
    }

    fn inputs(&self) -> Vec<&String> {
        vec![&self.table_name_input, &self.column_name_input, &self.column_type_input]
    }

    fn fields(&self) -> Vec<&str> {
        // These must match the order used in render_add_table
        vec!["Table name", "Name", "Type"]
    }

    fn has_unsaved_changes(&self) -> bool {
        self.has_unsaved_changes
    }

    fn set_has_unsaved_changes(&mut self, changed: bool) {
        self.has_unsaved_changes = changed;
    }

    fn handle_feature_action(&mut self, action: &CanvasAction, _context: &ActionContext) -> Option<String> {
        match action {
            // Handle adding column when user presses Enter on the Add button or uses specific action
            CanvasAction::Custom(action_str) if action_str == "add_column" => {
                self.add_column_from_inputs()
            }

            // Handle table saving
            CanvasAction::Custom(action_str) if action_str == "save_table" => {
                if self.table_name_input.trim().is_empty() {
                    Some("Table name is required".to_string())
                } else if self.columns.is_empty() {
                    Some("At least one column is required".to_string())
                } else {
                    Some(format!("Saving table: {}", self.table_name_input))
                }
            }

            // Handle deleting selected items
            CanvasAction::Custom(action_str) if action_str == "delete_selected" => {
                self.delete_selected_items()
            }

            // Handle canceling (clear form)
            CanvasAction::Custom(action_str) if action_str == "cancel" => {
                // Reset to defaults but keep profile_name
                let profile = self.profile_name.clone();
                *self = Self::default();
                self.profile_name = profile;
                Some("Form cleared".to_string())
            }

            // Custom validation when moving between fields
            CanvasAction::NextField => {
                // When leaving table name field, update the table_name for display
                if self.current_field() == 0 && !self.table_name_input.trim().is_empty() {
                    self.table_name = self.table_name_input.trim().to_string();
                }
                None // Let canvas library handle the normal field movement
            }

            // Let canvas library handle everything else
            _ => None,
        }
    }
}
