use clap::{Subcommand, Args, ValueEnum};
use std::path::PathBuf;
use crate::types::Result;

#[derive(ValueEnum, Clone, Debug)]
#[clap(rename_all = "lower")]
pub enum ImgFormat {
    Png,
    Jpeg,
    Webp,
    Gif,
    Tiff,
    Avif,
    Bmp,
    Dds,
    Exr,
    Ff,
    Hdr,
    Ico,
    Pnm,
    Qoi,
    Tga,
}

#[derive(Args, Debug)]
pub struct ConvertArgs {
    #[arg()]
    pub input: PathBuf,

    #[arg(long, short = 'f', value_enum, default_value_t = ImgFormat::Png)]
    pub format: ImgFormat,

    #[arg(long)]
    pub out_name: Option<String>,

    #[arg(long)]
    pub out_dir: Option<PathBuf>,
}

#[derive(ValueEnum, Clone, Debug)]
#[clap(rename_all = "lower")]
pub enum PngLevel {
    Fast,
    Default,
    Best,
}

#[derive(Args, Debug)]
pub struct CompressArgs {
    #[arg()]
    pub input: PathBuf,

    #[arg(long, short = 'f', value_enum)]
    pub format: Option<ImgFormat>,

    #[arg(long)]
    pub out_name: Option<String>,

    #[arg(long)]
    pub out_dir: Option<PathBuf>,

    #[arg(long, default_value_t = 80)]
    pub quality: u8,

    #[arg(long, value_enum, default_value_t = PngLevel::Default)]
    pub png_level: PngLevel,
}

#[derive(Subcommand)]
pub enum ImageCommands {
    Convert(ConvertArgs),
    Compress(CompressArgs),
}

pub async fn handle_image_command(command: ImageCommands) -> Result<()> {
    match command {
        ImageCommands::Convert(args) => {
            crate::commands::image::convert::execute(args)
        }
        ImageCommands::Compress(args) => {
            crate::commands::image::compress::execute(args)
        }
    }
}
