mod commands;
mod db;
mod error;
mod mcp;
mod models;
mod state;
mod utils;

use models::settings::AppSettings;
use state::AppState;
use std::sync::Arc;
use tauri::Manager;

pub fn run() {
    let shared_state = Arc::new(AppState::new());

    let _ = tauri::Builder::default()
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_dialog::init())
        .manage(shared_state)
        .setup(|app| {
            let state = app.state::<Arc<AppState>>().inner().clone();
            let data_dir = app
                .path()
                .app_data_dir()
                .map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
            let connections_path = data_dir.join("connections.json");

            // Read app settings
            let settings_path = data_dir.join("app_settings.json");

            let settings = if settings_path.exists() {
                std::fs::read_to_string(&settings_path)
                    .ok()
                    .and_then(|data| serde_json::from_str::<AppSettings>(&data).ok())
                    .unwrap_or_default()
            } else {
                AppSettings::default()
            };

            let mcp_enabled = settings.mcp.enabled;
            let mcp_port = settings.mcp.port;

            if mcp_enabled {
                let shutdown_rx = state.mcp_shutdown_tx.subscribe();
                let mcp_state = state.clone();
                tauri::async_runtime::spawn(async move {
                    *mcp_state.mcp_running.write().await = true;
                    if let Err(e) = mcp::start_mcp_server(
                        mcp_state.clone(),
                        connections_path,
                        mcp_port,
                        shutdown_rx,
                    )
                    .await
                    {
                        log::error!("MCP server error: {}", e);
                    }
                    *mcp_state.mcp_running.write().await = false;
                });
            }

            Ok(())
        })
        .invoke_handler(tauri::generate_handler![
            // connections
            commands::connections::get_connections,
            commands::connections::save_connection,
            commands::connections::delete_connection,
            commands::connections::test_connection,
            commands::connections::connect,
            commands::connections::switch_database,
            commands::connections::disconnect,
            commands::connections::set_read_only,
            commands::connections::get_read_only,
            commands::connections::get_db_flavor,
            // queries
            commands::queries::execute_query,
            // schema
            commands::schema::list_databases,
            commands::schema::list_schemas,
            commands::schema::list_tables,
            commands::schema::list_views,
            commands::schema::list_functions,
            commands::schema::list_indexes,
            commands::schema::list_sequences,
            commands::schema::get_table_columns,
            commands::schema::get_table_constraints,
            commands::schema::get_table_indexes,
            commands::schema::get_completion_schema,
            commands::schema::get_column_details,
            commands::schema::get_table_triggers,
            // data
            commands::data::get_table_data,
            commands::data::update_row,
            commands::data::insert_row,
            commands::data::delete_rows,
            // export
            commands::export::export_csv,
            commands::export::export_json,
            // history
            commands::history::add_history_entry,
            commands::history::get_history,
            commands::history::clear_history,
            // saved queries
            commands::saved_queries::list_saved_queries,
            commands::saved_queries::save_query,
            commands::saved_queries::delete_saved_query,
            // ai
            commands::ai::get_ai_settings,
            commands::ai::save_ai_settings,
            commands::ai::list_ollama_models,
            commands::ai::list_fireworks_models,
            commands::ai::list_openrouter_models,
            // chat
            commands::chat::chat_send,
            commands::chat::chat_compact,
            // memory
            commands::memory::get_memory,
            commands::memory::save_memory,
            // settings
            commands::settings::get_app_settings,
            commands::settings::save_app_settings,
            commands::settings::get_mcp_status,
        ])
        .run(tauri::generate_context!())
        .inspect_err(|e| {
            log::error!("Tauri application error: {}", e);
        });
}
