import { describe, it, expect } from 'vitest'
import { defaultInvoiceDate, formatPasteBlock } from '@/lib/invoices'

describe('defaultInvoiceDate', () => {
  it('INV-D-001 returns last day of previous month, YYYY-MM-DD', () => {
    // Mid-month: May 15, 2026 → April 30, 2026
    expect(defaultInvoiceDate(new Date(2026, 4, 15))).toBe('2026-04-30')
  })

  it('INV-D-002 on the first of the month, returns end of preceding month', () => {
    // June 1, 2026 → May 31, 2026
    expect(defaultInvoiceDate(new Date(2026, 5, 1))).toBe('2026-05-31')
  })

  it('INV-D-003 handles January (rolls back to previous December)', () => {
    // Jan 10, 2026 → Dec 31, 2025
    expect(defaultInvoiceDate(new Date(2026, 0, 10))).toBe('2025-12-31')
  })

  it('INV-D-004 handles March correctly across leap years', () => {
    // March 5, 2024 (leap year) → Feb 29, 2024
    expect(defaultInvoiceDate(new Date(2024, 2, 5))).toBe('2024-02-29')
    // March 5, 2026 (non-leap) → Feb 28, 2026
    expect(defaultInvoiceDate(new Date(2026, 2, 5))).toBe('2026-02-28')
  })
})

describe('formatPasteBlock', () => {
  const date = '2026-04-30'

  it('INV-P-001 returns empty string for empty breakdown', () => {
    expect(formatPasteBlock([], date)).toBe('')
  })

  it('INV-P-002 renders one line per breakdown row with tabs + fixed columns', () => {
    const out = formatPasteBlock(
      [
        {
          client: 'DaxTech',
          project: 'Website',
          row_count: 3,
          source_seconds: 10800,
          cost_usd: 21,
          billout_amount_usd: 75,
        },
      ],
      date,
    )
    // 7 columns: "DaxTech : Website", "Bowden Works Team", "75.00",
    // "2026-04-30", "", "Bowden Works", "Labour"
    expect(out.split('\t')).toEqual([
      'DaxTech : Website',
      'Bowden Works Team',
      '75.00',
      '2026-04-30',
      '',
      'Bowden Works',
      'Labour',
    ])
  })

  it('INV-P-003 amount formatted to 2 decimal places, no $ sign', () => {
    const out = formatPasteBlock(
      [
        {
          client: 'C',
          project: 'P',
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 1234.5,
        },
      ],
      date,
    )
    expect(out).toContain('\t1234.50\t')
    expect(out).not.toContain('$')
  })

  it('INV-P-004 multiple rows joined with newlines, sorted by caller', () => {
    const out = formatPasteBlock(
      [
        {
          client: 'A',
          project: 'Alpha',
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 10,
        },
        {
          client: 'B',
          project: 'Beta',
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 20,
        },
      ],
      date,
    )
    expect(out.split('\n')).toHaveLength(2)
    expect(out.split('\n')[0]).toContain('A : Alpha')
    expect(out.split('\n')[1]).toContain('B : Beta')
  })

  it('INV-P-005 NULL client / project surface as (no client) / (no project)', () => {
    const out = formatPasteBlock(
      [
        {
          client: null,
          project: null,
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 5,
        },
      ],
      date,
    )
    expect(out.split('\t')[0]).toBe('(no client) : (no project)')
  })

  it('INV-P-006 uses the colon-with-spaces separator (matches Toggl format)', () => {
    const out = formatPasteBlock(
      [
        {
          client: 'C',
          project: 'P',
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 5,
        },
      ],
      date,
    )
    expect(out).toMatch(/^C : P\t/)
  })

  it('INV-P-007 5th column (between date and Bowden Works) is empty', () => {
    const out = formatPasteBlock(
      [
        {
          client: 'C',
          project: 'P',
          row_count: 1,
          source_seconds: 3600,
          cost_usd: 0,
          billout_amount_usd: 5,
        },
      ],
      date,
    )
    expect(out.split('\t')[4]).toBe('')
  })
})
