/**
 * Init command - Initialize a .principal-views folder with template files and linting setup
 */
import { Command } from 'commander';
import { existsSync, mkdirSync, writeFileSync, readFileSync, chmodSync } from 'node:fs';
import { join } from 'node:path';
import { execSync } from 'node:child_process';
import chalk from 'chalk';
const TEMPLATE_CANVAS = {
    nodes: [],
    edges: [],
};
const TEMPLATE_PRIVURC = `# Principal View Configuration Lint Rules
# See: https://github.com/principal-ai/principal-view

# File patterns to include
include:
  - ".principal-views/**/*.yaml"
  - ".principal-views/**/*.yml"
  - ".principal-views/**/*.json"

# File patterns to exclude
exclude:
  - "**/node_modules/**"
  - ".principal-views/library.yaml"

# Path to component library (optional)
library: ".principal-views/library.yaml"

# Rule configuration
# Severity: "off" | "warn" | "error" (or 0 | 1 | 2)
rules:
  # Schema rules - validate structure
  no-unknown-fields: error
  required-metadata: error
  valid-node-types: error
  valid-edge-types: error
  valid-color-format: error

  # Reference rules - check cross-references
  connection-type-references: error
  state-transition-references: error

  # Structure rules - ensure completeness
  minimum-node-sources:
    severity: error
    options:
      minimum: 1
      excludeNodeTypes: []
  orphaned-node-types: error
  orphaned-edge-types: error
  unreachable-states: error
  dead-end-states: error

  # Pattern rules - validate regex patterns
  valid-action-patterns:
    severity: error
    options:
      strictMode: false

  # Library rules - check against component library
  library-node-type-match:
    severity: error
    options:
      allowExtra: true
`;
const HUSKY_PRE_COMMIT = `# Run principal view linting on staged .principal-views files
npx @principal-ai/principal-view-cli lint --quiet
`;
/**
 * Check if we're in a git repository
 */
