import { describe, it, expect } from 'vitest';
import { DosageUnit } from '../enums/medicine.enums.js';
import { CabinetItemStatus } from '../enums/cabinet.enums.js';
import {
  CreateCabinetItemSchema,
  UpdateCabinetItemSchema,
  AdjustQuantitySchema,
  CabinetQuerySchema,
} from './cabinet.schemas.js';

describe('CreateCabinetItemSchema', () => {
  const validItem = {
    medicineId: 'med-1',
    quantity: 30,
    unit: DosageUnit.TABLET,
  };

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

  it('accepts valid full input', () => {
    const result = CreateCabinetItemSchema.safeParse({
      ...validItem,
      medicineProductId: 'prod-1',
      expirationDate: '2026-12-31T00:00:00.000Z',
      notes: 'Main supply',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing medicineId', () => {
    const result = CreateCabinetItemSchema.safeParse({ quantity: 10, unit: DosageUnit.TABLET });
    expect(result.success).toBe(false);
  });

  it('rejects negative quantity', () => {
    const result = CreateCabinetItemSchema.safeParse({ ...validItem, quantity: -1 });
    expect(result.success).toBe(false);
  });

  it('accepts quantity of 0', () => {
    const result = CreateCabinetItemSchema.safeParse({ ...validItem, quantity: 0 });
    expect(result.success).toBe(true);
  });
});

describe('UpdateCabinetItemSchema', () => {
  it('accepts partial update', () => {
    const result = UpdateCabinetItemSchema.safeParse({ quantity: 25 });
    expect(result.success).toBe(true);
  });

  it('accepts status update', () => {
    const result = UpdateCabinetItemSchema.safeParse({ status: CabinetItemStatus.EXPIRED });
    expect(result.success).toBe(true);
  });

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

  it('rejects invalid status', () => {
    const result = UpdateCabinetItemSchema.safeParse({ status: 'invalid' });
    expect(result.success).toBe(false);
  });
});

describe('AdjustQuantitySchema', () => {
  it('accepts positive delta', () => {
    const result = AdjustQuantitySchema.safeParse({ delta: 5 });
    expect(result.success).toBe(true);
  });

  it('accepts negative delta', () => {
    const result = AdjustQuantitySchema.safeParse({ delta: -3, reason: 'Took a dose' });
    expect(result.success).toBe(true);
  });

  it('rejects missing delta', () => {
    const result = AdjustQuantitySchema.safeParse({});
    expect(result.success).toBe(false);
  });

  it('trims reason', () => {
    const result = AdjustQuantitySchema.safeParse({ delta: 1, reason: '  test  ' });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.reason).toBe('test');
    }
  });
});

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

  it('accepts medicineId filter', () => {
    const result = CabinetQuerySchema.safeParse({ medicineId: 'med-1' });
    expect(result.success).toBe(true);
  });

  it('accepts status filter', () => {
    const result = CabinetQuerySchema.safeParse({ status: CabinetItemStatus.ACTIVE });
    expect(result.success).toBe(true);
  });

  it('accepts expiringWithin filter', () => {
    const result = CabinetQuerySchema.safeParse({ expiringWithin: 30 });
    expect(result.success).toBe(true);
  });

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

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

  it('rejects expiringWithin over 365', () => {
    const result = CabinetQuerySchema.safeParse({ expiringWithin: 400 });
    expect(result.success).toBe(false);
  });
});
