// src/state/pages/auth.rs
use canvas::canvas::{CanvasState, ActionContext, CanvasAction};
use canvas::autocomplete::{AutocompleteCanvasState, AutocompleteState, SuggestionItem};
use lazy_static::lazy_static;

lazy_static! {
    pub static ref AVAILABLE_ROLES: Vec<String> = vec![
        "admin".to_string(),
        "moderator".to_string(),
        "accountant".to_string(),
        "viewer".to_string(),
    ];
}

/// Represents the authenticated session state
#[derive(Default)]
pub struct AuthState {
    pub auth_token: Option<String>,
    pub user_id: Option<String>,
    pub role: Option<String>,
    pub decoded_username: Option<String>,
}

/// Represents the state of the Login form UI
#[derive(Default)]
pub struct LoginState {
    pub username: String,
    pub password: String,
    pub error_message: Option<String>,
    pub current_field: usize,
    pub current_cursor_pos: usize,
    pub has_unsaved_changes: bool,
    pub login_request_pending: bool,
}

/// Represents the state of the Registration form UI
#[derive(Default, Clone)]
pub struct RegisterState {
    pub username: String,
    pub email: String,
    pub password: String,
    pub password_confirmation: String,
    pub role: String,
    pub error_message: Option<String>,
    pub current_field: usize,
    pub current_cursor_pos: usize,
    pub has_unsaved_changes: bool,
    // NEW: Replace old autocomplete with external library's system
    pub autocomplete: AutocompleteState<String>,
}

impl AuthState {
    pub fn new() -> Self {
        Self::default()
    }
}

impl LoginState {
    pub fn new() -> Self {
        Self::default()
    }
}

impl RegisterState {
    pub fn new() -> Self {
        let mut state = Self {
            autocomplete: AutocompleteState::new(),
            ..Default::default()
        };
        
        // Initialize autocomplete with role suggestions
        let suggestions: Vec<SuggestionItem<String>> = AVAILABLE_ROLES
            .iter()
            .map(|role| SuggestionItem::simple(role.clone(), role.clone()))
            .collect();
        
        // Set suggestions but keep inactive initially
        state.autocomplete.set_suggestions(suggestions);
        state.autocomplete.is_active = false; // Not active by default
        
        state
    }
}

// Implement external library's CanvasState for LoginState
impl CanvasState for LoginState {
    fn current_field(&self) -> usize {
        self.current_field
    }

    fn current_cursor_pos(&self) -> usize {
        self.current_cursor_pos
    }

    fn set_current_field(&mut self, index: usize) {
        if index < 2 {
            self.current_field = index;
        }
    }

    fn set_current_cursor_pos(&mut self, pos: usize) {
        self.current_cursor_pos = pos;
    }

    fn get_current_input(&self) -> &str {
        match self.current_field {
            0 => &self.username,
            1 => &self.password,
            _ => "",
        }
    }

    fn get_current_input_mut(&mut self) -> &mut String {
        match self.current_field {
            0 => &mut self.username,
            1 => &mut self.password,
            _ => panic!("Invalid current_field index in LoginState"),
        }
    }

    fn inputs(&self) -> Vec<&String> {
        vec![&self.username, &self.password]
    }

    fn fields(&self) -> Vec<&str> {
        vec!["Username/Email", "Password"]
    }

    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 {
            CanvasAction::Custom(action_str) if action_str == "submit" => {
                if !self.username.is_empty() && !self.password.is_empty() {
                    Some(format!("Submitting login for: {}", self.username))
                } else {
                    Some("Please fill in all required fields".to_string())
                }
            }
            _ => None,
        }
    }
}

// Implement external library's CanvasState for RegisterState
impl CanvasState for RegisterState {
    fn current_field(&self) -> usize {
        self.current_field
    }

    fn current_cursor_pos(&self) -> usize {
        self.current_cursor_pos
    }