function isGitRepo() {
    try {
        execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Get the git root directory
 */
function getGitRoot() {
    try {
        return execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
    }
    catch {
        return null;
    }
}
/**
 * Check if husky is already installed
 */
function isHuskyInstalled(gitRoot) {
    return existsSync(join(gitRoot, '.husky'));
}
/**
 * Detect package manager
 */
function detectPackageManager() {
    if (existsSync('bun.lockb'))
        return 'bun';
    if (existsSync('pnpm-lock.yaml'))
        return 'pnpm';
    if (existsSync('yarn.lock'))
        return 'yarn';
    return 'npm';
}
export function createInitCommand() {
    const command = new Command('init');
    command
        .description('Initialize a .principal-views folder with template files and linting setup')
        .option('-f, --force', 'Overwrite existing files')
        .option('-n, --name <name>', 'Name for the canvas file', 'architecture')
        .option('--no-husky', 'Skip Husky pre-commit hook setup')
        .option('--no-lint-config', 'Skip .privurc.yaml creation')
        .action(async (options) => {
        try {
            const cwd = process.cwd();
            const principalViewsDir = join(cwd, '.principal-views');
            const canvasFile = join(principalViewsDir, `${options.name}.canvas`);
            const libraryFile = join(principalViewsDir, 'library.yaml');
            const privurcFile = join(cwd, '.privurc.yaml');
            // Check if .principal-views directory exists
            if (!existsSync(principalViewsDir)) {
                mkdirSync(principalViewsDir, { recursive: true });
                console.log(chalk.green(`Created directory: .principal-views/`));
            }
            // Create canvas file
            if (existsSync(canvasFile) && !options.force) {
                console.log(chalk.yellow(`Canvas file already exists: .principal-views/${options.name}.canvas`));
            }
            else {
                writeFileSync(canvasFile, JSON.stringify(TEMPLATE_CANVAS, null, 2));
                console.log(chalk.green(`Created canvas file: .principal-views/${options.name}.canvas`));
            }
            // Create library file
            if (existsSync(libraryFile) && !options.force) {
                console.log(chalk.yellow(`Library file already exists: .principal-views/library.yaml`));
            }
            else {
                const libraryYaml = `version: "1.0.0"
name: "Component Library"

nodeComponents: {}

edgeComponents: {}
`;
                writeFileSync(libraryFile, libraryYaml);
                console.log(chalk.green(`Created library file: .principal-views/library.yaml`));
            }
            // Create .privurc.yaml config file
            if (options.lintConfig !== false) {
                if (existsSync(privurcFile) && !options.force) {
                    console.log(chalk.yellow(`Config file already exists: .privurc.yaml`));
                }
                else {
                    writeFileSync(privurcFile, TEMPLATE_PRIVURC);
                    console.log(chalk.green(`Created lint config: .privurc.yaml`));
                }
            }
            // Set up Husky pre-commit hook
            let huskySetup = false;
            if (options.husky !== false) {
                if (!isGitRepo()) {
                    console.log(chalk.yellow(`Skipping Husky setup: not a git repository`));
                }
                else {
                    const gitRoot = getGitRoot();
                    if (!gitRoot) {
                        console.log(chalk.yellow(`Skipping Husky setup: could not find git root`));
                    }
                    else {
                        const huskyDir = join(gitRoot, '.husky');
                        const preCommitFile = join(huskyDir, 'pre-commit');
                        if (isHuskyInstalled(gitRoot)) {
                            // Husky is already installed, just add/update pre-commit hook
                            if (existsSync(preCommitFile)) {
                                // Check if our hook is already in the file
                                const existingContent = readFileSync(preCommitFile, 'utf8');
                                if (existingContent.includes('principal-view-cli lint')) {
                                    console.log(chalk.yellow(`Husky pre-commit hook already includes principal view linting`));
                                }
                                else {
                                    // Append our lint command to existing pre-commit
                                    const updatedContent = existingContent.trimEnd() +
                                        '\n\n# Run principal view linting\nnpx @principal-ai/principal-view-cli lint --quiet\n';
                                    writeFileSync(preCommitFile, updatedContent);
                                    console.log(chalk.green(`Updated Husky pre-commit hook with principal view linting`));
                                    huskySetup = true;
                                }
                            }
                            else {
                                // Create new pre-commit hook
                                writeFileSync(preCommitFile, HUSKY_PRE_COMMIT);
                                chmodSync(preCommitFile, '755');
                                console.log(chalk.green(`Created Husky pre-commit hook`));
                                huskySetup = true;
                            }
                        }
                        else {
                            // Husky is not installed, try to install it
                            const pm = detectPackageManager();
                            const packageJsonPath = join(gitRoot, 'package.json');
                            if (!existsSync(packageJsonPath)) {
                                console.log(chalk.yellow(`Skipping Husky setup: no package.json found`));
                            }
                            else {
                                console.log(chalk.dim(`Installing Husky...`));
                                try {
                                    // Install husky as dev dependency
                                    const installCmd = {
                                        npm: 'npm install --save-dev husky',
                                        yarn: 'yarn add --dev husky',
                                        pnpm: 'pnpm add --save-dev husky',
                                        bun: 'bun add --dev husky',
                                    }[pm];
                                    execSync(installCmd, { stdio: 'inherit', cwd: gitRoot });
                                    // Initialize husky
                                    execSync('npx husky init', { stdio: 'inherit', cwd: gitRoot });
                                    // Write our pre-commit hook
                                    writeFileSync(preCommitFile, HUSKY_PRE_COMMIT);
                                    chmodSync(preCommitFile, '755');
                                    console.log(chalk.green(`Installed Husky and created pre-commit hook`));
                                    huskySetup = true;
                                }
                                catch (installError) {
                                    console.log(chalk.yellow(`Could not install Husky automatically: ${installError.message}`));
                                    console.log(chalk.dim(`  You can install it manually: ${pm} add --dev husky && npx husky init`));
                                }
                            }
                        }
                    }
                }
            }
            console.log('');
            console.log(chalk.bold('Setup complete!'));
            console.log('');
            console.log(chalk.bold('Files created:'));
            console.log(`  • ${chalk.cyan('.principal-views/library.yaml')} - Component library definitions`);
            console.log(`  • ${chalk.cyan(`.principal-views/${options.name}.canvas`)} - Graph canvas file`);
            if (options.lintConfig !== false) {
                console.log(`  • ${chalk.cyan('.privurc.yaml')} - Lint configuration`);
            }
            if (huskySetup) {
                console.log(`  • ${chalk.cyan('.husky/pre-commit')} - Pre-commit hook`);
            }
            console.log('');
            console.log(chalk.bold('Next steps:'));
            console.log(`  1. Define components in ${chalk.cyan('.principal-views/library.yaml')}`);
            console.log(`  2. Build your graph in ${chalk.cyan(`.principal-views/${options.name}.canvas`)}`);
            console.log(`  3. Run ${chalk.cyan('npx @principal-ai/principal-view-cli lint')} to validate your configuration`);
            if (huskySetup) {
                console.log(`  4. Commits will now automatically lint .principal-views files`);
            }
            console.log('');
            console.log(chalk.bold('Commands:'));
            console.log(`  • ${chalk.cyan('npx @principal-ai/principal-view-cli lint')} - Lint configuration files`);
            console.log(`  • ${chalk.cyan('npx @principal-ai/principal-view-cli lint --json')} - Output lint results as JSON`);
            console.log(`  • ${chalk.cyan('npx @principal-ai/principal-view-cli validate')} - Validate canvas files`);
            console.log(`  • ${chalk.cyan('npx @principal-ai/principal-view-cli doctor')} - Check project setup`);
        }
        catch (error) {
            console.error(chalk.red('Error:'), error.message);
            process.exit(1);
        }
    });
    return command;
}
