import { useCallback, useContext, useState } from "react";
import SettingsContext from "./settings-context";
import { buildTideClientConfig } from "../shared/utils/tide-api-utils";
import { book, print } from "@qite/tide-client";

import type {
  BookingPackage,
  BookingPackageBookRequest,
  BookingPackageDossier,
  BookingPackageRequest,
  AgentPrintActionRequest,
  Pax,
  BookingPackagePax,
} from "@qite/tide-client/build/types";

export interface UseOfferPrinterArgs {
  bookingPackage?: BookingPackage;
  getPax: () => Pax[] | undefined;
  tagIds?: number[];
  printActionId?: number | null;
  onPrinted?: (pdfUrl: string) => void;
}

export function useOfferPrinter({
  bookingPackage,
  getPax,
  tagIds = [],
  printActionId = null,
  onPrinted,
}: UseOfferPrinterArgs) {
  const settings = useContext(SettingsContext);
  if (!settings)
    throw new Error("useOfferPrinter must be used inside <BookingWizard>");

  const { language, officeId } = settings;
  const agentId = (settings as any).agentAdressId;

  if (typeof agentId !== "number" || agentId <= 0) {
    throw new Error("Missing agentAdressId in wizard settings");
  }

  const [stage, setStage] = useState<"idle" | "creating" | "printing">("idle");
  const loading = stage !== "idle";

  const createOffer = useCallback(async (): Promise<BookingPackageDossier> => {
    const paxRaw = getPax();
    if (!bookingPackage || !paxRaw?.length) {
      throw new Error("Missing booking package or pax");
    }

    const pax = paxRaw as unknown as BookingPackagePax[];

    const request: BookingPackageRequest<BookingPackageBookRequest> = {
      officeId,
      agentId,
      payload: {
        package: bookingPackage,
        status: 0,
        pax,
        nonTravelPax: [],
        notifications: [],
        tagIds,
        customerRequests: [],
      },
    };

    const cfg = buildTideClientConfig();
    return book(cfg, request, undefined, language);
  }, [agentId, bookingPackage, getPax, language, officeId, tagIds]);

  const languageData = [
    { code: "nl-BE", tideId: 1 },
    { code: "fr-BE", tideId: 2 },
    { code: "en-GB", tideId: 3 },
  ];

  function getTideLanguageId(code: string) {
    return languageData.find((l) => l.code === code)?.tideId || 1;
  }

  const printOffer = useCallback(
    async (offer: BookingPackageDossier) => {
      const cfg = buildTideClientConfig();

      const req: AgentPrintActionRequest = {
        id: printActionId ?? 0,
        dossierNumber: (offer as any).dossierNumber ?? (offer as any).number,
        languageId: getTideLanguageId(language),
      };

      const res = await print(cfg, req);
      const buf = await res.arrayBuffer();
      const url = URL.createObjectURL(
        new Blob([buf], { type: "application/pdf" })
      );
      onPrinted?.(url);
      window.open(url);
    },
    [language, onPrinted]
  );

  const handlePrint = useCallback(async () => {
    try {
      setStage("creating");
      const offer = await createOffer();
      setStage("printing");
      await printOffer(offer);
    } catch (err) {
      console.error("Offer print failed:", err);
      throw err;
    } finally {
      setStage("idle");
    }
  }, [createOffer, printOffer]);

  return { handlePrint, loading, stage };
}
