// src/search/event.rs
use crate::state::app::state::AppState;
use crate::services::grpc_client::GrpcClient;
use common::proto::komp_ac::search::search_response::Hit;
use crossterm::event::KeyCode;
use tokio::sync::mpsc;
use tracing::{error, info};
use std::collections::HashMap;
use anyhow::Result;

pub async fn handle_search_palette_event(
    key_event: crossterm::event::KeyEvent,
    app_state: &mut AppState,
    grpc_client: &mut GrpcClient,
    search_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
) -> Result<Option<String>> {
    let mut should_close = false;
    let mut outcome_message = None;
    let mut trigger_search = false;

    if let Some(search_state) = app_state.search_state.as_mut() {
        match key_event.code {
            KeyCode::Esc => {
                should_close = true;
                outcome_message = Some("Search cancelled".to_string());
            }
            KeyCode::Enter => {
                // Step 1: Extract the data we need while holding the borrow
                let maybe_data = search_state
                    .results
                    .get(search_state.selected_index)
                    .map(|hit| (hit.id, hit.content_json.clone()));

                // Step 2: Process outside the borrow
                if let Some((id, content_json)) = maybe_data {
                    if let Ok(data) = serde_json::from_str::<HashMap<String, String>>(&content_json) {
                        // Use current view path to access the active form
                        if let (Some(profile), Some(table)) = (
                            app_state.current_view_profile_name.clone(),
                            app_state.current_view_table_name.clone(),
                        ) {
                            let path = format!("{}/{}", profile, table);
                            if let Some(fs) = app_state.form_state_for_path(&path) {
                                let detached_pos = fs.total_count + 2;
                                fs.update_from_response(&data, detached_pos);
                            }
                        }
                        should_close = true;
                        outcome_message = Some(format!("Loaded record ID {}", id));
                    }
                }
            }
            KeyCode::Up => search_state.previous_result(),
            KeyCode::Down => search_state.next_result(),
            KeyCode::Char(c) => {
                search_state.input.insert(search_state.cursor_position, c);
                search_state.cursor_position += 1;
                trigger_search = true;
            }
            KeyCode::Backspace => {
                if search_state.cursor_position > 0 {
                    search_state.cursor_position -= 1;
                    search_state.input.remove(search_state.cursor_position);
                    trigger_search = true;
                }
            }
            KeyCode::Left => {
                search_state.cursor_position =
                    search_state.cursor_position.saturating_sub(1);
            }
            KeyCode::Right => {
                if search_state.cursor_position < search_state.input.len() {
                    search_state.cursor_position += 1;
                }
            }
            _ => {}
        }
    }

    if trigger_search {
        if let Some(search_state) = app_state.search_state.as_mut() {
            search_state.is_loading = true;
            search_state.results.clear();
            search_state.selected_index = 0;

            let query = search_state.input.clone();
            let table_name = search_state.table_name.clone();
            let sender = search_result_sender.clone();
            let mut grpc_client = grpc_client.clone();

            info!("Spawning search task for query: '{}'", query);
            tokio::spawn(async move {
                match grpc_client.search_table(table_name, query).await {
                    Ok(response) => {
                        let _ = sender.send(response.hits);
                    }
                    Err(e) => {
                        error!("Search failed: {:?}", e);
                        let _ = sender.send(vec![]);
                    }
                }
            });
        }
    }

    if should_close {
        app_state.search_state = None;
        app_state.ui.show_search_palette = false;
        app_state.ui.focus_outside_canvas = false;
    }

    Ok(outcome_message)
}
