import { describe, it, expect } from 'vitest';
import { DosageUnit } from '../enums/medicine.enums.js';
import { DosageFrequency, TimeOfDay } from '../enums/regimen.enums.js';
import {
  CreateRegimenSchema,
  UpdateRegimenSchema,
  RegimenQuerySchema,
  RegimenMedicationInputSchema,
} from './regimen.schemas.js';

const validMedication = {
  medicineId: 'med-1',
  dosage: 1,
  dosageUnit: DosageUnit.TABLET,
  frequency: DosageFrequency.DAILY,
};

describe('RegimenMedicationInputSchema', () => {
  it('accepts valid medication', () => {
    const result = RegimenMedicationInputSchema.safeParse(validMedication);
    expect(result.success).toBe(true);
  });

  it('accepts full medication with optional fields', () => {
    const result = RegimenMedicationInputSchema.safeParse({
      ...validMedication,
      timeOfDay: TimeOfDay.MORNING,
      instructions: 'Take with food',
    });
    expect(result.success).toBe(true);
  });

  it('accepts custom frequency with customFrequencyPerDay', () => {
    const result = RegimenMedicationInputSchema.safeParse({
      ...validMedication,
      frequency: DosageFrequency.CUSTOM,
      customFrequencyPerDay: 4,
    });
    expect(result.success).toBe(true);
  });

  it('rejects custom frequency without customFrequencyPerDay', () => {
    const result = RegimenMedicationInputSchema.safeParse({
      ...validMedication,
      frequency: DosageFrequency.CUSTOM,
    });
    expect(result.success).toBe(false);
  });

  it('rejects zero dosage', () => {
    const result = RegimenMedicationInputSchema.safeParse({
      ...validMedication,
      dosage: 0,
    });
    expect(result.success).toBe(false);
  });

  it('rejects missing medicineId', () => {
    const { medicineId: _, ...rest } = validMedication;
    const result = RegimenMedicationInputSchema.safeParse(rest);
    expect(result.success).toBe(false);
  });
});

describe('CreateRegimenSchema', () => {
  const validRegimen = {
    name: 'Daily medications',
    medications: [validMedication],
  };

  it('accepts valid input', () => {
    const result = CreateRegimenSchema.safeParse(validRegimen);
    expect(result.success).toBe(true);
  });

  it('defaults isActive to true', () => {
    const result = CreateRegimenSchema.safeParse(validRegimen);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.isActive).toBe(true);
    }
  });

  it('accepts isActive override', () => {
    const result = CreateRegimenSchema.safeParse({ ...validRegimen, isActive: false });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.isActive).toBe(false);
    }
  });

  it('rejects empty name', () => {
    const result = CreateRegimenSchema.safeParse({ ...validRegimen, name: '' });
    expect(result.success).toBe(false);
  });

  it('rejects empty medications array', () => {
    const result = CreateRegimenSchema.safeParse({ ...validRegimen, medications: [] });
    expect(result.success).toBe(false);
  });

  it('accepts multiple medications', () => {
    const result = CreateRegimenSchema.safeParse({
      ...validRegimen,
      medications: [validMedication, { ...validMedication, medicineId: 'med-2', dosage: 2 }],
    });
    expect(result.success).toBe(true);
  });
});

describe('UpdateRegimenSchema', () => {
  it('accepts partial update', () => {
    const result = UpdateRegimenSchema.safeParse({ name: 'Updated name' });
    expect(result.success).toBe(true);
  });

  it('accepts empty object', () => {
    const result = UpdateRegimenSchema.safeParse({});
    expect(result.success).toBe(true);
  });

  it('accepts isActive toggle', () => {
    const result = UpdateRegimenSchema.safeParse({ isActive: false });
    expect(result.success).toBe(true);
  });

  it('rejects empty medications array when provided', () => {
    const result = UpdateRegimenSchema.safeParse({ medications: [] });
    expect(result.success).toBe(false);
  });
});

describe('RegimenQuerySchema', () => {
  it('applies default limit', () => {
    const result = RegimenQuerySchema.safeParse({});
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.limit).toBe(20);
    }
  });

  it('parses isActive string to boolean', () => {
    const result = RegimenQuerySchema.safeParse({ isActive: 'true' });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.isActive).toBe(true);
    }
  });

  it('rejects limit over 100', () => {
    const result = RegimenQuerySchema.safeParse({ limit: 101 });
    expect(result.success).toBe(false);
  });
});
