use lofty::{prelude::*, probe::Probe};
use std::{
    fs::{self, create_dir_all},
    path::Path,
};

use crate::{SafeName, sanitize};

pub fn import_file(file: &Path, timbre_dir: &Path) {
    let tagged = Probe::open(&file)
        .expect("i couldn't open this file :(\n")
        .read()
        .expect("i couldn't read this file's tags :(\n");
    match tagged.primary_tag() {
        Some(tag) => {
            let track = tag.track();
            let artist = match tag.artist() {
                None => SafeName::Empty,
                Some(a) => sanitize(&a),
            };
            let album = match tag.album() {
                None => None,
                Some(a) => Some(sanitize(&a)),
            };
            let title = match tag.title() {
                None => SafeName::Empty,
                Some(t) => sanitize(&t),
            };

            if matches!(artist, SafeName::Malicious)
                || matches!(title, SafeName::Malicious)
                || matches!(album, Some(SafeName::Malicious))
            {
                println!(
                    "hey, help! i just found this file: {}\nit seems to be trying to do something bad and hurt your computer!\ni'm moving it to a Quarantine folder for you to check\nyou should probably check the source of it.\ntip: upload it to https://virustotal.com\n",
                    file.display()
                );

                create_dir_all(&timbre_dir.join("Quarantine")).expect("i can't create the Quarantine folder, could be something normal, potentially malware :(\nbe careful with the file! it's still in the Import folder.\ntip: upload it to https://virustotal.com\n");
                fs::rename(&file, &timbre_dir.join("Quarantine").join(file.file_name().expect("no filename??\n")))
                                .expect("i couldn't move this file :(, still in the Import folder, be careful!\ntip: upload it to https://virustotal.com\n");
                return;
            }

            let (SafeName::Ok(artist), SafeName::Ok(title)) = (artist, title) else {
                let unid = timbre_dir.join("Unidentified");
                fs::rename(&file, unid.join(file.file_name().unwrap()))
                                .expect("i couldn't move an Unidentified file to a folder :(\nis the folder missing? try timbre repair!\n");
                return;
            };
            let ext = file.extension().and_then(|e| e.to_str()).unwrap_or("");

            let dest = match album {
                Some(SafeName::Ok(album)) => {
                    let filename = match track {
                        Some(n) => format!("{:02} {}.{}", n, title, ext),
                        None => format!("{}.{}", title, ext),
                    };
                    timbre_dir
                        .join("Albums")
                        .join(&artist)
                        .join(&album)
                        .join(filename)
                }
                _ => timbre_dir
                    .join("Singles")
                    .join(&artist)
                    .join(format!("{}.{}", title, ext)),
            };

            if !dest.starts_with(&timbre_dir) {
                println!(
                    "hey, help! i just found this file: {}\nit seems to be trying to do something bad and hurt your computer!\ni'm moving it to a Quarantine folder for you to check\nyou should probably check the source of it.\ntip: upload it to https://virustotal.com\n",
                    file.display()
                );

                create_dir_all(&timbre_dir.join("Quarantine")).expect("i can't create the Quarantine folder, could be something normal, potentially malware :(\nbe careful with the file! it's still in the Import folder.\ntip: upload it to https://virustotal.com\n");
                fs::rename(&file, &timbre_dir.join("Quarantine").join(file.file_name().expect("no filename??\n")))
                                .expect("i couldn't move this file :(, still in the Import folder, be careful!\ntip: upload it to https://virustotal.com\n");
                return;
            }
            if dest.exists() {
                println!("already there, skipping {} :(", file.display());
                return;
            }
            create_dir_all(dest.parent().unwrap())
                .expect("can't create directory to put a file in :(\n");
            fs::rename(&file, &dest).expect("can't move file to directory :(\n");
        }
        None => {
            println!("no tags on {} :(", file.display());
        }
    }
}
