// src/editor/navigation.rs

use crate::canvas::modes::AppMode;
use crate::editor::FormEditor;
use crate::DataProvider;

impl<D: DataProvider> FormEditor<D> {
    /// Centralized field transition logic (unchanged).
    pub fn transition_to_field(&mut self, new_field: usize) -> anyhow::Result<()> {
        let field_count = self.data_provider.field_count();
        if field_count == 0 {
            return Ok(());
        }

        let prev_field = self.ui_state.current_field;

        #[cfg(feature = "computed")]
        let mut target_field = new_field.min(field_count - 1);
        #[cfg(not(feature = "computed"))]
        let target_field = new_field.min(field_count - 1);

        #[cfg(feature = "computed")]
        {
            if let Some(computed_state) = &self.ui_state.computed {
                if computed_state.is_computed_field(target_field) {
                    if target_field >= prev_field {
                        for i in (target_field + 1)..field_count {
                            if !computed_state.is_computed_field(i) {
                                target_field = i;
                                break;
                            }
                        }
                    } else {
                        let mut i = target_field;
                        loop {
                            if !computed_state.is_computed_field(i) {
                                target_field = i;
                                break;
                            }
                            if i == 0 {
                                break;
                            }
                            i -= 1;
                        }
                    }
                }
            }
        }

        if target_field == prev_field {
            return Ok(());
        }

        #[cfg(feature = "validation")]
        self.ui_state.validation.clear_last_switch_block();

        #[cfg(feature = "validation")]
        {
            let current_text = self.current_text();
            if !self
                .ui_state
                .validation
                .allows_field_switch(prev_field, current_text)
            {
                if let Some(reason) = self
                    .ui_state
                    .validation
                    .field_switch_block_reason(prev_field, current_text)
                {
                    self.ui_state
                        .validation
                        .set_last_switch_block(reason.clone());
                    tracing::debug!("Field switch blocked: {}", reason);
                    return Err(anyhow::anyhow!(
                        "Cannot switch fields: {}",
                        reason
                    ));
                }
            }
        }

        #[cfg(feature = "validation")]
        {
            let text =
                self.data_provider.field_value(prev_field).to_string();
            let _ = self
                .ui_state
                .validation
                .validate_field_content(prev_field, &text);

            if let Some(cfg) =
                self.ui_state.validation.get_field_config(prev_field)
            {
                if cfg.external_validation_enabled && !text.is_empty() {
                    self.set_external_validation(
                        prev_field,
                        crate::validation::ExternalValidationState::Validating,
                    );

                    if let Some(cb) =
                        self.external_validation_callback.as_mut()
                    {
                        let final_state = cb(prev_field, &text);
                        self.set_external_validation(prev_field, final_state);
                    }
                }
            }
        }

        #[cfg(feature = "computed")]
        {
            // Placeholder for recompute hook if needed later
        }

        self.ui_state.move_to_field(target_field, field_count);

        let current_text = self.current_text();
        let max_pos = current_text.chars().count();
        self.ui_state.set_cursor(
            self.ui_state.ideal_cursor_column,
            max_pos,
            self.ui_state.current_mode == AppMode::Edit,
        );

        // Automatically close suggestions on field switch
        #[cfg(feature = "suggestions")]
        {
            self.close_suggestions();
        }

        Ok(())
    }

    /// Move to first line (vim gg)
    pub fn move_first_line(&mut self) -> anyhow::Result<()> {
        self.transition_to_field(0)
    }

    /// Move to last line (vim G)
    pub fn move_last_line(&mut self) -> anyhow::Result<()> {
        let last_field =
            self.data_provider.field_count().saturating_sub(1);
        self.transition_to_field(last_field)
    }

    /// Move to previous field (vim k / up)
    pub fn move_up(&mut self) -> anyhow::Result<()> {
        let new_field = self.ui_state.current_field.saturating_sub(1);
        self.transition_to_field(new_field)
    }

    /// Move to next field (vim j / down)
    pub fn move_down(&mut self) -> anyhow::Result<()> {
        let new_field = (self.ui_state.current_field + 1)
            .min(self.data_provider.field_count().saturating_sub(1));
        self.transition_to_field(new_field)
    }

    /// Move to next field cyclic
    pub fn move_to_next_field(&mut self) -> anyhow::Result<()> {
        let field_count = self.data_provider.field_count();
        if field_count == 0 {
            return Ok(());
        }
        let new_field = (self.ui_state.current_field + 1) % field_count;
        self.transition_to_field(new_field)
    }

    /// Aliases
    pub fn prev_field(&mut self) -> anyhow::Result<()> {
        self.move_up()
    }

    pub fn next_field(&mut self) -> anyhow::Result<()> {
        self.move_down()
    }
}
