/**
 * Items module unit tests — validates schema parsing and type guards.
 */

import { describe, it, expect } from 'vitest';
import {
  CreateItemSchema,
  UpdateItemSchema,
  UpdateStatusSchema,
  ListItemsQuerySchema,
  ITEM_TYPES,
  ITEM_STATUSES,
  ITEM_PRIORITIES,
} from './types.js';

describe('CreateItemSchema', () => {
  it('accepts valid bug input', () => {
    const result = CreateItemSchema.safeParse({
      type: 'bug',
      title: 'App crashes on startup',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.type).toBe('bug');
      expect(result.data.priority).toBe('medium');
      expect(result.data.labels).toEqual([]);
      expect(result.data.source).toBe('internal');
    }
  });

  it('accepts valid feature request with all fields', () => {
    const result = CreateItemSchema.safeParse({
      type: 'feature',
      priority: 'high',
      title: 'Add dark mode',
      description: 'Users want dark mode support',
      labels: ['ui', 'theme'],
      assignee: 'usr_123',
      targetRelease: '1.2.0',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing title', () => {
    const result = CreateItemSchema.safeParse({ type: 'bug' });
    expect(result.success).toBe(false);
  });

  it('rejects invalid type', () => {
    const result = CreateItemSchema.safeParse({ type: 'epic', title: 'Test' });
    expect(result.success).toBe(false);
  });

  it('rejects invalid priority', () => {
    const result = CreateItemSchema.safeParse({
      type: 'task',
      title: 'Test',
      priority: 'urgent',
    });
    expect(result.success).toBe(false);
  });
});

describe('UpdateItemSchema', () => {
  it('accepts partial updates', () => {
    const result = UpdateItemSchema.safeParse({ priority: 'critical' });
    expect(result.success).toBe(true);
  });

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

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

describe('UpdateStatusSchema', () => {
  it('accepts valid status', () => {
    for (const status of ITEM_STATUSES) {
      const result = UpdateStatusSchema.safeParse({ status });
      expect(result.success).toBe(true);
    }
  });

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

describe('ListItemsQuerySchema', () => {
  it('provides defaults for empty query', () => {
    const result = ListItemsQuerySchema.safeParse({});
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.sortBy).toBe('createdAt');
      expect(result.data.sortOrder).toBe('desc');
      expect(result.data.limit).toBe(50);
      expect(result.data.offset).toBe(0);
    }
  });

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

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

describe('type constants', () => {
  it('has expected item types', () => {
    expect(ITEM_TYPES).toEqual(['bug', 'feature', 'task']);
  });

  it('has expected statuses', () => {
    expect(ITEM_STATUSES).toEqual(['open', 'in_progress', 'done', 'closed', 'wont_fix']);
  });

  it('has expected priorities', () => {
    expect(ITEM_PRIORITIES).toEqual(['critical', 'high', 'medium', 'low']);
  });
});
