use pixstrip_core::types::*;
use std::path::PathBuf;

#[test]
fn image_format_from_extension() {
    assert_eq!(ImageFormat::from_extension("jpg"), Some(ImageFormat::Jpeg));
    assert_eq!(ImageFormat::from_extension("JPEG"), Some(ImageFormat::Jpeg));
    assert_eq!(ImageFormat::from_extension("png"), Some(ImageFormat::Png));
    assert_eq!(ImageFormat::from_extension("webp"), Some(ImageFormat::WebP));
    assert_eq!(ImageFormat::from_extension("avif"), Some(ImageFormat::Avif));
    assert_eq!(ImageFormat::from_extension("gif"), Some(ImageFormat::Gif));
    assert_eq!(ImageFormat::from_extension("tiff"), Some(ImageFormat::Tiff));
    assert_eq!(ImageFormat::from_extension("tif"), Some(ImageFormat::Tiff));
    assert_eq!(ImageFormat::from_extension("xyz"), None);
}

#[test]
fn image_format_extension_string() {
    assert_eq!(ImageFormat::Jpeg.extension(), "jpg");
    assert_eq!(ImageFormat::Png.extension(), "png");
    assert_eq!(ImageFormat::WebP.extension(), "webp");
    assert_eq!(ImageFormat::Avif.extension(), "avif");
}

#[test]
fn image_source_from_path() {
    let source = ImageSource::from_path("/tmp/photo.jpg");
    assert_eq!(source.path, PathBuf::from("/tmp/photo.jpg"));
    assert_eq!(source.original_format, Some(ImageFormat::Jpeg));
}

#[test]
fn image_source_unknown_format() {
    let source = ImageSource::from_path("/tmp/file.xyz");
    assert_eq!(source.original_format, None);
}

#[test]
fn dimensions_display() {
    let dims = Dimensions { width: 1920, height: 1080 };
    assert_eq!(dims.to_string(), "1920x1080");
}

#[test]
fn dimensions_aspect_ratio() {
    let dims = Dimensions { width: 1920, height: 1080 };
    let ratio = dims.aspect_ratio();
    assert!((ratio - 16.0 / 9.0).abs() < 0.01);
}

#[test]
fn dimensions_fit_within() {
    let original = Dimensions { width: 4000, height: 3000 };
    let max_box = Dimensions { width: 1200, height: 1200 };
    let fitted = original.fit_within(max_box, false);
    assert_eq!(fitted.width, 1200);
    assert_eq!(fitted.height, 900);
}

#[test]
fn dimensions_fit_within_no_upscale() {
    let original = Dimensions { width: 800, height: 600 };
    let max_box = Dimensions { width: 1200, height: 1200 };
    let fitted = original.fit_within(max_box, false);
    assert_eq!(fitted.width, 800);
    assert_eq!(fitted.height, 600);
}

#[test]
fn dimensions_fit_within_allow_upscale() {
    let original = Dimensions { width: 800, height: 600 };
    let max_box = Dimensions { width: 1200, height: 1200 };
    let fitted = original.fit_within(max_box, true);
    assert_eq!(fitted.width, 1200);
    assert_eq!(fitted.height, 900);
}

#[test]
fn quality_preset_values() {
    assert!(QualityPreset::Maximum.jpeg_quality() > QualityPreset::High.jpeg_quality());
    assert!(QualityPreset::High.jpeg_quality() > QualityPreset::Medium.jpeg_quality());
    assert!(QualityPreset::Medium.jpeg_quality() > QualityPreset::Low.jpeg_quality());
}

#[test]
fn dimensions_zero_height_aspect_ratio() {
    let dims = Dimensions { width: 1920, height: 0 };
    assert_eq!(dims.aspect_ratio(), 1.0);
}

#[test]
fn dimensions_zero_both_aspect_ratio() {
    let dims = Dimensions { width: 0, height: 0 };
    assert_eq!(dims.aspect_ratio(), 1.0);
}

#[test]
fn dimensions_fit_within_zero_self_width() {
    let original = Dimensions { width: 0, height: 600 };
    let max_box = Dimensions { width: 1200, height: 1200 };
    let fitted = original.fit_within(max_box, false);
    assert_eq!(fitted, original);
}

#[test]
fn dimensions_fit_within_zero_self_height() {
    let original = Dimensions { width: 800, height: 0 };
    let max_box = Dimensions { width: 1200, height: 1200 };
    let fitted = original.fit_within(max_box, false);
    assert_eq!(fitted, original);
}

#[test]
fn dimensions_fit_within_zero_max() {
    let original = Dimensions { width: 800, height: 600 };
    let max_box = Dimensions { width: 0, height: 0 };
    let fitted = original.fit_within(max_box, false);
    assert_eq!(fitted, original);
}
