import { describe, it, expect } from 'vitest'
import {
  formatWeekKey,
  getMondayOfWeek,
  getWeekDays,
  getWorkDays,
  shiftWeek,
  STATUS_OPTIONS,
  isValidGoalStatus,
  isValidActivityStatus,
} from '@/lib/pmo/weekly'

describe('getMondayOfWeek', () => {
  it('returns the Monday for any day in the week (Wednesday)', () => {
    const wed = new Date('2026-05-20T15:00:00Z') // Wednesday
    const mon = getMondayOfWeek(wed)
    expect(mon.toISOString().slice(0, 10)).toBe('2026-05-18')
  })
  it('returns the Monday for Sunday (treats Sunday as end of prior week)', () => {
    const sun = new Date('2026-05-24T10:00:00Z')
    const mon = getMondayOfWeek(sun)
    expect(mon.toISOString().slice(0, 10)).toBe('2026-05-18')
  })
  it('returns the same date for Monday', () => {
    const mon = new Date('2026-05-18T00:00:00Z')
    expect(getMondayOfWeek(mon).toISOString().slice(0, 10)).toBe('2026-05-18')
  })
})

describe('formatWeekKey', () => {
  it('serialises a Monday to YYYY-MM-DD', () => {
    expect(formatWeekKey(new Date('2026-05-18T00:00:00Z'))).toBe('2026-05-18')
  })
})

describe('getWorkDays', () => {
  it('returns Mo-Fr starting from the week-start Monday', () => {
    const days = getWorkDays(new Date('2026-05-18T00:00:00Z'))
    expect(days.map((d) => d.toISOString().slice(0, 10))).toEqual([
      '2026-05-18', '2026-05-19', '2026-05-20', '2026-05-21', '2026-05-22',
    ])
  })
})

describe('getWeekDays', () => {
  it('returns full Mo-So (7 days)', () => {
    const days = getWeekDays(new Date('2026-05-18T00:00:00Z'))
    expect(days).toHaveLength(7)
    expect(days[6].toISOString().slice(0, 10)).toBe('2026-05-24')
  })
})

describe('shiftWeek', () => {
  const mon = new Date('2026-05-18T00:00:00Z')
  it('shifts forward by N weeks', () => {
    expect(formatWeekKey(shiftWeek(mon, 1))).toBe('2026-05-25')
    expect(formatWeekKey(shiftWeek(mon, 2))).toBe('2026-06-01')
  })
  it('shifts backward by N weeks', () => {
    expect(formatWeekKey(shiftWeek(mon, -1))).toBe('2026-05-11')
  })
})

describe('STATUS_OPTIONS + validators', () => {
  it('goal status options match the schema CHECK', () => {
    expect(STATUS_OPTIONS.goal.map((s) => s.value)).toEqual([
      'open', 'in_progress', 'done', 'blocked', 'rolled_over',
    ])
  })
  it('activity status options match the schema CHECK', () => {
    expect(STATUS_OPTIONS.activity.map((s) => s.value)).toEqual([
      'open', 'in_progress', 'done', 'not_done', 'rolled_over',
    ])
  })
  it('isValidGoalStatus / isValidActivityStatus catch bad inputs', () => {
    expect(isValidGoalStatus('open')).toBe(true)
    expect(isValidGoalStatus('not_done')).toBe(false) // activity-only
    expect(isValidActivityStatus('not_done')).toBe(true)
    expect(isValidActivityStatus('blocked')).toBe(false) // goal-only
    expect(isValidGoalStatus('')).toBe(false)
  })
})
