use clap::{Parser, Subcommand, ValueEnum};
use domain::Role;
use server::{Config, create_user, run, seed};

#[derive(Parser)]
#[command(version, about = "Collection management system server")]
struct Cli {
    #[command(subcommand)]
    command: Option<Command>,
    #[command(flatten)]
    config: Config,
}

#[derive(Subcommand)]
enum Command {
    /// Create a user (admin bootstrap).
    CreateUser {
        #[arg(long)]
        email: String,
        #[arg(long, value_enum)]
        role: RoleArg,
    },
    /// Seed the baseline Spectrum cataloguing vocabularies + field definitions (idempotent).
    Seed,
}

#[derive(Clone, Copy, ValueEnum)]
enum RoleArg {
    Admin,
    Editor,
}

impl From<RoleArg> for Role {
    fn from(r: RoleArg) -> Self {
        match r {
            RoleArg::Admin => Role::Admin,
            RoleArg::Editor => Role::Editor,
        }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Load a .env file (if present) so the binary picks up config when run directly,
    // not only via `just` (which uses `set dotenv-load`). A missing .env is fine.
    dotenvy::dotenv().ok();

    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();

    let cli = Cli::parse();

    match cli.command {
        None => run(cli.config).await,
        Some(Command::CreateUser { email, role }) => {
            create_user(&cli.config.database_url, &email, role.into()).await
        }
        Some(Command::Seed) => seed(&cli.config.database_url).await,
    }
}
