import { describe, it, expect } from 'vitest';
import {
  CreatePurchaseItemSchema,
  CreatePurchaseSchema,
  UpdatePurchaseSchema,
  PurchaseQuerySchema,
} from './purchase.schemas.js';

describe('CreatePurchaseItemSchema', () => {
  it('accepts minimal valid item', () => {
    const result = CreatePurchaseItemSchema.safeParse({
      name: 'Tylenol 30ct',
      quantity: 30,
      unit: 'tablet',
    });
    expect(result.success).toBe(true);
    if (result.success) expect(result.data.addedToCabinet).toBeUndefined();
  });

  it('accepts item with all fields', () => {
    const result = CreatePurchaseItemSchema.safeParse({
      medicineProductId: 'mp-1',
      name: 'Tylenol 30ct',
      quantity: 30,
      unit: 'tablet',
      actualPrice: 9.99,
      currency: 'USD',
      priceRecordId: 'pr-1',
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty name', () => {
    expect(
      CreatePurchaseItemSchema.safeParse({ name: '', quantity: 1, unit: 'tablet' }).success,
    ).toBe(false);
  });

  it('rejects non-positive quantity', () => {
    expect(
      CreatePurchaseItemSchema.safeParse({ name: 'X', quantity: 0, unit: 'tablet' }).success,
    ).toBe(false);
  });

  it('rejects empty unit', () => {
    expect(CreatePurchaseItemSchema.safeParse({ name: 'X', quantity: 1, unit: '' }).success).toBe(
      false,
    );
  });

  it('trims name whitespace', () => {
    const result = CreatePurchaseItemSchema.parse({
      name: '  Tylenol  ',
      quantity: 1,
      unit: 'tablet',
    });
    expect(result.name).toBe('Tylenol');
  });
});

describe('CreatePurchaseSchema', () => {
  const validItem = { name: 'Tylenol', quantity: 30, unit: 'tablet' };

  it('defaults status to in_cabinet', () => {
    const result = CreatePurchaseSchema.parse({ storeId: 'st-1', items: [validItem] });
    expect(result.status).toBe('in_cabinet');
  });

  it('accepts ordered status', () => {
    const result = CreatePurchaseSchema.safeParse({
      storeId: 'st-1',
      status: 'ordered',
      items: [validItem],
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty storeId', () => {
    expect(CreatePurchaseSchema.safeParse({ storeId: '', items: [validItem] }).success).toBe(false);
  });

  it('rejects empty items array', () => {
    expect(CreatePurchaseSchema.safeParse({ storeId: 'st-1', items: [] }).success).toBe(false);
  });

  it('rejects invalid status', () => {
    expect(
      CreatePurchaseSchema.safeParse({ storeId: 'st-1', status: 'pending', items: [validItem] })
        .success,
    ).toBe(false);
  });

  it('accepts optional purchasedAt datetime', () => {
    const result = CreatePurchaseSchema.safeParse({
      storeId: 'st-1',
      items: [validItem],
      purchasedAt: '2026-01-15T00:00:00.000Z',
    });
    expect(result.success).toBe(true);
  });

  it('rejects invalid purchasedAt', () => {
    expect(
      CreatePurchaseSchema.safeParse({
        storeId: 'st-1',
        items: [validItem],
        purchasedAt: 'not-a-date',
      }).success,
    ).toBe(false);
  });
});

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

  it('accepts notes only', () => {
    expect(UpdatePurchaseSchema.safeParse({ notes: 'updated' }).success).toBe(true);
  });

  it('trims notes whitespace', () => {
    const result = UpdatePurchaseSchema.parse({ notes: '  hello  ' });
    expect(result.notes).toBe('hello');
  });
});

describe('PurchaseQuerySchema', () => {
  it('defaults limit to 20', () => {
    const result = PurchaseQuerySchema.parse({});
    expect(result.limit).toBe(20);
  });

  it('accepts status filter', () => {
    expect(PurchaseQuerySchema.safeParse({ status: 'ordered' }).success).toBe(true);
    expect(PurchaseQuerySchema.safeParse({ status: 'in_cabinet' }).success).toBe(true);
  });

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

  it('coerces string limit', () => {
    const result = PurchaseQuerySchema.parse({ limit: '50' });
    expect(result.limit).toBe(50);
  });
});
