use std::path::PathBuf;

use rinja::Template;
use serde::Deserialize;

use crate::create_file;

pub const MATERIAL_KINDS: &[&str] = &[
	"blazing",
	"bright",
	"dark",
	"dense",
	"energy",
	"frost",
	"lightning",
	"lucid",
	"power",
	"remembrance",
	"serenity",
	"twilight",
];

#[derive(Debug, Deserialize, PartialEq, Eq)]
pub struct MaterialDrops {
	kind: String,
	shard: Vec<EnemyDrop>,
	stone: Vec<EnemyDrop>,
	gem: Vec<EnemyDrop>,
	crystal: Vec<EnemyDrop>,
}

impl MaterialDrops {
	fn drops(&self, kind: &str) -> &[EnemyDrop] {
		match kind {
			"shard" => &self.shard,
			"stone" => &self.stone,
			"gem" => &self.gem,
			"crystal" => &self.crystal,
			_ => &self.shard,
		}
	}
}

#[derive(Debug, Deserialize, PartialEq, Eq)]
pub struct EnemyDrop {
	from: String,
	chance: u8,
}

impl EnemyDrop {
	fn texture(&self) -> String {
		self.from.replace(" ", "_").to_lowercase()
	}
}

#[derive(Template)]
#[template(path = "pages/kh2/drops.html")]
struct DropsTemplate {
	pub drops: Vec<MaterialDrops>,
}

const DROPS_PATH: &str = "./input/kh2/drops";

pub fn init() {
	tracing::info!("Loading enemy drops data from {}", DROPS_PATH);
	let mut drops: Vec<MaterialDrops> = vec![];
	// Loading multiple files into one vector due to the size of each board
	let paths = std::fs::read_dir(DROPS_PATH)
		.unwrap()
		.filter_map(|f| f.ok())
		.map(|f| f.path())
		.filter_map(|p| match p.extension().map_or(false, |e| e == "toml") {
			true => Some(p),
			false => None,
		})
		.collect::<Vec<PathBuf>>();

	for path in paths {
		let drops_str = std::fs::read_to_string(path).unwrap();
		let enemy_drops = toml::from_str::<MaterialDrops>(&drops_str).unwrap();
		drops.push(enemy_drops);
	}
	drops.sort_by(|a, b| a.kind.cmp(&b.kind));

	tracing::info!("Generating the KH2 drops template");
	let drops_template = DropsTemplate { drops };

	create_file("./out/kh2", "drops", drops_template.render().unwrap()).unwrap();
}
