use config::AppConfig;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Clone, Debug)]
pub struct AppAvatar {
    pub basic_path: PathBuf,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct AvatarLoad {
    w: Option<u32>,
    h: Option<u32>,
}

impl AppAvatar {
    pub async fn init(cfg: &AppConfig) -> anyhow::Result<Self> {
        let path = cfg.avatar_path()?;
        if std::fs::read_dir(&path).is_err() {
            std::fs::create_dir_all(&path)?;
        }
        let basic_path = PathBuf::from(path);
        Ok(Self { basic_path })
    }
    pub async fn upload(&self, file: Vec<u8>, file_name: String, ext: &str) -> anyhow::Result<()> {
        let image = image::load_from_memory(&*file)?;
        image.save(self.basic_path.join(format!("{}.{}", file_name, ext)))?;
        Ok(())
    }
    pub async fn load(&self, file_name: String, load: AvatarLoad) -> anyhow::Result<Vec<u8>> {
        let path = self.basic_path.join(format!("{}.png", file_name));
        let image = image::open(path)?;
        let (w, h) = (
            load.w.unwrap_or(image.width()),
            load.h.unwrap_or(image.height()),
        );
        let image = image.resize(w, h, image::imageops::FilterType::Nearest);
        Ok(image.as_bytes().to_vec())
    }
    pub async fn delete(&self, file_name: String, ext: &str) -> anyhow::Result<()> {
        let path = self.basic_path.join(format!("{}.{}", file_name, ext));
        std::fs::remove_file(path)?;
        Ok(())
    }
}
