import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
import { readFiltersFromSearchParams } from '@/lib/filters'

describe('readFiltersFromSearchParams', () => {
  beforeEach(() => {
    // Pin "now" to mid-May 2026 so month-relative tests are deterministic.
    vi.useFakeTimers()
    vi.setSystemTime(new Date('2026-05-15T12:00:00Z'))
  })

  afterEach(() => {
    vi.useRealTimers()
  })

  it('FLT-001 defaults to this-month when date is absent', () => {
    const r = readFiltersFromSearchParams({})
    expect(r.startBound).toBe('2026-05-01 00:00:00')
    expect(r.endBound).toBe('2026-06-01 00:00:00')
  })

  it('FLT-002 returns null bounds when date=all', () => {
    const r = readFiltersFromSearchParams({ date: 'all' })
    expect(r.startBound).toBeNull()
    expect(r.endBound).toBeNull()
  })

  it('FLT-003 this-month: first-of-this-month to first-of-next-month', () => {
    const r = readFiltersFromSearchParams({ date: 'this-month' })
    expect(r.startBound).toBe('2026-05-01 00:00:00')
    expect(r.endBound).toBe('2026-06-01 00:00:00')
  })

  it('FLT-004 last-month handles January correctly', () => {
    vi.setSystemTime(new Date('2026-01-15T12:00:00Z'))
    const r = readFiltersFromSearchParams({ date: 'last-month' })
    expect(r.startBound).toBe('2025-12-01 00:00:00')
    expect(r.endBound).toBe('2026-01-01 00:00:00')
  })

  it('FLT-005 custom range uses inclusive-end-day semantic', () => {
    const r = readFiltersFromSearchParams({
      date: 'custom',
      start: '2026-04-10',
      end: '2026-04-15',
    })
    expect(r.startBound).toBe('2026-04-10 00:00:00')
    // end + 1 day, so anything on 2026-04-15 is included
    expect(r.endBound).toBe('2026-04-16 00:00:00')
  })

  it('FLT-006 status pass-through, defaults to all', () => {
    expect(readFiltersFromSearchParams({}).status).toBe('all')
    expect(
      readFiltersFromSearchParams({ status: 'transferred' }).status,
    ).toBe('transferred')
    expect(readFiltersFromSearchParams({ status: 'blocked' }).status).toBe(
      'blocked',
    )
  })

  it('FLT-007 batch=all becomes null; other strings are preserved', () => {
    expect(readFiltersFromSearchParams({}).batch).toBeNull()
    expect(readFiltersFromSearchParams({ batch: 'all' }).batch).toBeNull()
    expect(
      readFiltersFromSearchParams({ batch: 'abc-123' }).batch,
    ).toBe('abc-123')
  })

  it('FLT-008 empty/whitespace q becomes null', () => {
    expect(readFiltersFromSearchParams({}).q).toBeNull()
    expect(readFiltersFromSearchParams({ q: '' }).q).toBeNull()
    expect(readFiltersFromSearchParams({ q: '   ' }).q).toBeNull()
    expect(readFiltersFromSearchParams({ q: 'demo' }).q).toBe('demo')
  })

  it('FLT-009 imported_by pass-through (uuid string or null)', () => {
    expect(readFiltersFromSearchParams({}).imported_by).toBeNull()
    expect(readFiltersFromSearchParams({ imported_by: '' }).imported_by).toBeNull()
    expect(
      readFiltersFromSearchParams({
        imported_by: 'bdea4ccb-d961-4317-912f-53f91b82e0ee',
      }).imported_by,
    ).toBe('bdea4ccb-d961-4317-912f-53f91b82e0ee')
  })

  it('FLT-010 defaults arg overrides built-in defaults', () => {
    // When the entries page chooses date=all + status=pending as defaults,
    // the helper should honor them in the absence of URL params.
    const r = readFiltersFromSearchParams(
      {},
      { date: 'all', status: 'pending' },
    )
    expect(r.startBound).toBeNull()
    expect(r.endBound).toBeNull()
    expect(r.status).toBe('pending')
  })
})
