use std::path::{Path, PathBuf};
use std::process::Command;
use std::fs;
use crate::types::Result;
use crate::utils::log::{success, info};
use super::commands::RemoveAudioArgs;

fn detect_extension(input: &Path) -> &str {
    input.extension()
        .and_then(|e| e.to_str())
        .unwrap_or("mp4")
}

fn build_output_path(input: &Path, output: Option<PathBuf>) -> PathBuf {
    if let Some(out) = output {
        return out;
    }
    
    let parent = input.parent().unwrap_or_else(|| Path::new("."));
    let stem = input.file_stem()
        .and_then(|s| s.to_str())
        .unwrap_or("video");
    let ext = detect_extension(input);
    
    parent.join(format!("{}_silent.{}", stem, ext))
}

pub async fn execute(args: RemoveAudioArgs) -> Result<()> {
    let input = &args.input;
    
    if !input.exists() {
        return Err(format!("Input file not found: {}", input.display()).into());
    }
    
    let output = build_output_path(input, args.output);
    
    if output.exists() {
        return Err(format!("Output file already exists: {}", output.display()).into());
    }
    
    if let Some(parent) = output.parent() {
        fs::create_dir_all(parent)?;
    }
    
    info("Removing audio track...");
    
    let status = Command::new("ffmpeg")
        .args(["-y", "-hide_banner", "-loglevel", "warning"])
        .args(["-i"])
        .arg(input)
        .args(["-an"])
        .args(["-c:v", "copy"])
        .arg(&output)
        .status()?;
    
    if !status.success() {
        if output.exists() {
            let _ = fs::remove_file(&output);
        }
        return Err("FFmpeg remove audio failed".into());
    }
    
    let input_size = fs::metadata(input)?.len();
    let output_size = fs::metadata(&output)?.len();
    let reduction = if input_size > 0 {
        ((input_size as f64 - output_size as f64) / input_size as f64) * 100.0
    } else {
        0.0
    };
    
    println!();
    success("Audio removed successfully!");
    println!("  Output:        {}", output.display());
    println!("  Original size: {} bytes ({:.2} MB)", input_size, input_size as f64 / 1024.0 / 1024.0);
    println!("  New size:      {} bytes ({:.2} MB)", output_size, output_size as f64 / 1024.0 / 1024.0);
    println!("  Size reduced:  {:.1}%", reduction);
    
    Ok(())
}
