import { DevelopmentStore, Feature, TestCase, TDDConfig } from './types.js';
import { ConfigManager } from '../../config/config-manager.js';

export class DevelopmentDataStore {
  private store: DevelopmentStore;
  private configManager: ConfigManager;
  private readonly MODULE_NAME = 'development';
  private readonly DATA_FILE = 'development.json';

  constructor(configManager?: ConfigManager) {
    this.configManager = configManager || new ConfigManager();
    this.store = {
      features: {},
      sessions: {},
      config: {
        enforceTestFirst: true,
        minimumTestCoverage: 80,
        requireTestsBeforeImplementation: true,
        autoGenerateTestTemplates: true,
      },
    };
  }

  async init(): Promise<void> {
    const storageManager = this.configManager.getStorageManager();
    await storageManager.ensureStorageDirectories();
    
    const data = await storageManager.loadData(this.MODULE_NAME, this.DATA_FILE);
    if (data) {
      this.store = data;
    } else {
      // If file doesn't exist, create it with default store
      await this.save();
    }
  }

  async save(): Promise<void> {
    const storageManager = this.configManager.getStorageManager();
    await storageManager.saveData(this.MODULE_NAME, this.DATA_FILE, this.store);
  }

  createFeature(name: string, description: string): Feature {
    const feature: Feature = {
      id: this.generateId(),
      name,
      description,
      testCases: [],
      implementationStatus: 'not-started',
      testCoverage: 0,
      createdAt: new Date(),
      updatedAt: new Date(),
    };

    this.store.features[feature.id] = feature;
    return feature;
  }

  getFeature(nameOrId: string): Feature | undefined {
    if (this.store.features[nameOrId]) {
      return this.store.features[nameOrId];
    }
    
    return Object.values(this.store.features).find(f => f.name === nameOrId);
  }

  addTestCase(featureNameOrId: string, testCase: Omit<TestCase, 'id' | 'createdAt' | 'updatedAt'>): TestCase | null {
    const feature = this.getFeature(featureNameOrId);
    if (!feature) {
      return null;
    }

    const newTest: TestCase = {
      ...testCase,
      id: this.generateId(),
      createdAt: new Date(),
      updatedAt: new Date(),
    };

    feature.testCases.push(newTest);
    feature.updatedAt = new Date();
    this.updateTestCoverage(feature);
    
    return newTest;
  }

  updateTestStatus(featureNameOrId: string, testId: string, status: TestCase['status']): boolean {
    const feature = this.getFeature(featureNameOrId);
    if (!feature) {
      return false;
    }

    const test = feature.testCases.find(t => t.id === testId);
    if (!test) {
      return false;
    }

    test.status = status;
    test.updatedAt = new Date();
    feature.updatedAt = new Date();
    this.updateTestCoverage(feature);
    
    return true;
  }

  getConfig(): TDDConfig {
    return this.store.config;
  }

  updateConfig(updates: Partial<TDDConfig>): void {
    Object.assign(this.store.config, updates);
  }

  private updateTestCoverage(feature: Feature): void {
    const totalTests = feature.testCases.length;
    const passingTests = feature.testCases.filter(t => t.status === 'passing').length;
    
    feature.testCoverage = totalTests > 0 ? (passingTests / totalTests) * 100 : 0;
  }

  generateTestTemplate(featureName: string, testName: string, language: string = 'typescript'): string {
    const templates: Record<string, string> = {
      typescript: `
describe('${featureName}', () => {
  it('${testName}', () => {
    // Arrange
    // TODO: Set up test data and dependencies
    
    // Act
    // TODO: Execute the code being tested
    
    // Assert
    // TODO: Verify the expected outcome
    expect(result).toBe(expected);
  });
});`,
      javascript: `
describe('${featureName}', () => {
  it('${testName}', () => {
    // Arrange
    // TODO: Set up test data and dependencies
    
    // Act
    // TODO: Execute the code being tested
    
    // Assert
    // TODO: Verify the expected outcome
    expect(result).toBe(expected);
  });
});`,
      python: `
import unittest

class Test${featureName.replace(/\s+/g, '')}(unittest.TestCase):
    def test_${testName.toLowerCase().replace(/\s+/g, '_')}(self):
        # Arrange
        # TODO: Set up test data and dependencies
        
        # Act
        # TODO: Execute the code being tested
        
        # Assert
        # TODO: Verify the expected outcome
        self.assertEqual(result, expected)`,
    };

    return templates[language] || templates.typescript;
  }

  private generateId(): string {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }
}