import { describe, it, expect } from 'vitest';
import {
  CreateMedicineSchema,
  UpdateMedicineSchema,
  MedicineQuerySchema,
  CreateMedicineProductSchema,
  UpdateMedicineProductSchema,
} from './medicine.schemas.js';
import {
  MedicineForm,
  StrengthUnit,
  MedicineCategory,
  DosageUnit,
  MedicineProductSource,
} from '../enums/medicine.enums.js';

describe('CreateMedicineSchema', () => {
  const validMedicine = {
    name: 'Metformin',
    form: MedicineForm.TABLET,
    strength: 500,
    strengthUnit: StrengthUnit.MG,
    category: MedicineCategory.PRESCRIPTION,
  };

  it('accepts valid medicine', () => {
    const result = CreateMedicineSchema.safeParse(validMedicine);
    expect(result.success).toBe(true);
  });

  it('accepts medicine with all optional fields', () => {
    const result = CreateMedicineSchema.safeParse({
      ...validMedicine,
      notes: 'Take with food',
      tags: ['daily', 'morning'],
    });
    expect(result.success).toBe(true);
  });

  it('defaults tags to empty array', () => {
    const result = CreateMedicineSchema.safeParse(validMedicine);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.tags).toEqual([]);
    }
  });

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

  it('rejects zero strength', () => {
    const result = CreateMedicineSchema.safeParse({ ...validMedicine, strength: 0 });
    expect(result.success).toBe(false);
  });

  it('rejects negative strength', () => {
    const result = CreateMedicineSchema.safeParse({ ...validMedicine, strength: -1 });
    expect(result.success).toBe(false);
  });

  it('rejects invalid form', () => {
    const result = CreateMedicineSchema.safeParse({ ...validMedicine, form: 'gummy' });
    expect(result.success).toBe(false);
  });

  it('rejects invalid category', () => {
    const result = CreateMedicineSchema.safeParse({ ...validMedicine, category: 'magic' });
    expect(result.success).toBe(false);
  });

  it('trims name whitespace', () => {
    const result = CreateMedicineSchema.safeParse({ ...validMedicine, name: '  Metformin  ' });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.name).toBe('Metformin');
    }
  });
});

describe('UpdateMedicineSchema', () => {
  it('accepts empty object (all fields optional)', () => {
    const result = UpdateMedicineSchema.safeParse({});
    expect(result.success).toBe(true);
  });

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

  it('rejects invalid strength', () => {
    const result = UpdateMedicineSchema.safeParse({ strength: -5 });
    expect(result.success).toBe(false);
  });
});

describe('MedicineQuerySchema', () => {
  it('accepts empty query with defaults', () => {
    const result = MedicineQuerySchema.safeParse({});
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.limit).toBe(20);
    }
  });

  it('accepts full query', () => {
    const result = MedicineQuerySchema.safeParse({
      q: 'metformin',
      category: MedicineCategory.PRESCRIPTION,
      form: MedicineForm.TABLET,
      cursor: 'abc123',
      limit: 50,
    });
    expect(result.success).toBe(true);
  });

  it('coerces limit from string', () => {
    const result = MedicineQuerySchema.safeParse({ limit: '10' });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.limit).toBe(10);
    }
  });

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

describe('CreateMedicineProductSchema', () => {
  const validProduct = {
    brand: 'CVS Health',
    packageSize: 90,
    packageUnit: DosageUnit.TABLET,
  };

  it('accepts valid product', () => {
    const result = CreateMedicineProductSchema.safeParse(validProduct);
    expect(result.success).toBe(true);
  });

  it('defaults source to manual', () => {
    const result = CreateMedicineProductSchema.safeParse(validProduct);
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.source).toBe(MedicineProductSource.MANUAL);
    }
  });

  it('accepts product with all optional fields', () => {
    const result = CreateMedicineProductSchema.safeParse({
      ...validProduct,
      manufacturer: 'CVS Pharmacy',
      imageUrl: 'https://example.com/image.jpg',
      notes: 'Generic equivalent',
      source: MedicineProductSource.IMPORT,
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty brand', () => {
    const result = CreateMedicineProductSchema.safeParse({ ...validProduct, brand: '' });
    expect(result.success).toBe(false);
  });

  it('rejects zero package size', () => {
    const result = CreateMedicineProductSchema.safeParse({ ...validProduct, packageSize: 0 });
    expect(result.success).toBe(false);
  });

  it('rejects invalid URL', () => {
    const result = CreateMedicineProductSchema.safeParse({
      ...validProduct,
      imageUrl: 'not-a-url',
    });
    expect(result.success).toBe(false);
  });
});

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

  it('accepts partial update', () => {
    const result = UpdateMedicineProductSchema.safeParse({
      brand: 'Kirkland',
      packageSize: 60,
    });
    expect(result.success).toBe(true);
  });
});
