import { describe, expect, it } from 'vitest';

import fixTrackEQ, { DEFAULT_EQ_BANDS } from './fixTrackEQ';

describe('fixTrackEQ', () => {
  it('should return default EQ for null/undefined', () => {
    const result = fixTrackEQ(null);

    expect(result.enabled).toBe(true);
    expect(result.band1.type).toBe('highpass');
    expect(result.band1.enabled).toBe(false);
    expect(result.band6.type).toBe('lowpass');
    expect(result.band6.enabled).toBe(false);
  });

  it('should fix valid 6-band EQ in place', () => {
    const input = {
      enabled: true,
      band1: {
        type: 'highpass',
        enabled: true,
        frequency: 80,
        gain: 0,
        q: 1.0,
      },
      band2: {
        type: 'lowshelf',
        enabled: true,
        frequency: 200,
        gain: 3,
        q: 0.707,
      },
      band3: {
        type: 'peaking',
        enabled: true,
        frequency: 500,
        gain: -2,
        q: 1.5,
      },
      band4: {
        type: 'peaking',
        enabled: true,
        frequency: 1500,
        gain: 4,
        q: 0.5,
      },
      band5: {
        type: 'highshelf',
        enabled: true,
        frequency: 4000,
        gain: 2,
        q: 0.707,
      },
      band6: {
        type: 'lowpass',
        enabled: true,
        frequency: 10000,
        gain: 0,
        q: 0.8,
      },
    };

    const result = fixTrackEQ(input);

    expect(result).toBe(input); // Referential equality
    expect(result.band2.gain).toBe(3);
    expect(result.band3.gain).toBe(-2);
  });

  it('should migrate from old array-based EQ format', () => {
    const oldEQ = [
      { frequency: 200, gain: 3, q: 1.0 },
      { frequency: 500, gain: -2, q: 1.5 },
      { frequency: 1500, gain: 4, q: 0.5 },
      { frequency: 4000, gain: 2, q: 0.8 },
    ];

    const result = fixTrackEQ(oldEQ);

    expect(result.enabled).toBe(true);
    // Old array entries should map to bands 2-5
    expect(result.band2.type).toBe('peaking');
    expect(result.band2.frequency).toBe(200);
    expect(result.band2.gain).toBe(3);
    expect(result.band3.frequency).toBe(500);
    expect(result.band3.gain).toBe(-2);
    expect(result.band4.frequency).toBe(1500);
    expect(result.band5.frequency).toBe(4000);
  });

  it('should migrate from old highPassFilter/lowPassFilter format', () => {
    const oldFormat = {
      highPassFilter: {
        enabled: true,
        frequency: 100,
        q: 1.0,
      },
      lowPassFilter: {
        enabled: true,
        frequency: 8000,
        q: 0.707,
      },
    };

    const result = fixTrackEQ(oldFormat);

    expect(result.band1.type).toBe('highpass');
    expect(result.band1.enabled).toBe(true);
    expect(result.band1.frequency).toBe(100);
    expect(result.band1.q).toBe(1.0);

    expect(result.band6.type).toBe('lowpass');
    expect(result.band6.enabled).toBe(true);
    expect(result.band6.frequency).toBe(8000);
    expect(result.band6.q).toBe(0.707);

    // Cleanup: old properties should be removed
    expect('highPassFilter' in result).toBe(false);
    expect('lowPassFilter' in result).toBe(false);
  });

  it('should migrate from 4-band to 6-band format', () => {
    const oldFormat = {
      enabled: true,
      band1: {
        type: 'highpass',
        enabled: true,
        frequency: 60,
        gain: 0,
        q: 0.707,
      },
      band2: {
        type: 'peaking',
        enabled: true,
        frequency: 200,
        gain: 2,
        q: 1.0,
      },
      band3: {
        type: 'peaking',
        enabled: true,
        frequency: 1000,
        gain: -3,
        q: 1.5,
      },
      band4: {
        type: 'lowpass',
        enabled: true,
        frequency: 8000,
        gain: 0,
        q: 0.707,
      },
      // band5 and band6 missing
    };

    const result = fixTrackEQ(oldFormat);

    expect(result.band1.frequency).toBe(60);
    expect(result.band2.frequency).toBe(200);
    expect(result.band3.frequency).toBe(1000);
    expect(result.band4.frequency).toBe(8000);
    expect(result.band5).toBeDefined();
    expect(result.band6).toBeDefined();
  });

  it('should fix invalid band values using defaults', () => {
    const input = {
      enabled: true,
      band1: {
        type: 'highpass',
        enabled: true,
        frequency: NaN, // Invalid
        gain: 0,
        q: Infinity, // Invalid
      },
      band2: DEFAULT_EQ_BANDS[1],
      band3: DEFAULT_EQ_BANDS[2],
      band4: DEFAULT_EQ_BANDS[3],
      band5: DEFAULT_EQ_BANDS[4],
      band6: DEFAULT_EQ_BANDS[5],
    };

    const result = fixTrackEQ(input);

    // Should use default band1 values for invalid fields
    expect(result.band1.frequency).toBe(DEFAULT_EQ_BANDS[0].frequency);
    expect(result.band1.q).toBe(DEFAULT_EQ_BANDS[0].q);
  });

  it('should reject negative frequency and q values', () => {
    const input = {
      enabled: true,
      band1: DEFAULT_EQ_BANDS[0],
      band2: {
        type: 'lowshelf',
        enabled: true,
        frequency: -100, // Invalid
        gain: 2,
        q: -0.5, // Invalid
      },
      band3: DEFAULT_EQ_BANDS[2],
      band4: DEFAULT_EQ_BANDS[3],
      band5: DEFAULT_EQ_BANDS[4],
      band6: DEFAULT_EQ_BANDS[5],
    };

    const result = fixTrackEQ(input);

    // Should use default values for negative freq/q
    expect(result.band2.frequency).toBe(DEFAULT_EQ_BANDS[1].frequency);
    expect(result.band2.q).toBe(DEFAULT_EQ_BANDS[1].q);
    // Gain can be negative, so it should be unchanged
    expect(result.band2.gain).toBe(2);
  });
});
