mod commands;
mod templates;

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "kit")]
#[command(about = "A CLI for scaffolding Kit web applications", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Create a new Kit project
    New {
        /// The name of the project to create
        name: Option<String>,

        /// Skip all prompts and use defaults
        #[arg(long)]
        no_interaction: bool,

        /// Skip git initialization
        #[arg(long)]
        no_git: bool,
    },
    /// Start the development servers (backend + frontend)
    Serve {
        /// Backend port (default: 8000)
        #[arg(long, short = 'p', default_value = "8000")]
        port: u16,

        /// Frontend port (default: 5173)
        #[arg(long, default_value = "5173")]
        frontend_port: u16,

        /// Only start backend server
        #[arg(long)]
        backend_only: bool,

        /// Only start frontend server
        #[arg(long)]
        frontend_only: bool,

        /// Skip TypeScript type generation
        #[arg(long)]
        skip_types: bool,
    },
    /// Generate TypeScript types from Rust InertiaProps structs
    GenerateTypes {
        /// Output file path (default: frontend/src/types/inertia-props.ts)
        #[arg(long, short = 'o')]
        output: Option<String>,

        /// Watch for changes and regenerate
        #[arg(long, short = 'w')]
        watch: bool,
    },
    /// Generate a new middleware
    #[command(name = "make:middleware")]
    MakeMiddleware {
        /// Name of the middleware (e.g., Auth, RateLimit)
        name: String,
    },
    /// Generate a new controller
    #[command(name = "make:controller")]
    MakeController {
        /// Name of the controller (e.g., users, user_profile)
        name: String,
    },
    /// Generate a new action
    #[command(name = "make:action")]
    MakeAction {
        /// Name of the action (e.g., AddTodo, CreateUser)
        name: String,
    },
    /// Generate a new database migration
    #[command(name = "make:migration")]
    MakeMigration {
        /// Name of the migration (e.g., create_users_table, add_email_to_users)
        name: String,
    },
    /// Run all pending database migrations
    Migrate,
    /// Rollback the last database migration(s)
    #[command(name = "migrate:rollback")]
    MigrateRollback {
        /// Number of migrations to rollback
        #[arg(long, default_value = "1")]
        step: u32,
    },
    /// Show the status of all migrations
    #[command(name = "migrate:status")]
    MigrateStatus,
    /// Drop all tables and re-run all migrations
    #[command(name = "migrate:fresh")]
    MigrateFresh,
    /// Sync database schema to entity files (runs migrations + generates entities)
    #[command(name = "db:sync")]
    DbSync {
        /// Skip running migrations before sync
        #[arg(long)]
        skip_migrations: bool,
    },
}

fn main() {
    let cli = Cli::parse();

    match cli.command {
        Commands::New {
            name,
            no_interaction,
            no_git,
        } => {
            commands::new::run(name, no_interaction, no_git);
        }
        Commands::Serve {
            port,
            frontend_port,
            backend_only,
            frontend_only,
            skip_types,
        } => {
            commands::serve::run(port, frontend_port, backend_only, frontend_only, skip_types);
        }
        Commands::GenerateTypes { output, watch } => {
            commands::generate_types::run(output, watch);
        }
        Commands::MakeMiddleware { name } => {
            commands::make_middleware::run(name);
        }
        Commands::MakeController { name } => {
            commands::make_controller::run(name);
        }
        Commands::MakeAction { name } => {
            commands::make_action::run(name);
        }
        Commands::MakeMigration { name } => {
            commands::make_migration::run(name);
        }
        Commands::Migrate => {
            commands::migrate::run();
        }
        Commands::MigrateRollback { step } => {
            commands::migrate_rollback::run(step);
        }
        Commands::MigrateStatus => {
            commands::migrate_status::run();
        }
        Commands::MigrateFresh => {
            commands::migrate_fresh::run();
        }
        Commands::DbSync { skip_migrations } => {
            commands::db_sync::run(skip_migrations);
        }
    }
}
