import { describe, it, expect } from 'vitest';
import type { PromptScriptConfig, TargetEntry, TargetConfig } from '../types/config.js';

describe('PromptScriptConfig', () => {
  describe('base config', () => {
    it('should accept minimal valid config', () => {
      const config: PromptScriptConfig = {
        id: 'test-project',
        syntax: '1.1.0',
        targets: ['github'],
      };

      expect(config.id).toBe('test-project');
      expect(config.syntax).toBe('1.1.0');
    });

    it('should accept full config with description', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        description: 'Test project',
        registry: { path: './registry' },
        targets: ['github'],
      };

      expect(config.description).toBe('Test project');
    });
  });

  describe('extends', () => {
    it('should accept extends field', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        extends: '../base-config.yaml',
        registry: {},
        targets: [],
      };

      expect(config.extends).toBe('../base-config.yaml');
    });
  });

  describe('input section', () => {
    it('should accept entry file', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {},
        targets: [],
        input: {
          entry: './custom/entry.prs',
        },
      };

      expect(config.input?.entry).toBe('./custom/entry.prs');
    });

    it('should accept include/exclude patterns', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {},
        targets: [],
        input: {
          include: ['src/**/*.prs'],
          exclude: ['**/node_modules/**'],
        },
      };

      expect(config.input?.include).toContain('src/**/*.prs');
      expect(config.input?.exclude).toContain('**/node_modules/**');
    });
  });

  describe('registry section', () => {
    it('should accept cache settings', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {
          cache: {
            enabled: true,
            ttl: 300000,
          },
        },
        targets: [],
      };

      expect(config.registry?.cache?.enabled).toBe(true);
      expect(config.registry?.cache?.ttl).toBe(300000);
    });

    it('should accept auth settings with token', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {
          url: 'https://registry.example.com',
          auth: {
            type: 'bearer',
            token: 'secret-token',
          },
        },
        targets: [],
      };

      expect(config.registry?.auth?.type).toBe('bearer');
      expect(config.registry?.auth?.token).toBe('secret-token');
    });

    it('should accept auth settings with env var', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {
          auth: {
            type: 'basic',
            tokenEnvVar: 'REGISTRY_TOKEN',
          },
        },
        targets: [],
      };

      expect(config.registry?.auth?.tokenEnvVar).toBe('REGISTRY_TOKEN');
    });
  });

  describe('watch section', () => {
    it('should accept watch settings', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {},
        targets: [],
        watch: {
          include: ['**/*.prs'],
          exclude: ['**/vendor/**'],
          debounce: 500,
          clearScreen: true,
        },
      };

      expect(config.watch?.include).toContain('**/*.prs');
      expect(config.watch?.debounce).toBe(500);
      expect(config.watch?.clearScreen).toBe(true);
    });
  });

  describe('output section', () => {
    it('should accept output settings', () => {
      const config: PromptScriptConfig = {
        id: 'test',
        syntax: '1.1.0',
        registry: {},
        targets: [],
        output: {
          baseDir: './dist',
          header: '# Auto-generated by PromptScript',
          overwrite: true,
        },
      };

      expect(config.output?.baseDir).toBe('./dist');
      expect(config.output?.header).toContain('Auto-generated');
      expect(config.output?.overwrite).toBe(true);
    });
  });

  describe('targets section', () => {
    it('should accept string targets', () => {
      const targets: TargetEntry[] = ['github', 'claude', 'cursor'];

      expect(targets).toContain('github');
    });

    it('should accept object targets with config', () => {
      const config: TargetConfig = {
        enabled: true,
        output: './custom/output.md',
        convention: 'markdown',
        version: 'legacy',
      };

      const targets: TargetEntry[] = [{ github: config }];

      expect((targets[0] as { github: TargetConfig }).github.output).toBe('./custom/output.md');
    });

    it('should accept mixed targets', () => {
      const targets: TargetEntry[] = ['github', { claude: { convention: 'xml' } }, 'cursor'];

      expect(targets).toHaveLength(3);
    });
  });
});
