import { describe, it, expect } from 'vitest'
import {
  CreateRequestInputSchema,
  ListRequestsQuerySchema,
  RequestSeverityEnum,
  RequestCategoryEnum,
  RequestStatusEnum,
  RequestSourceEnum,
  RequestTypeEnum
} from '../api-schemas'

const validInput = {
  type: 'bug' as const,
  title: 'Login button not responding',
  description: 'The login button does nothing when clicked on Safari.',
  severity: 'warning' as const,
  category: 'ui_bug' as const
}

describe('CreateRequestInputSchema', () => {
  it('accepts a minimal valid payload', () => {
    const result = CreateRequestInputSchema.safeParse(validInput)
    expect(result.success).toBe(true)
  })

  it('accepts a fully-populated payload', () => {
    const result = CreateRequestInputSchema.safeParse({
      ...validInput,
      affected_page: '/projects/abc',
      evidence: { stack: 'TypeError: x is undefined' },
      context: { recent_messages: [], identified_source: 'ui/src/routes/login.tsx' },
      project_id: '123e4567-e89b-12d3-a456-426614174000',
      task_id: '123e4567-e89b-12d3-a456-426614174001'
    })
    expect(result.success).toBe(true)
  })

  it('accepts null for optional nullish fields', () => {
    const result = CreateRequestInputSchema.safeParse({
      ...validInput,
      affected_page: null,
      evidence: null,
      context: null,
      project_id: null,
      task_id: null
    })
    expect(result.success).toBe(true)
  })

  it('accepts feature type', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, type: 'feature' })
    expect(result.success).toBe(true)
  })

  it('accepts question type', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, type: 'question' })
    expect(result.success).toBe(true)
  })

  it('accepts other type', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, type: 'other' })
    expect(result.success).toBe(true)
  })

  it('rejects missing type (required, no default)', () => {
    const { type: _type, ...withoutType } = validInput
    const result = CreateRequestInputSchema.safeParse(withoutType)
    expect(result.success).toBe(false)
  })

  it('rejects invalid type value', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, type: 'enhancement' })
    expect(result.success).toBe(false)
  })

  it('rejects empty title', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, title: '' })
    expect(result.success).toBe(false)
  })

  it('rejects empty description', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, description: '' })
    expect(result.success).toBe(false)
  })

  it('rejects invalid severity', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, severity: 'urgent' })
    expect(result.success).toBe(false)
  })

  it('rejects invalid category', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, category: 'typo' })
    expect(result.success).toBe(false)
  })

  it('rejects invalid project_id UUID', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, project_id: 'not-a-uuid' })
    expect(result.success).toBe(false)
  })

  it('rejects invalid task_id UUID', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, task_id: 'not-a-uuid' })
    expect(result.success).toBe(false)
  })

  it('rejects client-supplied source (strict mode — mass assignment prevention)', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, source: 'external' })
    expect(result.success).toBe(false)
  })

  it('rejects client-supplied organization_id (strict mode)', () => {
    const result = CreateRequestInputSchema.safeParse({
      ...validInput,
      organization_id: '123e4567-e89b-12d3-a456-426614174000'
    })
    expect(result.success).toBe(false)
  })

  it('rejects client-supplied reporter_id (strict mode)', () => {
    const result = CreateRequestInputSchema.safeParse({
      ...validInput,
      reporter_id: '123e4567-e89b-12d3-a456-426614174000'
    })
    expect(result.success).toBe(false)
  })

  it('rejects client-supplied status (strict mode)', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, status: 'resolved' })
    expect(result.success).toBe(false)
  })

  it('rejects arbitrary unknown field (strict mode)', () => {
    const result = CreateRequestInputSchema.safeParse({ ...validInput, foo: 'bar' })
    expect(result.success).toBe(false)
  })
})

describe('ListRequestsQuerySchema', () => {
  it('applies default limit of 50', () => {
    const result = ListRequestsQuerySchema.safeParse({})
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.limit).toBe(50)
    }
  })

  it('coerces string limit to number', () => {
    const result = ListRequestsQuerySchema.safeParse({ limit: '25' })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.limit).toBe(25)
    }
  })

  it('rejects limit < 1', () => {
    const result = ListRequestsQuerySchema.safeParse({ limit: '0' })
    expect(result.success).toBe(false)
  })

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

  it('rejects non-numeric limit', () => {
    const result = ListRequestsQuerySchema.safeParse({ limit: 'abc' })
    expect(result.success).toBe(false)
  })

  it('accepts valid status filter', () => {
    const result = ListRequestsQuerySchema.safeParse({ status: 'open' })
    expect(result.success).toBe(true)
  })

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

  it('accepts valid severity filter', () => {
    const result = ListRequestsQuerySchema.safeParse({ severity: 'critical' })
    expect(result.success).toBe(true)
  })

  it('rejects invalid severity filter', () => {
    const result = ListRequestsQuerySchema.safeParse({ severity: 'urgent' })
    expect(result.success).toBe(false)
  })

  it('accepts valid project_id UUID filter', () => {
    const result = ListRequestsQuerySchema.safeParse({
      project_id: '123e4567-e89b-12d3-a456-426614174000'
    })
    expect(result.success).toBe(true)
  })

  it('rejects invalid project_id UUID', () => {
    const result = ListRequestsQuerySchema.safeParse({ project_id: 'not-a-uuid' })
    expect(result.success).toBe(false)
  })
})

describe('RequestSeverityEnum', () => {
  it('accepts all valid severities', () => {
    const severities = ['critical', 'warning', 'info']
    severities.forEach((s) => {
      expect(RequestSeverityEnum.safeParse(s).success).toBe(true)
    })
  })

  it('rejects invalid severity', () => {
    expect(RequestSeverityEnum.safeParse('urgent').success).toBe(false)
  })
})

describe('RequestCategoryEnum', () => {
  it('accepts all valid categories (must match DB CHECK constraint)', () => {
    const categories = [
      'ui_bug',
      'data_inconsistency',
      'performance',
      'error_pattern',
      'configuration',
      'feature_request',
      'api_design',
      'documentation',
      'integration_request',
      'other'
    ]
    categories.forEach((c) => {
      expect(RequestCategoryEnum.safeParse(c).success).toBe(true)
    })
  })

  it('rejects invalid category', () => {
    expect(RequestCategoryEnum.safeParse('typo').success).toBe(false)
  })
})

describe('RequestStatusEnum', () => {
  it('accepts all valid statuses (must match DB CHECK constraint)', () => {
    const statuses = ['open', 'investigating', 'resolved', 'wont_fix']
    statuses.forEach((s) => {
      expect(RequestStatusEnum.safeParse(s).success).toBe(true)
    })
  })

  it('rejects invalid status', () => {
    expect(RequestStatusEnum.safeParse('archived').success).toBe(false)
  })
})

describe('RequestSourceEnum', () => {
  it('accepts all valid sources (must match DB CHECK constraint)', () => {
    const sources = ['agent', 'cli', 'api', 'webhook', 'user', 'external']
    sources.forEach((s) => {
      expect(RequestSourceEnum.safeParse(s).success).toBe(true)
    })
  })

  it('rejects invalid source', () => {
    expect(RequestSourceEnum.safeParse('bot').success).toBe(false)
  })
})

describe('RequestTypeEnum', () => {
  it('accepts all valid types', () => {
    const types = ['bug', 'feature', 'question', 'other']
    types.forEach((t) => {
      expect(RequestTypeEnum.safeParse(t).success).toBe(true)
    })
  })

  it('rejects invalid type', () => {
    expect(RequestTypeEnum.safeParse('enhancement').success).toBe(false)
  })
})