    fn set_current_field(&mut self, index: usize) {
        if index < 5 {
            self.current_field = index;
            
            // Auto-activate autocomplete when moving to role field (index 4)
            if index == 4 && !self.autocomplete.is_active {
                self.activate_autocomplete();
            } else if index != 4 && self.autocomplete.is_active {
                self.deactivate_autocomplete();
            }
        }
    }

    fn set_current_cursor_pos(&mut self, pos: usize) {
        self.current_cursor_pos = pos;
    }

    fn get_current_input(&self) -> &str {
        match self.current_field {
            0 => &self.username,
            1 => &self.email,
            2 => &self.password,
            3 => &self.password_confirmation,
            4 => &self.role,
            _ => "",
        }
    }

    fn get_current_input_mut(&mut self) -> &mut String {
        match self.current_field {
            0 => &mut self.username,
            1 => &mut self.email,
            2 => &mut self.password,
            3 => &mut self.password_confirmation,
            4 => &mut self.role,
            _ => panic!("Invalid current_field index in RegisterState"),
        }
    }

    fn inputs(&self) -> Vec<&String> {
        vec![
            &self.username,
            &self.email,
            &self.password,
            &self.password_confirmation,
            &self.role,
        ]
    }

    fn fields(&self) -> Vec<&str> {
        vec![
            "Username",
            "Email (Optional)",
            "Password (Optional)",
            "Confirm Password",
            "Role (Optional)"
        ]
    }

    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 {
            CanvasAction::Custom(action_str) if action_str == "submit" => {
                if !self.username.is_empty() {
                    Some(format!("Submitting registration for: {}", self.username))
                } else {
                    Some("Username is required".to_string())
                }
            }
            _ => None,
        }
    }
}

// Add autocomplete support for RegisterState
impl AutocompleteCanvasState for RegisterState {
    type SuggestionData = String;

    fn supports_autocomplete(&self, field_index: usize) -> bool {
        field_index == 4 // Only role field supports autocomplete
    }

    fn autocomplete_state(&self) -> Option<&AutocompleteState<Self::SuggestionData>> {
        Some(&self.autocomplete)
    }

    fn autocomplete_state_mut(&mut self) -> Option<&mut AutocompleteState<Self::SuggestionData>> {
        Some(&mut self.autocomplete)
    }

    fn activate_autocomplete(&mut self) {
        let current_field = self.current_field();
        if self.supports_autocomplete(current_field) {
            self.autocomplete.activate(current_field);
            
            // Re-filter suggestions based on current input
            let current_input = self.role.to_lowercase();
            let filtered_suggestions: Vec<SuggestionItem<String>> = AVAILABLE_ROLES
                .iter()
                .filter(|role| role.to_lowercase().contains(&current_input))
                .map(|role| SuggestionItem::simple(role.clone(), role.clone()))
                .collect();
            
            self.autocomplete.set_suggestions(filtered_suggestions);
        }
    }

    fn deactivate_autocomplete(&mut self) {
        self.autocomplete.deactivate();
    }

    fn is_autocomplete_active(&self) -> bool {
        self.autocomplete.is_active
    }

    fn is_autocomplete_ready(&self) -> bool {
        self.autocomplete.is_ready()
    }

    fn apply_autocomplete_selection(&mut self) -> Option<String> {
        // First, get the data we need and clone it to avoid borrowing conflicts
        let selection_info = self.autocomplete.get_selected().map(|selected| {
            (selected.value_to_store.clone(), selected.display_text.clone())
        });

        // Now do the mutable operations
        if let Some((value, display_text)) = selection_info {
            self.role = value;
            self.set_has_unsaved_changes(true);
            self.deactivate_autocomplete();
            Some(format!("Selected role: {}", display_text))
        } else {
            None
        }
    }

    fn set_autocomplete_suggestions(&mut self, suggestions: Vec<SuggestionItem<Self::SuggestionData>>) {
        if let Some(state) = self.autocomplete_state_mut() {
            state.set_suggestions(suggestions);
        }
    }

    fn set_autocomplete_loading(&mut self, loading: bool) {
        if let Some(state) = self.autocomplete_state_mut() {
            state.is_loading = loading;
        }
    }
}
