// src/state/pages/auth.rs
use crate::state::pages::canvas_state::CanvasState;
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,
    pub show_role_suggestions: bool,
    pub role_suggestions: Vec<String>,
    pub selected_suggestion_index: Option<usize>,
    pub in_suggestion_mode: bool,
}

impl AuthState {
    /// Creates a new empty AuthState (unauthenticated)
    pub fn new() -> Self {
        Self {
            auth_token: None,
            user_id: None,
            role: None,
            decoded_username: None,
        }
    }
}

impl LoginState {
    /// Creates a new empty LoginState
    pub fn new() -> Self {
        Self {
            username: String::new(),
            password: String::new(),
            error_message: None,
            current_field: 0,
            current_cursor_pos: 0,
            has_unsaved_changes: false,
            login_request_pending: false,
        }
    }
}

impl RegisterState {
    /// Creates a new empty RegisterState
    pub fn new() -> Self {
        Self {
            username: String::new(),
            email: String::new(),
            password: String::new(),
            password_confirmation: String::new(),
            role: String::new(),
            error_message: None,
            current_field: 0,
            current_cursor_pos: 0,
            has_unsaved_changes: false,
            show_role_suggestions: false,
            role_suggestions: Vec::new(),
            selected_suggestion_index: None,
            in_suggestion_mode: false,
        }
    }

    /// Updates role suggestions based on current input
    pub fn update_role_suggestions(&mut self) {
        let current_input = self.role.to_lowercase();
        self.role_suggestions = AVAILABLE_ROLES
            .iter()
            .filter(|role| role.to_lowercase().contains(&current_input))
            .cloned()
            .collect();
        self.show_role_suggestions = !self.role_suggestions.is_empty();
    }
}

impl CanvasState for LoginState {
    fn current_field(&self) -> usize {
        self.current_field
    }

    fn current_cursor_pos(&self) -> usize {
        let len = match self.current_field {
            0 => self.username.len(),
            1 => self.password.len(),
            _ => 0,
        };
        self.current_cursor_pos.min(len)
    }

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

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

    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 fields(&self) -> Vec<&str> {
        vec!["Username/Email", "Password"]
    }

    fn set_current_field(&mut self, index: usize) {
        if index < 2 {
            self.current_field = index;
            let len = match self.current_field {
                0 => self.username.len(),
                1 => self.password.len(),
                _ => 0,
            };
            self.current_cursor_pos = self.current_cursor_pos.min(len);
        }
    }

    fn set_current_cursor_pos(&mut self, pos: usize) {
        let len = match self.current_field {
            0 => self.username.len(),
            1 => self.password.len(),
            _ => 0,
        };
        self.current_cursor_pos = pos.min(len);
    }

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

    fn get_suggestions(&self) -> Option<&[String]> {
        None
    }

    fn get_selected_suggestion_index(&self) -> Option<usize> {
        None
    }
}

impl CanvasState for RegisterState {
    fn current_field(&self) -> usize {
        self.current_field
    }

    fn current_cursor_pos(&self) -> usize {
        let len = match self.current_field {
            0 => self.username.len(),
            1 => self.email.len(),
            2 => self.password.len(),
            3 => self.password_confirmation.len(),
            4 => self.role.len(),
            _ => 0,
        };
        self.current_cursor_pos.min(len)
    }

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

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

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

    fn set_current_field(&mut self, index: usize) {
        if index < 5 {
            self.current_field = index;
            let len = match self.current_field {
                0 => self.username.len(),
                1 => self.email.len(),
                2 => self.password.len(),
                3 => self.password_confirmation.len(),
                4 => self.role.len(),
                _ => 0,
            };
            self.current_cursor_pos = self.current_cursor_pos.min(len);
        }
    }

    fn set_current_cursor_pos(&mut self, pos: usize) {
        let len = match self.current_field {
            0 => self.username.len(),
            1 => self.email.len(),
            2 => self.password.len(),
            3 => self.password_confirmation.len(),
            4 => self.role.len(),
            _ => 0,
        };
        self.current_cursor_pos = pos.min(len);
    }

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

    fn get_suggestions(&self) -> Option<&[String]> {
        if self.current_field == 4 && self.in_suggestion_mode && self.show_role_suggestions {
            Some(&self.role_suggestions)
        } else {
            None
        }
    }

    fn get_selected_suggestion_index(&self) -> Option<usize> {
        if self.current_field == 4 && self.in_suggestion_mode && self.show_role_suggestions {
            self.selected_suggestion_index
        } else {
            None
        }
    }
}
