// src/pages/login/state.rs

use canvas::{AppMode, DataProvider};
use canvas::FormEditor;
use std::fmt;

#[derive(Debug, Clone)]
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,
    pub app_mode: AppMode,
}

impl Default for LoginState {
    fn default() -> 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,
            app_mode: canvas::AppMode::Edit,
        }
    }
}

impl LoginState {
    pub fn new() -> Self {
        Self {
            app_mode: canvas::AppMode::Edit,
            ..Default::default()
        }
    }

    pub fn current_field(&self) -> usize {
        self.current_field
    }

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

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

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

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

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

    pub fn current_mode(&self) -> AppMode {
        self.app_mode
    }

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

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

// Implement DataProvider for LoginState
impl DataProvider for LoginState {
    fn field_count(&self) -> usize {
        2
    }

    fn field_name(&self, index: usize) -> &str {
        match index {
            0 => "Username/Email",
            1 => "Password",
            _ => "",
        }
    }

    fn field_value(&self, index: usize) -> &str {
        match index {
            0 => &self.username,
            1 => &self.password,
            _ => "",
        }
    }

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

    fn supports_suggestions(&self, _field_index: usize) -> bool {
        false // Login form doesn't support suggestions
    }
}

/// Wrapper that owns both the raw login state and its editor

pub struct LoginFormState {
    pub state: LoginState,
    pub editor: FormEditor<LoginState>,
}

// manual debug because FormEditor doesnt implement debug
impl fmt::Debug for LoginFormState {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("LoginFormState")
            .field("state", &self.state) // ✅ only print the data
            .finish()
    }
}

impl LoginFormState {
    /// Sync the editor's data provider back into our state
    pub fn sync_from_editor(&mut self) {
        // FormEditor holds the authoritative data
        let dp = self.editor.data_provider();
        self.state = dp.clone(); // LoginState implements Clone
    }

    /// Create a new LoginFormState with default LoginState and FormEditor
    pub fn new() -> Self {
        let state = LoginState::default();
        let editor = FormEditor::new(state.clone());
        Self { state, editor }
    }

    // === Delegates to LoginState fields ===

    pub fn username(&self) -> &str {
        &self.state.username
    }

    pub fn username_mut(&mut self) -> &mut String {
        &mut self.state.username
    }

    pub fn password(&self) -> &str {
        &self.state.password
    }

    pub fn password_mut(&mut self) -> &mut String {
        &mut self.state.password
    }

    pub fn error_message(&self) -> Option<&String> {
        self.state.error_message.as_ref()
    }

    pub fn set_error_message(&mut self, msg: Option<String>) {
        self.state.error_message = msg;
    }

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

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

    pub fn clear(&mut self) {
        self.state.username.clear();
        self.state.password.clear();
        self.state.error_message = None;
        self.state.has_unsaved_changes = false;
        self.state.login_request_pending = false;
        self.state.current_cursor_pos = 0;
    }

    // === Delegates to LoginState cursor/input ===

    pub fn current_field(&self) -> usize {
        self.state.current_field()
    }

    pub fn set_current_field(&mut self, index: usize) {
        self.state.set_current_field(index);
    }

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

    pub fn set_current_cursor_pos(&mut self, pos: usize) {
        self.state.set_current_cursor_pos(pos);
    }

    pub fn get_current_input(&self) -> &str {
        self.state.get_current_input()
    }

    pub fn get_current_input_mut(&mut self) -> &mut String {
        self.state.get_current_input_mut()
    }

    // === Delegates to FormEditor ===

    pub fn mode(&self) -> AppMode {
        self.editor.mode()
    }

    pub fn cursor_position(&self) -> usize {
        self.editor.cursor_position()
    }

    pub fn handle_key_event(
        &mut self,
        key_event: crossterm::event::KeyEvent,
    ) -> canvas::keymap::KeyEventOutcome {
        self.editor.handle_key_event(key_event)
    }
}
