use super::RezonCommand;
use crate::error::Error::{self, *};
use crate::tui::clean_console;
use async_trait::async_trait;
use clap::{ArgMatches, Command};
use colorful::{Color, Colorful};
use std::{fs::File, io::Write, path::Path};

pub struct Init {}

#[async_trait]
impl RezonCommand for Init {
	fn cmd() -> clap::Command {
		Command::new("init").about("Initialize Rezon in an existing project!")
	}

	async fn execute(_args: &ArgMatches) -> Result<(), Error> {
		create_rezon_config_file()?;
		Ok(())
	}
}

pub fn create_rezon_config_file() -> Result<(), Error> {
	let file_name = "rezon.toml";
	let file_content = r#"[config]
api_key = "your_api_key_here"

[model]
model_type = "tensorflow-or-pytorch"
model_path = "path/to/model"
parameters = ["name1", "name2", "name3"]
"#;

	let path = Path::new(file_name);
	// try_exists is better than exists because it allows us to propagate any permission errors on
	// the config file
	match path.try_exists() {
		Ok(exists) => {
			if exists {
				return Err(CliError(format!("{file_name} already exists in the current working directory!")));
			}
		}
		Err(e) => {
			return Err(Io {
				path: path.to_path_buf(),
				source: e,
			})
		}
	}

	let mut file = match File::create(path) {
		Ok(file) => file,
		Err(e) => {
			return Err(Io {
				path: path.to_path_buf(),
				source: e,
			})
		}
	};
	if let Err(e) = file.write_all(file_content.as_bytes()) {
		return Err(Io {
			path: path.to_path_buf(),
			source: e,
		});
	};

	clean_console();

	println!(
		"{} Successfuly Initialized {}\n",
		"✓".color(Color::Green),
		"Rezon!".color(Color::Purple1a).bold()
	);
	println!(
		"{}{}{}{}",
		"Next steps:\n".color(Color::White).bold(),
		format!(
			"{} Add your Rezon API key to the newly created {} file\n",
			"➜".color(Color::Purple1a),
			"rezon.toml".color(Color::Purple1a).bold()
		),
		format!("{} Configure your model paths for deployment\n", "➜".color(Color::Purple1a)),
		format!(
			"{} Deploy your model to the cloud with `{} {}`\n",
			"➜".color(Color::Purple1a),
			"rezon".color(Color::Purple1a).bold(),
			"deploy".bold()
		)
	);
	Ok(())
}
