import type { Freight } from "@edr/types";

import { URL_CONSTANTS } from "@/constants/URLS";
import { client } from "../utils/api";
import type { InitiateResponse } from "./payments.service";

const B = URL_CONSTANTS.BILLING;

/** A customer-facing invoice row, as returned by `GET /billing/my-invoices`. */
export type PortalInvoice = Freight.IInvoice;

/** An invoice plus its line items, as returned by `GET /billing/my-invoices/:id`. */
export type PortalInvoiceDetail = Freight.IInvoice & {
  lines: Freight.IInvoiceLine[];
};

export interface PayInvoicePayload {
  method?: string;
  platform?: "web" | "mobile";
  payerAccount?: string;
  returnUrl?: string;
  failureUrl?: string;
}

export const invoicesService = {
  /** Every invoice billed to the signed-in customer's company, newest first. */
  listMy: async (): Promise<PortalInvoice[]> => {
    const { data } = await client.get(B.MY_INVOICES);
    return data.data ?? data;
  },

  /** The customer's invoices for one source record (e.g. a booking). */
  listForSource: async (
    source: string,
    sourceId: string,
  ): Promise<PortalInvoice[]> => {
    const { data } = await client.get(B.MY_INVOICES, {
      params: { source, sourceId },
    });
    return data.data ?? data;
  },

  /** One of the customer's invoices, with its line items. */
  get: async (id: string): Promise<PortalInvoiceDetail> => {
    const { data } = await client.get(B.MY_INVOICE_BY_ID(id));
    return data.data ?? data;
  },

  /** The sealed invoice PDF for one of the customer's invoices. */
  downloadDocument: async (id: string): Promise<Blob> => {
    const { data } = await client.get(B.MY_INVOICE_DOCUMENT(id), {
      responseType: "blob",
    });
    return data;
  },

  /** The sealed payment-receipt PDF (available once paid). */
  downloadReceipt: async (id: string): Promise<Blob> => {
    const { data } = await client.get(B.MY_INVOICE_RECEIPT(id), {
      responseType: "blob",
    });
    return data;
  },

  /** Initiate gateway payment for an open invoice; returns the client action. */
  pay: async (
    id: string,
    payload: PayInvoicePayload = {},
  ): Promise<InitiateResponse> => {
    const { data } = await client.post(B.PAY_INVOICE(id), {
      platform: "web",
      ...payload,
    });
    return data.data ?? data;
  },
};
