use pixstrip_core::operations::rename::{
    apply_template, apply_regex_replace, apply_space_replacement,
    apply_special_chars, apply_case_conversion, resolve_collision,
};

#[test]
fn template_basic_variables() {
    let result = apply_template(
        "{name}_{counter:3}.{ext}",
        "sunset",
        "jpg",
        1,
        None,
    );
    assert_eq!(result, "sunset_001.jpg");
}

#[test]
fn template_with_prefix() {
    let result = apply_template(
        "blog_{name}.{ext}",
        "photo",
        "webp",
        1,
        None,
    );
    assert_eq!(result, "blog_photo.webp");
}

#[test]
fn template_counter_padding() {
    let result = apply_template(
        "{name}_{counter:4}.{ext}",
        "img",
        "png",
        42,
        None,
    );
    assert_eq!(result, "img_0042.png");
}

#[test]
fn template_counter_no_padding() {
    let result = apply_template(
        "{name}_{counter}.{ext}",
        "img",
        "png",
        42,
        None,
    );
    assert_eq!(result, "img_42.png");
}

#[test]
fn template_width_height() {
    let result = apply_template(
        "{name}_{width}x{height}.{ext}",
        "photo",
        "jpg",
        1,
        Some((1920, 1080)),
    );
    assert_eq!(result, "photo_1920x1080.jpg");
}

#[test]
fn collision_adds_suffix() {
    let dir = tempfile::tempdir().unwrap();
    let base = dir.path().join("photo.jpg");
    std::fs::write(&base, b"exists").unwrap();

    let resolved = resolve_collision(&base);
    assert_eq!(
        resolved.file_name().unwrap().to_str().unwrap(),
        "photo_1.jpg"
    );
}

#[test]
fn collision_increments() {
    let dir = tempfile::tempdir().unwrap();
    std::fs::write(dir.path().join("photo.jpg"), b"exists").unwrap();
    std::fs::write(dir.path().join("photo_1.jpg"), b"exists").unwrap();

    let resolved = resolve_collision(&dir.path().join("photo.jpg"));
    assert_eq!(
        resolved.file_name().unwrap().to_str().unwrap(),
        "photo_2.jpg"
    );
}

#[test]
fn no_collision_returns_same() {
    let dir = tempfile::tempdir().unwrap();
    let path = dir.path().join("unique.jpg");
    let resolved = resolve_collision(&path);
    assert_eq!(resolved, path);
}

// --- Regex replace tests ---

#[test]
fn regex_replace_basic() {
    let result = apply_regex_replace("hello_world", "_", "-");
    assert_eq!(result, "hello-world");
}

#[test]
fn regex_replace_pattern() {
    let result = apply_regex_replace("IMG_20260307_001", r"\d{8}", "DATE");
    assert_eq!(result, "IMG_DATE_001");
}

#[test]
fn regex_replace_invalid_pattern_returns_original() {
    let result = apply_regex_replace("hello", "[invalid", "x");
    assert_eq!(result, "hello");
}

#[test]
fn regex_replace_empty_find_returns_original() {
    let result = apply_regex_replace("hello", "", "x");
    assert_eq!(result, "hello");
}

// --- Space replacement tests ---

#[test]
fn space_replacement_none() {
    assert_eq!(apply_space_replacement("hello world", 0), "hello world");
}

#[test]
fn space_replacement_underscore() {
    assert_eq!(apply_space_replacement("hello world", 1), "hello_world");
}

#[test]
fn space_replacement_hyphen() {
    assert_eq!(apply_space_replacement("hello world", 2), "hello-world");
}

#[test]
fn space_replacement_dot() {
    assert_eq!(apply_space_replacement("hello world", 3), "hello.world");
}

#[test]
fn space_replacement_camelcase() {
    assert_eq!(apply_space_replacement("hello world", 4), "helloWorld");
}

#[test]
fn space_replacement_remove() {
    assert_eq!(apply_space_replacement("hello world", 5), "helloworld");
}

// --- Special chars tests ---

#[test]
fn special_chars_keep_all() {
    assert_eq!(apply_special_chars("file<name>.txt", 0), "file<name>.txt");
}

#[test]
fn special_chars_filesystem_safe() {
    assert_eq!(apply_special_chars("file<name>", 1), "filename");
}

#[test]
fn special_chars_web_safe() {
    assert_eq!(apply_special_chars("file name!@#", 2), "filename");
}

#[test]
fn special_chars_alphanumeric_only() {
    assert_eq!(apply_special_chars("file-name_123", 5), "filename123");
}

// --- Case conversion tests ---

#[test]
fn case_conversion_none() {
    assert_eq!(apply_case_conversion("Hello World", 0), "Hello World");
}

#[test]
fn case_conversion_lowercase() {
    assert_eq!(apply_case_conversion("Hello World", 1), "hello world");
}

#[test]
fn case_conversion_uppercase() {
    assert_eq!(apply_case_conversion("Hello World", 2), "HELLO WORLD");
}

#[test]
fn case_conversion_title_case() {
    assert_eq!(apply_case_conversion("hello world", 3), "Hello World");
}

#[test]
fn case_conversion_title_preserves_separators() {
    assert_eq!(apply_case_conversion("hello-world_foo", 3), "Hello-World_Foo");
}

// --- RenameConfig::apply_simple edge cases ---

use pixstrip_core::operations::RenameConfig;

fn default_rename_config() -> RenameConfig {
    RenameConfig {
        prefix: String::new(),
        suffix: String::new(),
        counter_start: 1,
        counter_padding: 3,
        counter_enabled: false,
        counter_position: 3,
        template: None,
        case_mode: 0,
        replace_spaces: 0,
        special_chars: 0,
        regex_find: String::new(),
        regex_replace: String::new(),
    }
}

#[test]
fn apply_simple_no_changes() {
    let cfg = default_rename_config();
    assert_eq!(cfg.apply_simple("photo", "jpg", 1), "photo.jpg");
}

#[test]
fn apply_simple_with_prefix_suffix() {
    let mut cfg = default_rename_config();
    cfg.prefix = "web_".into();
    cfg.suffix = "_final".into();
    assert_eq!(cfg.apply_simple("photo", "jpg", 1), "web_photo_final.jpg");
}

#[test]
fn apply_simple_counter_after_suffix() {
    let mut cfg = default_rename_config();
    cfg.counter_enabled = true;
    cfg.counter_position = 3;
    assert_eq!(cfg.apply_simple("photo", "jpg", 1), "photo_001.jpg");
}

#[test]
fn apply_simple_counter_replaces_name() {
    let mut cfg = default_rename_config();
    cfg.counter_enabled = true;
    cfg.counter_position = 4;
    assert_eq!(cfg.apply_simple("photo", "jpg", 1), "001.jpg");
}

#[test]
fn apply_simple_empty_name() {
    let cfg = default_rename_config();
    assert_eq!(cfg.apply_simple("", "png", 1), ".png");
}

#[test]
fn apply_simple_case_lowercase() {
    let mut cfg = default_rename_config();
    cfg.case_mode = 1;
    assert_eq!(cfg.apply_simple("MyPhoto", "JPG", 1), "myphoto.JPG");
}

#[test]
fn apply_simple_large_counter_padding_capped() {
    let mut cfg = default_rename_config();
    cfg.counter_enabled = true;
    cfg.counter_padding = 100; // should be capped to 10
    cfg.counter_position = 3;
    let result = cfg.apply_simple("photo", "jpg", 1);
    // Counter portion should be at most 10 digits
    assert!(result.len() <= 22); // "photo_" + 10 digits + ".jpg"
}
