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

import { clearStoredAccessToken, setStoredAccessToken } from '@/services/authSession'
import { generateManualReservationInvoice } from '@/services/reservationService'
import type { ManualInvoiceGenerationRequest, ManualInvoiceGenerationResult } from '@/types/manualInvoice'

const jsonHeaders = {
  headers: {
    get: (name: string) => (name.toLowerCase() === 'content-type' ? 'application/json' : null),
  },
}

function mockJsonResponse(payload: unknown): Response {
  return {
    ok: true,
    status: 200,
    json: async () => payload,
    text: async () => JSON.stringify(payload),
    ...jsonHeaders,
  } as Response
}

function createManualInvoiceRequest(): ManualInvoiceGenerationRequest {
  return {
    hotel_id: 'HOTEL-TEST',
    source_type: 'MANUAL',
    task_id: null,
    order_id: null,
    template_code: 'PROFORMA_INVOICE_V1',
    invoice_payload: {
      document: {
        invoice_date: '2026-07-17',
        booking_date: '2026-07-17',
        due_date: '2026-07-24',
      },
      recipient: {
        company_code: 'QBD',
        contact_id: 'QBD_JITDANUN_PANAPHUCHONG',
        company: 'Q.B.D. TRAVEL GROUP CO., LTD',
        attention: 'Jitdanun Panaphuchong',
        address: '2/90 Rajpattana,Rajpattana,Sapansoong, Bangkok, TH, 10240',
        telephone: '089-032 0176',
        email: 'op.qbdtravel@gmail.com',
      },
      booking: {
        group_name: 'LLT260509FA213',
        arrival_date: '2026-07-20',
        departure_date: '2026-07-22',
        room_rate_note: 'Inclusive breakfast',
        extra_bed_rate: 900,
      },
      charges: [
        {
          description: '2N TWN +1 DBL',
          room_type: 'TWN/DBL',
          quantity: 3,
          rate: 2500,
          nights: 2,
        },
      ],
    },
  }
}

function createManualInvoiceResult(): ManualInvoiceGenerationResult {
  return {
    invoice_generation_id: '91001',
    generation_status: 'GENERATED',
    source_type: 'MANUAL',
    hotel_id: 'HOTEL-TEST',
    order_id: null,
    task_id: null,
    template_code: 'PROFORMA_INVOICE_V1',
    pdf_url: 'https://oss.example/invoices/manual-91001.pdf',
    pdf_object_key: 'reservation/invoices/manual-91001.pdf',
    generated_excel_object_key: 'reservation/invoices/manual-91001.xlsx',
    totals: {
      subtotal: 14018.69,
      vat: 981.31,
      total: 15000,
      currency: 'THB',
    },
    created_at: '2026-07-17T08:00:00Z',
  }
}

describe('manual invoice reservation service', () => {
  beforeEach(() => {
    vi.restoreAllMocks()
    clearStoredAccessToken()
  })

  it('posts manual invoice payload to the M009 business endpoint with Bearer auth', async () => {
    const request = createManualInvoiceRequest()
    const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockJsonResponse(createManualInvoiceResult()))
    setStoredAccessToken('session-token')

    const result = await generateManualReservationInvoice(request)

    expect(fetchMock).toHaveBeenCalledWith(
      '/api/reservation/invoices/manual-generations',
      expect.objectContaining({
        method: 'POST',
        headers: expect.objectContaining({
          Accept: 'application/json',
          Authorization: 'Bearer session-token',
          'Content-Type': 'application/json',
        }),
        body: JSON.stringify(request),
      }),
    )
    expect(fetchMock.mock.calls[0]?.[0]).not.toContain('/api/system/document-conversions/excel-to-pdf')
    expect(result.pdf_url).toBe('https://oss.example/invoices/manual-91001.pdf')
  })
})
