use std::path::PathBuf;
use std::process::exit;
use std::sync::mpsc;
use std::thread;

use crate::args::CLIArgs;
use crate::args::TranscodeCommandArgs;
use crate::types::File;
use crate::utils::transcoder::presets::print_presets;
use crate::utils::transcoder::presets::transcode_preset_or_config;
use crate::utils::transcoder::transcode;

pub fn transcode_command(
    _args: &CLIArgs,
    transcode_args: &TranscodeCommandArgs,
) -> Result<(), Box<dyn std::error::Error>> {
    if transcode_args.transcode_config.is_none() && transcode_args.transcode_preset.is_none() {
        panic!("Please provide Transcode Preset/Config");
    }

    if let Some(preset) = &transcode_args.transcode_preset {
        if preset == "help" {
            print_presets();
            exit(0);
        }
    }

    println!("Transcoding");
    let input_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.source));
    let output_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.source));

    let transcode_config = transcode_preset_or_config(
        transcode_args.transcode_preset.as_ref(),
        transcode_args.transcode_config.as_ref(),
    );

    if transcode_config.is_err() {
        panic!("Please provide Transcode Preset/Config");
    }
    let transcode_config = transcode_config.unwrap();

    if !transcode_args.ignore_extension {
        if let Some(ref file_extension) = transcode_config.file_extension {
            if file_extension != &output_file.extension {
                panic!(
                    concat!(
                        "{} is not the recommended ",
                        "extension for specified transcode config ",
                        "please change it to {} ",
                        "or run with --ignore-extension"
                    ),
                    output_file.extension, file_extension
                );
            }
        }
    }

    let (tx, rx): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel();
    let child = thread::spawn(move || loop {
        let progress = rx.recv();

        if let Ok(progress_str) = progress {
            println!("Transcode Progress: {}", progress_str);
        } else {
            break;
        }
    });

    transcode(
        input_file,
        transcode_args.dest.clone(),
        transcode_config,
        Some(tx),
    )?;
    child.join().expect("oops! the child thread panicked");

    println!("Transcode Finished");

    Ok(())
}