use pixstrip_core::watcher::*;
use std::sync::mpsc;

#[test]
fn watch_folder_serialization() {
    let folder = WatchFolder {
        path: "/home/user/photos".into(),
        preset_name: "Blog Photos".into(),
        recursive: true,
        active: true,
    };

    let json = serde_json::to_string(&folder).unwrap();
    let deserialized: WatchFolder = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized.preset_name, "Blog Photos");
    assert!(deserialized.recursive);
}

#[test]
fn watcher_starts_and_stops() {
    let dir = tempfile::tempdir().unwrap();
    let folder = WatchFolder {
        path: dir.path().to_path_buf(),
        preset_name: "Test".into(),
        recursive: false,
        active: true,
    };

    let watcher = FolderWatcher::new();
    let (tx, _rx) = mpsc::channel();

    watcher.start(&folder, tx).unwrap();
    assert!(watcher.is_running());

    watcher.stop();
    // Give the thread time to see the stop signal
    std::thread::sleep(std::time::Duration::from_millis(600));
    assert!(!watcher.is_running());
}

#[test]
fn watcher_detects_new_image() {
    let dir = tempfile::tempdir().unwrap();
    let folder = WatchFolder {
        path: dir.path().to_path_buf(),
        preset_name: "Test".into(),
        recursive: false,
        active: true,
    };

    let watcher = FolderWatcher::new();
    let (tx, rx) = mpsc::channel();

    watcher.start(&folder, tx).unwrap();

    // Wait for watcher to be ready
    std::thread::sleep(std::time::Duration::from_millis(500));

    // Create an image file
    let img_path = dir.path().join("new_photo.jpg");
    std::fs::write(&img_path, b"fake jpeg data").unwrap();

    // Wait and check for event
    let event = rx.recv_timeout(std::time::Duration::from_secs(3));
    watcher.stop();

    match event {
        Ok(WatchEvent::NewImage(path)) => {
            assert_eq!(path, img_path);
        }
        Ok(WatchEvent::Error(e)) => panic!("Unexpected error: {}", e),
        Err(_) => panic!("No event received within timeout"),
    }
}

#[test]
fn watcher_ignores_non_image_files() {
    let dir = tempfile::tempdir().unwrap();
    let folder = WatchFolder {
        path: dir.path().to_path_buf(),
        preset_name: "Test".into(),
        recursive: false,
        active: true,
    };

    let watcher = FolderWatcher::new();
    let (tx, rx) = mpsc::channel();

    watcher.start(&folder, tx).unwrap();
    std::thread::sleep(std::time::Duration::from_millis(500));

    // Create a non-image file
    std::fs::write(dir.path().join("readme.txt"), b"text file").unwrap();

    // Should not receive any event
    let result = rx.recv_timeout(std::time::Duration::from_secs(1));
    watcher.stop();

    assert!(result.is_err(), "Should not receive event for non-image file");
}

#[test]
fn watcher_rejects_nonexistent_path() {
    let folder = WatchFolder {
        path: "/nonexistent/path/to/watch".into(),
        preset_name: "Test".into(),
        recursive: false,
        active: true,
    };

    let watcher = FolderWatcher::new();
    let (tx, _rx) = mpsc::channel();

    assert!(watcher.start(&folder, tx).is_err());
}
