import { afterEach, describe, expect, it, vi } from 'vitest'

const renderToBufferMock = vi.fn().mockResolvedValue(Buffer.from('pdf-bytes'))

vi.mock('@react-pdf/renderer', () => ({
  renderToBuffer: (...args: any[]) => renderToBufferMock(...args),
  Document: 'Document',
  Page: 'Page',
  Text: 'Text',
  View: 'View',
  StyleSheet: { create: (styles: any) => styles },
}))

import { buildInvoiceNumber, generateInvoicePdf } from './invoicePdfService'

describe('invoicePdfService', () => {
  afterEach(() => {
    vi.clearAllMocks()
  })

  it('builds stable legacy invoice numbers from the creation year and id suffix', () => {
    expect(buildInvoiceNumber('invoice_abcdef', new Date('2026-06-09T12:00:00.000Z'))).toBe('INV-2026-ABCDEF')
    expect(buildInvoiceNumber('short', new Date('2027-06-01T00:00:00.000Z'))).toBe('INV-2027-SHORT')
  })

  it('renders a subscription invoice document into a buffer', async () => {
    const result = await generateInvoicePdf({
      invoiceNumber: 'INV-2026-000001',
      issueDate: '2026-06-09T00:00:00.000Z',
      dueDate: null,
      company: { name: 'Atlas Cars', email: 'billing@atlas.test', phone: '+212600000000', address: { formatted: 'Casablanca' } },
      subscription: { plan: 'PRO', billingPeriod: 'MONTHLY', currency: 'MAD' },
      amount: 99000,
      currency: 'MAD',
      status: 'PAID',
      paymentProvider: 'PAYPAL',
      transactionId: 'txn_1',
      paidAt: '2026-06-09T12:00:00.000Z',
      lineItems: [{ description: 'Pro monthly subscription', amount: 99000, currency: 'MAD', quantity: 1, unitAmount: 99000 }],
      totals: {
        subtotalAmount: 99000,
        discountAmount: 0,
        creditAmount: 0,
        taxAmount: 0,
        totalAmount: 99000,
        amountPaid: 99000,
        amountDue: 0,
      },
    })

    expect(result).toEqual(Buffer.from('pdf-bytes'))
    expect(renderToBufferMock).toHaveBeenCalledTimes(1)
    expect(renderToBufferMock.mock.calls[0][0]).toEqual(expect.objectContaining({
      props: expect.objectContaining({ data: expect.objectContaining({ invoiceNumber: 'INV-2026-000001' }) }),
    }))
  })

  it('falls back to a simple PDF when the React PDF renderer fails', async () => {
    renderToBufferMock.mockRejectedValueOnce(new Error('renderer failed'))

    const result = await generateInvoicePdf({
      invoiceNumber: 'INV-2026-000002',
      issueDate: '2026-06-09T00:00:00.000Z',
      dueDate: null,
      company: { name: 'Atlas Cars', email: 'billing@atlas.test', address: { formatted: 'Casablanca' } },
      amount: 80000,
      currency: 'MAD',
      status: 'OPEN',
      paymentProvider: 'MANUAL',
      lineItems: [{ description: 'Migration assistance', amount: 30000, currency: 'MAD', quantity: 2, unitAmount: 15000 }],
      totals: {
        subtotalAmount: 80000,
        discountAmount: 0,
        creditAmount: 0,
        taxAmount: 0,
        totalAmount: 80000,
        amountPaid: 0,
        amountDue: 80000,
      },
    })

    expect(result.subarray(0, 8).toString()).toBe('%PDF-1.4')
    expect(result.toString()).toContain('INV-2026-000002')
  })
})
