use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::path::PathBuf;
use std::sync::Mutex;
use tauri::{AppHandle, State};

use crate::infrastructure::notify_watcher::run_debounce_loop;

pub struct WatcherState(pub Mutex<Option<RecommendedWatcher>>);

#[tauri::command]
pub fn start_watch(
    app: AppHandle,
    path: String,
    state: State<WatcherState>,
) -> Result<(), String> {
    // Drop the previous watcher — disconnects the channel and stops the background thread
    {
        let mut guard = state.0.lock().unwrap();
        *guard = None;
    }

    let (tx, rx) = std::sync::mpsc::channel::<notify::Result<notify::Event>>();

    let mut watcher = notify::recommended_watcher(move |res| {
        let _ = tx.send(res);
    })
    .map_err(|e| e.to_string())?;

    let watch_path = PathBuf::from(&path);
    let mode = if watch_path.is_dir() {
        RecursiveMode::Recursive
    } else {
        RecursiveMode::NonRecursive
    };

    watcher
        .watch(&watch_path, mode)
        .map_err(|e| e.to_string())?;

    std::thread::spawn(move || {
        run_debounce_loop(rx, app);
    });

    let mut guard = state.0.lock().unwrap();
    *guard = Some(watcher);

    Ok(())
}

#[tauri::command]
pub fn stop_watch(state: State<WatcherState>) {
    let mut guard = state.0.lock().unwrap();
    *guard = None;
}
