import { runPortfolioPdfBatch } from "./ylivitleiyuglkyjgkec.mjs";
import { downloadErgoPolicyPdfResult } from "./mircxkyqumigfadixdcc.mjs";
import {
  createPortfolioPdfPolicySelectorSet,
  portfolioPdfPolicySelectorMatches,
} from "./abywezhrsiqkqfhujfvq.mjs";

export const MTU_PORTFOLIO_PDF_CONCURRENCY = 1;
export const MTU_PRINT_HOST = "polisaonline.ergohestia.pl";
export const MTU_PRINT_SYMBOLS = Object.freeze([
  "POLISA",
  "POLISA-ELEKTRONICZNA",
  "POLISA-KOPIA",
]);
export const MTU_PDF_TRANSIENT_RETRY_DELAY_MS = 1800;

function delay(milliseconds) {
  return new Promise((resolve) => globalThis.setTimeout(resolve, milliseconds));
}

function compactPolicyNumber(value) {
  const normalized = String(value ?? "").trim();
  if (!normalized || normalized.length > 256 || normalized.includes("\0")) return "";
  return normalized;
}

function normalizedPortfolioKey(value) {
  return String(value ?? "").replace(/[^0-9A-Za-z]/g, "").toUpperCase();
}

function sourcePolicy(sourceEntry) {
  const policy = sourceEntry?.policy ?? sourceEntry;
  return policy && typeof policy === "object" && !Array.isArray(policy)
    ? policy
    : null;
}

function failedMtuPdfBatch(remaining, deferred = 0, circuitCode = "unknown") {
  return {
    publicResult: {
      attempted: 0,
      succeeded: 0,
      failed: 0,
      backoff: 0,
      quarantined: 0,
      unsupported: 0,
      deferred: Math.max(0, deferred),
      remaining: Math.max(0, remaining),
      batchComplete: false,
      circuitOpen: true,
      circuitCode,
      manualRetryAvailable: false,
    },
    privateResult: {
      manualRetryIdentities: [],
    },
  };
}

 
export function prepareMtuPortfolioPdfEntries({
  entries,
  policies,
  skipPolicyNumbers = [],
  knownPolicyNumbers = [],
} = {}) {
  if (entries !== undefined && policies !== undefined) {
    throw new TypeError("Podaj entries albo policies, nie oba pola jednoczesnie.");
  }
  const source = entries ?? policies;
  if (!Array.isArray(source)) {
    throw new TypeError("entries albo policies musi byc tablica.");
  }
  const skipSet = createPortfolioPdfPolicySelectorSet(skipPolicyNumbers, {
    insurer: "mtu",
  });
  const knownSet = createPortfolioPdfPolicySelectorSet(knownPolicyNumbers, {
    insurer: "mtu",
  });
  const eligible = [];
  for (let index = 0; index < source.length; index += 1) {
    const sourceEntry = source[index];
    const policy = sourcePolicy(sourceEntry);
    if (!policy || String(policy.insurer || "").trim().toUpperCase() !== "MTU") continue;
    const originalPolicyNumber = compactPolicyNumber(policy.policyNumber);
    const key = normalizedPortfolioKey(originalPolicyNumber);
    const identitySource = { ...policy, policyNumber: originalPolicyNumber };
    if (!key || portfolioPdfPolicySelectorMatches(skipSet, identitySource)) continue;
    eligible.push({
      sourceIndex: index,
      known: portfolioPdfPolicySelectorMatches(knownSet, identitySource),
      runnerEntry: sourceEntry?.policy
        ? { ...sourceEntry, policy, policyNumber: originalPolicyNumber }
        : { policy, policyNumber: originalPolicyNumber },
    });
  }
  eligible.sort((left, right) => (
    Number(left.known) - Number(right.known)
    || left.sourceIndex - right.sourceIndex
  ));
  return eligible.map(({ runnerEntry }) => runnerEntry);
}

 
export async function runMtuPortfolioPdfBatch({
  page,
  retryStore,
  pdfDirectory,
  entries,
  policies,
  limit,
  skipPolicyNumbers = [],
  knownPolicyNumbers = [],
  onProgress = () => {},
  transientRetryDelayMs = MTU_PDF_TRANSIENT_RETRY_DELAY_MS,
} = {}) {
  if (typeof onProgress !== "function") {
    throw new TypeError("onProgress musi byc funkcja.");
  }
  if (!Number.isSafeInteger(transientRetryDelayMs) || transientRetryDelayMs < 0) {
    throw new TypeError("transientRetryDelayMs musi byc nieujemna liczba calkowita.");
  }
  const eligible = prepareMtuPortfolioPdfEntries({
    entries,
    policies,
    skipPolicyNumbers,
    knownPolicyNumbers,
  });
  if (
    limit !== undefined
    && (!Number.isSafeInteger(limit) || limit <= 0)
  ) {
    throw new TypeError("limit musi byc dodatnia liczba calkowita.");
  }
  const selected = eligible.slice(0, limit ?? eligible.length);
  const businessDeferred = eligible.length - selected.length;
  const planned = selected.length;
  let processed = 0;
  let result;
  try {
    result = await runPortfolioPdfBatch({
      retryStore,
      insurer: "mtu",
      pdfDirectory,
      entries: selected,
      limit: selected.length || undefined,
      concurrency: MTU_PORTFOLIO_PDF_CONCURRENCY,
      fetchDocument: async ({ entry }) => {
        try {
          const request = () => downloadErgoPolicyPdfResult({
            page,
            host: MTU_PRINT_HOST,
            policyNumber: entry.policy?.policyNumber,
            symbols: MTU_PRINT_SYMBOLS,
          });
          let result = await request();
          if (result?.type === "global_failure") {
            
            
            
            await delay(transientRetryDelayMs);
            result = await request();
          }
          return result;
        } finally {
          processed += 1;
          onProgress({ processed, planned });
        }
      },
    });
  } catch {
    
    
    return failedMtuPdfBatch(eligible.length, businessDeferred);
  }
  if (processed < planned) {
    processed = planned;
    onProgress({ processed, planned });
  }
  if (businessDeferred === 0) return result;
  return {
    ...result,
    publicResult: {
      ...result.publicResult,
      deferred: result.publicResult.deferred + businessDeferred,
      remaining: result.publicResult.remaining + businessDeferred,
      batchComplete: false,
    },
  };
}
