#[cfg(not(feature = "previews-image"))]
use anyhow::anyhow;
#[cfg(feature = "previews-image")]
use image::{io::Reader as ImageReader, GenericImageView};
use std::{cmp, collections::HashMap, path::Path};

use anyhow::Result;

use super::Previewable;

pub struct ImagePath<'a>(pub &'a Path);

impl<'a> Previewable for ImagePath<'a> {
    fn get_thumbnail(&self, options: HashMap<String, String>) -> Result<Option<Vec<u8>>> {
        #[cfg(feature = "previews-image")]
        {
            let file = std::fs::File::open(self.0)?;
            let mut bufreader = std::io::BufReader::new(&file);
            let exifreader = exif::Reader::new();
            let orientation = exifreader
                .read_from_container(&mut bufreader)
                .ok()
                .and_then(|exif| {
                    exif.get_field(exif::Tag::Orientation, exif::In::PRIMARY)
                        .and_then(|f| match &f.value {
                            exif::Value::Short(shorts) => Some(shorts.clone()),
                            _ => None,
                        })
                })
                .and_then(|shorts| shorts.first().cloned());

            let image = ImageReader::open(self.0)?.decode()?;
            let image = match orientation {
                Some(3) => image.rotate180(),
                Some(6) => image.rotate90(),
                Some(8) => image.rotate270(),
                _ => image,
            };

            let (w, h) = image.dimensions();
            let max_dimension = {
                if let Some(str_size) = options.get("size") {
                    str_size.parse()?
                } else {
                    1024
                }
            };
            let quality = {
                if let Some(str_quality) = options.get("quality") {
                    str_quality.parse()?
                } else {
                    90.0
                }
            };

            if cmp::max(w, h) > max_dimension {
                let thumbnail = image.thumbnail(max_dimension, max_dimension);
                let thumbnail = thumbnail.into_rgba8();
                let (w, h) = thumbnail.dimensions();
                let encoder = webp::Encoder::from_rgba(&thumbnail, w, h);
                let result = encoder.encode(quality);
                Ok(Some(result.to_vec()))
            } else {
                Ok(None)
            }
        }

        #[cfg(not(feature = "previews-image"))]
        Err(anyhow!("Image preview support not enabled!"))
    }
}
