/**
 * E2E Test: Enhanced i18n Generator
 *
 * This test verifies that the enhanced i18n generator actually writes
 * all expected internationalization files to disk with correct content.
 */

import * as fs from 'fs';
import * as path from 'path';
import '../generators/index'; // Ensure all generators are registered
import { GenerationOrchestrator } from '../generators/generation-orchestrator';
import { Workflow } from '../types/workflow';

describe('E2E: Enhanced i18n Generator', () => {
  const testOutputDir = path.join(__dirname, '../../.e2e-output/enhanced-i18n');
  let orchestrator: GenerationOrchestrator;

  beforeEach(() => {
    // Clean up test directory before each test
    if (fs.existsSync(testOutputDir)) {
      fs.rmSync(testOutputDir, { recursive: true, force: true });
    }

    orchestrator = new GenerationOrchestrator();
  });

  afterEach(() => {
    // Clean up test directory after each test
    if (fs.existsSync(testOutputDir)) {
      fs.rmSync(testOutputDir, { recursive: true, force: true });
    }
  });

  it('should generate all i18n files for complete i18n schema', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'e2e-i18n-test',
        version: '1.0.0',
        name: 'E2E i18n Test',
        description: 'Testing enhanced i18n generator E2E',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
          config: { port: 5173 },
        },
        api: {
          type: 'backend',
          technology: 'typescript/express',
          config: { port: 3000 },
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'es', 'fr'],
        fallback_strategy: 'cascade',
        formatting: {
          dates: 'locale_specific',
          numbers: 'locale_specific',
          currency: 'locale_specific',
        },
        translation_management: {
          provider: 'lokalise',
          auto_sync: true,
        },
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    // Generate code
    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Verify files were generated
    expect(_result.files.length).toBeGreaterThan(0);

    // Define expected files
    const expectedFiles = [
      'web/src/config/i18n.ts',
      'web/src/hooks/useTranslation.ts',
      'web/src/components/LocaleSwitcher.tsx',
      'web/src/utils/formatting.ts',
      'web/src/types/translations.ts',
      'api/src/config/i18n.ts',
      'api/src/middleware/locale-detection.ts',
      'api/src/utils/translations.ts',
      'api/scripts/sync-translations.ts',
    ];

    // Verify each expected file exists
    expectedFiles.forEach(expectedFile => {
      const fullPath = path.join(testOutputDir, expectedFile);
      expect(fs.existsSync(fullPath)).toBe(true);
    });

    // Verify translation files for each locale
    const locales = ['en', 'es', 'fr'];
    const translationTypes = ['common.json', 'errors.json', 'validation.json'];

    locales.forEach(locale => {
      translationTypes.forEach(type => {
        const fullPath = path.join(testOutputDir, 'web/public/locales', locale, type);
        expect(fs.existsSync(fullPath)).toBe(true);
      });
    });
  });

  it('should generate frontend i18n config with correct locales', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'frontend-i18n-test',
        version: '1.0.0',
        name: 'Frontend i18n Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en-US',
        supported_locales: ['en-US', 'es-MX', 'fr-CA'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read the generated config
    const configPath = path.join(testOutputDir, 'web/src/config/i18n.ts');
    expect(fs.existsSync(configPath)).toBe(true);

    const config = fs.readFileSync(configPath, 'utf-8');

    // Verify configuration
    expect(config).toContain("defaultLocale = 'en-US'");
    expect(config).toContain('en-US');
    expect(config).toContain('es-MX');
    expect(config).toContain('fr-CA');
    expect(config).toContain('i18next');
  });

  it('should generate translation hook with formatting functions', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'hook-test',
        version: '1.0.0',
        name: 'Hook Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'de'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read the hook file
    const hookPath = path.join(testOutputDir, 'web/src/hooks/useTranslation.ts');
    expect(fs.existsSync(hookPath)).toBe(true);

    const hook = fs.readFileSync(hookPath, 'utf-8');

    // Verify hook exports
    expect(hook).toContain('useTranslation');
    expect(hook).toContain('useFormattedDate');
    expect(hook).toContain('useFormattedNumber');
    expect(hook).toContain('formatDate');
    expect(hook).toContain('formatRelative');
    expect(hook).toContain('formatCurrency');
    expect(hook).toContain('formatPercent');
  });

  it('should generate locale switcher component', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'switcher-test',
        version: '1.0.0',
        name: 'Switcher Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'es', 'fr', 'de'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read the switcher component
    const switcherPath = path.join(testOutputDir, 'web/src/components/LocaleSwitcher.tsx');
    expect(fs.existsSync(switcherPath)).toBe(true);

    const switcher = fs.readFileSync(switcherPath, 'utf-8');

    // Verify component
    expect(switcher).toContain('LocaleSwitcher');
    expect(switcher).toContain('localeNames');
    expect(switcher).toContain('English');
    expect(switcher).toContain('Español');
    expect(switcher).toContain('Français');
    expect(switcher).toContain('Deutsch');
  });

  it('should generate backend locale detection middleware', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'middleware-test',
        version: '1.0.0',
        name: 'Middleware Test',
        description: 'Test workflow',
      },
      stack: {
        api: {
          type: 'backend',
          technology: 'typescript/express',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'es'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read the middleware
    const middlewarePath = path.join(testOutputDir, 'api/src/middleware/locale-detection.ts');
    expect(fs.existsSync(middlewarePath)).toBe(true);

    const middleware = fs.readFileSync(middlewarePath, 'utf-8');

    // Verify middleware
    expect(middleware).toContain('localeDetection');
    expect(middleware).toContain('accept-language');
    expect(middleware).toContain('req.query.lang');
    expect(middleware).toContain('req.cookies?.locale');
    expect(middleware).toContain('.locale =');
  });

  it('should generate translation files with correct structure', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'translations-test',
        version: '1.0.0',
        name: 'Translations Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'es'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read common translations
    const commonEnPath = path.join(testOutputDir, 'web/public/locales/en/common.json');
    expect(fs.existsSync(commonEnPath)).toBe(true);

    const commonEn = JSON.parse(fs.readFileSync(commonEnPath, 'utf-8'));
    expect(commonEn.welcome).toBe('Welcome');
    expect(commonEn.loading).toBe('Loading...');
    expect(commonEn.save).toBe('Save');

    // Read error translations
    const errorsEnPath = path.join(testOutputDir, 'web/public/locales/en/errors.json');
    expect(fs.existsSync(errorsEnPath)).toBe(true);

    const errorsEn = JSON.parse(fs.readFileSync(errorsEnPath, 'utf-8'));
    expect(errorsEn.general_error).toContain('error occurred');
    expect(errorsEn.network_error).toContain('Network error');

    // Read validation translations
    const validationEnPath = path.join(testOutputDir, 'web/public/locales/en/validation.json');
    expect(fs.existsSync(validationEnPath)).toBe(true);

    const validationEn = JSON.parse(fs.readFileSync(validationEnPath, 'utf-8'));
    expect(validationEn.required).toContain('required');
    expect(validationEn.invalid_email).toContain('email');
  });

  it('should generate Lokalise sync script', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'lokalise-test',
        version: '1.0.0',
        name: 'Lokalise Test',
        description: 'Test workflow',
      },
      stack: {
        api: {
          type: 'backend',
          technology: 'typescript/express',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'fr'],
        translation_management: {
          provider: 'lokalise',
          auto_sync: true,
        },
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read the sync script
    const syncPath = path.join(testOutputDir, 'api/scripts/sync-translations.ts');
    expect(fs.existsSync(syncPath)).toBe(true);

    const sync = fs.readFileSync(syncPath, 'utf-8');

    // Verify sync script
    expect(sync).toContain('LokaliseApi');
    expect(sync).toContain('LOKALISE_PROJECT_ID');
    expect(sync).toContain('LOKALISE_API_KEY');
    expect(sync).toContain('syncTranslations');
  });

  it('should use cascade fallback strategy', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'cascade-test',
        version: '1.0.0',
        name: 'Cascade Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'es', 'fr'],
        fallback_strategy: 'cascade',
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read config
    const configPath = path.join(testOutputDir, 'web/src/config/i18n.ts');
    const config = fs.readFileSync(configPath, 'utf-8');

    expect(config).toContain('fallbackLng: supportedLocales');
  });

  it('should use ISO date formatting when specified', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'iso-date-test',
        version: '1.0.0',
        name: 'ISO Date Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en'],
        formatting: {
          dates: 'iso',
        },
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read hook
    const hookPath = path.join(testOutputDir, 'web/src/hooks/useTranslation.ts');
    const hook = fs.readFileSync(hookPath, 'utf-8');

    expect(hook).toContain('toISOString');
  });

  it('should generate formatting utilities', async () => {
    const workflow: Workflow = {
      workflow: {
        id: 'formatting-test',
        version: '1.0.0',
        name: 'Formatting Test',
        description: 'Test workflow',
      },
      stack: {
        web: {
          type: 'frontend',
          technology: 'react',
        },
      },
      i18n: {
        default_locale: 'en',
        supported_locales: ['en', 'ja'],
      },
      stages: {
        local: {
          infrastructure: {
            databases: { primary: 'postgresql://localhost/test' },
            services: {},
          },
        },
      },
    };

    const _result = await orchestrator.generate(workflow, {
      outputDirectory: testOutputDir,
      dryRun: false,
      verbose: false,
    });

    // Read formatting utils
    const utilsPath = path.join(testOutputDir, 'web/src/utils/formatting.ts');
    expect(fs.existsSync(utilsPath)).toBe(true);

    const utils = fs.readFileSync(utilsPath, 'utf-8');

    expect(utils).toContain('formatDate');
    expect(utils).toContain('formatNumber');
    expect(utils).toContain('formatCurrency');
    expect(utils).toContain('formatFileSize');
  });
});
