import { ReportDefinition } from './report-definition.aggregate';
import { ReportType } from '../../value-objects/report-type.enum';
import { OutputFormat } from '../../value-objects/output-format.enum';
import { ReportSchedule } from '../../value-objects/report-schedule.vo';

describe('ReportDefinition Aggregate', () => {
  describe('create', () => {
    it('should create a report definition with required fields', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Test Report',
        reportCode: 'TEST_001',
      });

      expect(definition.reportType).toBe(ReportType.LEADERBOARD_REPORT);
      expect(definition.reportName).toBe('Test Report');
      expect(definition.reportCode).toBe('TEST_001');
      expect(definition.isActive).toBe(true);
      expect(definition.outputFormats).toContain(OutputFormat.EXCEL);
    });

    it('should create a report definition with custom output formats', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.PLANTING_REPORT,
        reportName: 'Planting Report',
        reportCode: 'PLANTING_001',
        outputFormats: [OutputFormat.CSV, OutputFormat.PDF],
      });

      expect(definition.outputFormats).toHaveLength(2);
      expect(definition.outputFormats).toContain(OutputFormat.CSV);
      expect(definition.outputFormats).toContain(OutputFormat.PDF);
    });

    it('should create a report definition with schedule', () => {
      const schedule = ReportSchedule.daily(1, 0);
      const definition = ReportDefinition.create({
        reportType: ReportType.PLANTING_REPORT,
        reportName: 'Daily Planting Report',
        reportCode: 'PLANTING_DAILY',
        schedule,
      });

      expect(definition.schedule).toBeDefined();
      expect(definition.schedule?.enabled).toBe(true);
      expect(definition.isScheduled()).toBe(true);
    });
  });

  describe('invariants', () => {
    it('should require at least one output format', () => {
      expect(() => {
        const def = ReportDefinition.create({
          reportType: ReportType.LEADERBOARD_REPORT,
          reportName: 'Test',
          reportCode: 'TEST',
          outputFormats: [OutputFormat.EXCEL],
        });
        def.removeOutputFormat(OutputFormat.EXCEL);
      }).toThrow('报表定义至少需要支持一种输出格式');
    });
  });

  describe('commands', () => {
    it('should update name', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Original Name',
        reportCode: 'TEST',
      });

      definition.updateName('New Name');
      expect(definition.reportName).toBe('New Name');
    });

    it('should add output format', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Test',
        reportCode: 'TEST',
        outputFormats: [OutputFormat.EXCEL],
      });

      definition.addOutputFormat(OutputFormat.CSV);
      expect(definition.outputFormats).toContain(OutputFormat.CSV);
    });

    it('should not add duplicate output format', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Test',
        reportCode: 'TEST',
        outputFormats: [OutputFormat.EXCEL],
      });

      definition.addOutputFormat(OutputFormat.EXCEL);
      expect(definition.outputFormats.filter(f => f === OutputFormat.EXCEL)).toHaveLength(1);
    });

    it('should activate and deactivate', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Test',
        reportCode: 'TEST',
      });

      definition.deactivate();
      expect(definition.isActive).toBe(false);

      definition.activate();
      expect(definition.isActive).toBe(true);
    });

    it('should mark as generated', () => {
      const definition = ReportDefinition.create({
        reportType: ReportType.LEADERBOARD_REPORT,
        reportName: 'Test',
        reportCode: 'TEST',
      });

      expect(definition.lastGeneratedAt).toBeNull();

      definition.markGenerated();
      expect(definition.lastGeneratedAt).toBeInstanceOf(Date);
    });
  });
});
