/**
 * Processors for "claim-submit" and "claim-pre-auth" jobs.
 * Mirrors routes/claims.ts /selenium-claim and /selenium-claim-pre-auth
 */
import path from "path";
import axios from "axios";
import { storage } from "../../storage";
import { callPythonSync } from "./_shared";

export interface ClaimSubmitProcessorInput {
  enrichedPayload: any;
  files: { originalname: string; bufferBase64: string; mimetype: string }[];
  claimId?: number;
  /** "claimsubmit" (default) or "claim-pre-auth" */
  variant?: "claimsubmit" | "claim-pre-auth";
  /** When set, the frontend socket listener will handle the PDF download — skip auto-save */
  socketId?: string;
}

export interface ClaimSubmitProcessorResult {
  status: string;
  claimNumber?: string;
  pdf_url?: string;
  [key: string]: any;
}

/** Fetch the PDF from the selenium service and save it to cloud storage. */
async function savePdfFromSelenium(
  pdf_url: string,
  patientId: number,
  variant: "claimsubmit" | "claim-pre-auth"
) {
  try {
    const filename = path.basename(new URL(pdf_url).pathname);
    const seleniumPort = process.env.SELENIUM_PORT || "5002";
    const localUrl = `http://localhost:${seleniumPort}/downloads/${filename}`;

    const resp = await axios.get(localUrl, { responseType: "arraybuffer", timeout: 30000 });

    const groupTitleKey = variant === "claim-pre-auth" ? "INSURANCE_CLAIM_PREAUTH" : "INSURANCE_CLAIM";
    const groupTitle   = variant === "claim-pre-auth" ? "Preauth" : "Claims";

    let group = await storage.findPdfGroupByPatientTitleKey(patientId, groupTitleKey);
    if (!group) {
      group = await storage.createPdfGroup(patientId, groupTitle, groupTitleKey);
    }

    await storage.createPdfFile(group.id!, filename, resp.data);
    console.log(`[claimSubmitProcessor] PDF saved for patient ${patientId}: ${filename}`);
  } catch (err: any) {
    // Non-fatal — claim was submitted; just log the PDF failure
    console.error("[claimSubmitProcessor] failed to save PDF:", err?.message ?? err);
  }
}

export async function runClaimSubmitProcessor(
  input: ClaimSubmitProcessorInput
): Promise<ClaimSubmitProcessorResult> {
  const { enrichedPayload, files, claimId } = input;
  const variant = input.variant ?? "claimsubmit";

  // Build the same payload shape the Python /claimsubmit endpoint expects
  const pdfs = files
    .filter((f) => f.mimetype === "application/pdf")
    .map(({ originalname, bufferBase64 }) => ({ originalname, bufferBase64 }));

  const images = files
    .filter((f) => f.mimetype.startsWith("image/"))
    .map(({ originalname, bufferBase64 }) => ({ originalname, bufferBase64 }));

  const payload = { claim: enrichedPayload, pdfs, images };

  const endpoint = variant === "claim-pre-auth" ? "/claim-pre-auth" : "/claimsubmit";

  // 1) Call the Python service synchronously (BullMQ worker handles async)
  const result = await callPythonSync(endpoint, payload, 10 * 60 * 1000);

  // 2) Persist claimNumber / preAuthNumber and update status
  if (claimId) {
    try {
      if (variant === "claim-pre-auth") {
        const updates: Record<string, any> = { status: "PREAUTH" };
        if (result?.preAuthNumber) updates.preAuthNumber = result.preAuthNumber;
        await storage.updateClaim(claimId, updates);
      } else {
        const updates: Record<string, any> = { status: "REVIEW" };
        if (result?.claimNumber) updates.claimNumber = result.claimNumber;
        await storage.updateClaim(claimId, updates);
      }
    } catch (e) {
      console.error("[claimSubmitProcessor] failed to update claim after submission:", e);
    }
  }

  // 3) Auto-save PDF for batch jobs (no socketId = no frontend listener to call fetchpdf)
  if (result?.pdf_url && enrichedPayload?.patientId && !input.socketId) {
    await savePdfFromSelenium(
      result.pdf_url,
      Number(enrichedPayload.patientId),
      variant
    );
  }

  return { ...result, claimId };
}
