#!/usr/bin/env node
import { Command } from 'commander';
import inquirer from 'inquirer';
import chalk from 'chalk';
import fs from 'fs/promises';
import path from 'path';
{{#if config_file}}
{{#if (eq config_format "yaml")}}
import yaml from 'js-yaml';
{{/if}}
{{/if}}

const program = new Command();

{{#if config_file}}
interface Config {
  {{#each config_fields}}
  {{this.name}}: {{this.ts_type}};
  {{/each}}
}

async function loadConfig(configPath: string): Promise<Config> {
  const content = await fs.readFile(configPath, 'utf-8');
  {{#if (eq config_format "json")}}
  return JSON.parse(content);
  {{else if (eq config_format "yaml")}}
  return yaml.load(content) as Config;
  {{else if (eq config_format "toml")}}
  // Note: Add toml parser dependency
  return {} as Config; // TODO: Parse TOML
  {{/if}}
}
{{/if}}

program
  .name('{{app_name}}')
  .description('{{app_description}}')
  .version('{{app_version}}');

{{#if config_file}}
program
  .option('-c, --config <path>', 'config file path')
  .option('-v, --verbose', 'verbose output', false);
{{/if}}

{{#each commands}}
program
  .command('{{this.name}}')
  .description('{{this.about}}')
  {{#each this.arguments}}
  .argument('{{#if this.required}}<{{this.name}}>{{else}}[{{this.name}}]{{/if}}', '{{this.help}}'{{#if this.default}}, '{{this.default}}'{{/if}})
  {{/each}}
  {{#each this.options}}
  .option('{{#if this.short}}-{{this.short}}, {{/if}}--{{this.long}} <{{this.name}}>', '{{this.help}}'{{#if this.default}}, '{{this.default}}'{{/if}})
  {{/each}}
  .action(async ({{#each this.arguments}}{{this.name}}, {{/each}}options) => {
    try {
      {{#if ../config_file}}
      const config = options.config ? await loadConfig(options.config) : null;
      {{/if}}

      {{#if this.prompts}}
      // Interactive prompts
      const answers = await inquirer.prompt([
        {{#each this.prompts}}
        {
          type: '{{this.type}}',
          name: '{{this.name}}',
          message: '{{this.message}}',
          {{#if this.choices}}
          choices: [{{this.choices}}],
          {{/if}}
        },
        {{/each}}
      ]);
      {{/if}}

      {{#each this.validators}}
      // Validate {{this.field}}
      {{#if (eq this.type "regex")}}
      if (!{{this.pattern}}.test({{this.field}})) {
        throw new Error('{{this.error_message}}');
      }
      {{else if (eq this.type "range")}}
      if ({{this.field}} < {{this.min}} || {{this.field}} > {{this.max}}) {
        throw new Error('{{this.error_message}}');
      }
      {{/if}}
      {{/each}}

      await execute{{pascal_case this.name}}(
        {{#each this.arguments}}{{this.name}}, {{/each}}
        options
      );
    } catch (error) {
      console.error(chalk.red('Error:'), error instanceof Error ? error.message : error);
      process.exit(1);
    }
  });

{{/each}}

{{#each commands}}
async function execute{{pascal_case this.name}}(
  {{#each this.arguments}}
  {{this.name}}: {{this.ts_type}},
  {{/each}}
  options: {
    {{#each this.options}}
    {{this.name}}?: {{#if this.multiple}}{{this.ts_type}}[]{{else}}{{this.ts_type}}{{/if}};
    {{/each}}
  }
): Promise<void> {
  // TODO: Implement {{this.name}} command logic
  console.log(chalk.green('Executing {{this.name}} command'));
  {{#each this.arguments}}
  console.log('  {{this.name}}:', {{this.name}});
  {{/each}}
  {{#each this.options}}
  if (options.{{this.name}}) {
    console.log('  {{this.name}}:', options.{{this.name}});
  }
  {{/each}}
}

{{/each}}

program.parse();
