import * as path from 'path';
import * as fs from 'fs/promises';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import chalk from 'chalk';
import inquirer from 'inquirer';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export interface CreateSpecOptions {
  name: string;
  type?: 'feature' | 'api' | 'architecture';
  status?: 'draft' | 'review' | 'approved';
  force?: boolean;
  projectRoot?: string;
}

export class CreateSpecCommand {
  async execute(options: CreateSpecOptions): Promise<void> {
    const projectRoot = options.projectRoot || process.cwd();
    const type = options.type || 'feature';
    const status = options.status || 'draft';
    
    // Convert spec name to kebab-case
    const specName = options.name.toLowerCase().replace(/\s+/g, '-');
    const specType = type === 'feature' ? 'features' : type;
    
    // Create specs directory structure
    const specsDir = path.join(projectRoot, 'specs', specType);
    await fs.mkdir(specsDir, { recursive: true });
    
    // Define spec file path
    const specFile = path.join(specsDir, `${specName}.md`);
    
    // Check if spec already exists
    if (!options.force) {
      try {
        await fs.access(specFile);
        console.log(chalk.yellow(`Spec '${specName}' already exists at ${specFile}`));
        console.log(chalk.yellow('Use --force to overwrite'));
        return;
      } catch {
        // File doesn't exist, continue
      }
    } else if (options.force) {
      console.log(chalk.yellow(`Overwriting existing spec: ${specFile}`));
    }
    
    // Create spec content
    const specContent = this.generateSpecContent(specName, type, status);
    
    // Write spec file
    await fs.writeFile(specFile, specContent);
    
    console.log(chalk.green(`✅ Created spec: ${specFile}`));
    console.log('\nNext steps:');
    console.log(chalk.cyan('1. Fill out the specification'));
    console.log(chalk.cyan('2. Get it reviewed and approved'));
    console.log(chalk.cyan(`3. Generate tests: vibe test ${specName}`));
    console.log(chalk.cyan(`4. Implement: vibe create ${specName}`));
  }

  private generateSpecContent(name: string, type: string, status: string): string {
    const title = name.split('-').map(word => 
      word.charAt(0).toUpperCase() + word.slice(1)
    ).join(' ');
    
    const template = `# ${type === 'feature' ? 'Feature' : type === 'api' ? 'API' : 'Architecture'}: ${name}

**Status**: ${status}  
**Created**: ${new Date().toISOString().split('T')[0]}  
**Type**: ${type}

## Overview
<!-- Provide a brief description of what this ${type} does -->

## Motivation
<!-- Why is this ${type} needed? What problem does it solve? -->

## Requirements

### Functional Requirements
<!-- List the functional requirements -->
- [ ] Requirement 1
- [ ] Requirement 2

### Non-Functional Requirements
<!-- List non-functional requirements (performance, security, etc.) -->
- [ ] Performance: ...
- [ ] Security: ...

## Technical Design

### Architecture
<!-- Describe the high-level architecture -->

### API Design
<!-- Define the API interface (if applicable) -->

### Data Model
<!-- Define data structures and models -->

## Implementation Plan

### Phase 1: Foundation
- [ ] Task 1
- [ ] Task 2

### Phase 2: Core Features
- [ ] Task 3
- [ ] Task 4

## Testing Strategy

### Unit Tests
- [ ] Test case 1
- [ ] Test case 2

### Integration Tests
- [ ] Test scenario 1
- [ ] Test scenario 2

## Success Criteria
<!-- How will we know this ${type} is successful? -->
- [ ] Criteria 1
- [ ] Criteria 2

## Dependencies
<!-- List any dependencies on other features or systems -->

## Notes
<!-- Additional notes or considerations -->
`;
    
    return template;
  }

  async interactivePrompt(): Promise<CreateSpecOptions> {
    const answers = await inquirer.prompt([
      {
        type: 'input',
        name: 'name',
        message: 'What should we call this spec?',
        validate: (input: string) => {
          if (!input.trim()) return 'Spec name is required';
          if (!/^[a-zA-Z0-9-\s]+$/.test(input)) {
            return 'Spec name can only contain letters, numbers, hyphens, and spaces';
          }
          return true;
        }
      },
      {
        type: 'list',
        name: 'type',
        message: 'What type of spec?',
        choices: ['feature', 'api', 'architecture'],
        default: 'feature'
      },
      {
        type: 'list',
        name: 'status',
        message: 'Initial status?',
        choices: ['draft', 'review', 'approved'],
        default: 'draft'
      }
    ]);
    
    return answers;
  }
}