use clap::{Args, Parser, Subcommand};

#[derive(Debug, Parser)]
#[command(name = "crust")]
#[command(about = "CLI for crust workspace and scaffolding operations")]
pub struct Cli {
	#[command(subcommand)]
	pub command: Commands,
}

#[derive(Debug, Subcommand)]
pub enum Commands {
	/// Initialize a project in the current directory or inside a new folder
	Init(InitArgs),
	/// Add a new bounded context to the current project
	New(NewArgs),
	/// Add an artifact to a bounded context
	Add(AddArgs),
	/// Create an infrastructure implementation for an existing domain port
	Impl(ImplArgs),
}

#[derive(Debug, Args)]
pub struct InitArgs {
	/// Optional project name. If omitted, uses the current directory name.
	pub name: Option<String>,
}

#[derive(Debug, Args)]
pub struct NewArgs {
	/// Bounded context names to create
	#[arg(required = true)]
	pub bounded_contexts: Vec<String>,
}

#[derive(Debug, Args)]
pub struct AddArgs {
	#[command(subcommand)]
	pub kind: AddSubcommand,
}

#[derive(Debug, Subcommand)]
pub enum AddSubcommand {
	/// Create query use-case artifact(s): add query <name> [<name2> ...] in <context>
	Query(AddMultipleTargetArgs),
	/// Create command use-case artifact(s): add command <name> [<name2> ...] in <context>
	Command(AddMultipleTargetArgs),
	/// Create infrastructure technology folder(s): add tech <name> [<name2> ...] in <context>
	Tech(AddMultipleTargetArgs),
	/// Create domain feature folder(s): add domain <name> [<name2> ...] in <context>
	Domain(AddMultipleTargetArgs),
	/// Create domain port file: add port <domain> <port_name> in <context> [with <tech>]
	Port(AddPortTargetArgs),
}

#[derive(Debug, Args)]
pub struct AddTargetArgs {
	/// Artifact/domain/tech name to create
	pub name: String,

	/// Natural-language separator keyword
	#[arg(value_parser = ["in"])]
	pub in_keyword: String,

	/// Target bounded context name
	pub bounded_context: String,
}

#[derive(Debug, Args)]
pub struct AddMultipleTargetArgs {
	/// Names and context: <name> [<name2> ...] in <context>
	pub args: Vec<String>,
}

#[derive(Debug, Args)]
pub struct AddPortTargetArgs {
	/// Domain feature folder name
	pub domain_feature_name: String,

	/// Domain port file name
	pub port_name: String,

	/// Natural-language separator keyword
	#[arg(value_parser = ["in"])]
	pub in_keyword: String,

	/// Target bounded context name
	pub bounded_context: String,

	/// Optional keyword to trigger implementation scaffolding
	#[arg(value_parser = ["with"])]
	pub with_keyword: Option<String>,

	/// Optional infrastructure tech (e.g. postgres)
	pub tech_name: Option<String>,
}


#[derive(Debug, Args)]
pub struct ImplArgs {
	/// Domain feature folder name
	pub domain_feature_name: String,

	/// Domain port file name
	pub port_name: String,

	/// Natural-language separator keyword
	#[arg(value_parser = ["for"])]
	pub for_keyword: String,

	/// Infrastructure tech folder name (e.g. postgre)
	pub tech_name: String,

	/// Natural-language separator keyword
	#[arg(value_parser = ["in"])]
	pub in_keyword: String,

	/// Target bounded context name
	pub bounded_context: String,
}
