import { APIRequestContext } from '@playwright/test';
import { fromInvoiceCreateApiResponse, toInvoiceCreateApiPayload } from '@/manager/modules/invoice/invoice-mappers';
import { InvoiceCreateApiResponse, InvoiceCreateData } from '@/manager/modules/invoice/invoice-types';
import { Invoice } from '@/manager/modules/invoice/invoice-types';
import { fetchLocationDefaultPaymentMethodIdsViaApi } from '@/manager/modules/location/location-api';
import dayjs from 'dayjs';

export async function createInvoiceViaApi(request: APIRequestContext, data: InvoiceCreateData): Promise<Invoice> {
  const defaultPaymentMethodIds = await fetchLocationDefaultPaymentMethodIdsViaApi(request, data.location.id);

  const response = await request.post('/v1/invoice', {
    data: toInvoiceCreateApiPayload(data, defaultPaymentMethodIds),
  });

  if (!response.ok()) {
    throw new Error(`Failed to create invoice via API: ${response.status()} ${await response.text()}`);
  }

  const body = (await response.json()) as InvoiceCreateApiResponse;

  return fromInvoiceCreateApiResponse(body, data);
}

// Marks an open invoice paid with an out-of-band cash payment — purely internal, no Stripe charge or email.
// Used to stand up the 'paid' invoices the credit-note specs need without a real card charge.
export async function markInvoiceAsPaidViaApi(request: APIRequestContext, id: number): Promise<void> {
  const response = await request.put(`/v1/invoice/${id}/status-paid`, {
    data: { payment_date: dayjs().format('YYYY-MM-DD'), payment_type: 'cash' },
  });

  if (!response.ok()) {
    throw new Error(`Failed to mark invoice ${id} as paid via API: ${response.status()} ${await response.text()}`);
  }
}
