(function registerPzuTravelPolicyParser(globalScope) {
  "use strict";

  const registry = globalScope.PolicyPdfParserRegistry;
  const helpers = globalScope.PolicyPdfParserHelpers;
  if (!registry || !helpers) throw new Error("Najpierw wczytaj wspólny silnik importu polis PDF.");

  const { normalizeForDetection, firstMatch, toIsoDate, cleanPremium } = helpers;

  
  
  
  function findAmount(allText, patterns) {
    return firstMatch(allText, patterns).replace(/\s+/g, " ");
  }

  function buildTravelRiskSummary(allText) {
    const risks = [];
    const medical = findAmount(allText, [/Koszty leczenia[^\n]{0,80}?([0-9][0-9  ]{2,12})\s*zł/i]);
    risks.push(medical ? `Koszty leczenia (suma ${medical} zł)` : "Koszty leczenia");
    if (/Assistance/i.test(allText)) risks.push("Assistance");
    const accident = findAmount(allText, [/śmierci i trwałego uszczerbku[^\n]{0,100}?([0-9][0-9  ]{2,12})\s*zł/i]);
    if (accident) risks.push(`NNW (suma ${accident} zł)`);
    else if (/nieszczęśliwych wypadków/i.test(allText)) risks.push("NNW");
    const liability = findAmount(allText, [/Odpowiedzialność cywilna w życiu prywatnym[\s\S]{0,160}?Zakres podstawowy[^\n]{0,60}?([0-9][0-9  ]{2,12})\s*zł/i]);
    if (liability) risks.push(`OC w życiu prywatnym (suma ${liability} zł)`);
    else if (/Odpowiedzialność cywilna w życiu prywatnym/i.test(allText)) risks.push("OC w życiu prywatnym");
    const luggage = findAmount(allText, [/Bagaż podróżny[^\n]{0,60}?([0-9][0-9  ]{2,12})\s*zł/i]);
    if (luggage) risks.push(`Bagaż (suma ${luggage} zł)`);
    else if (/Bagaż podróżny/i.test(allText)) risks.push("Bagaż");
    const destination = firstMatch(allText, [
      /PZU WOJAŻER\s*\n([A-ZĄĆĘŁŃÓŚŹŻ][\p{L} ]{2,40})\s*\n/u,
    ]);
    if (destination && !/Umowa/i.test(destination)) risks.unshift(`Podróż: ${destination}`);
    return risks.join(" • ").slice(0, 400);
  }

  function findContact(allText) {
    const rawEmail = firstMatch(allText, [/E-?mail\s*:\s*([^\n]+?)(?=\s+Telefon\s*:|$)/i]);
    const rawPhone = firstMatch(allText, [/Telefon\s*:\s*([^\n]+)/i]);
    const email = /@/.test(rawEmail) && !/NIEUSTALON|ODMOW/i.test(normalizeForDetection(rawEmail))
      ? rawEmail
      : "";
    const phoneDigits = rawPhone.replace(/\D/g, "");
    const phone = phoneDigits.length >= 7 && !/NIEUSTALON|ODMOW/i.test(normalizeForDetection(rawPhone))
      ? rawPhone.replace(/[()\s-]+/g, "")
      : "";
    return [
      phone ? `Telefon: ${phone}` : "",
      email ? `E-mail: ${email}` : "",
    ].filter(Boolean).join("\n");
  }

  function parsePzuTravelPolicy({ allText }) {
    const holderLine = firstMatch(allText, [
      /Ubezpieczający\s*\/?\s*(?:Policyholder)?\s*:\s*([^\n]+)/i,
    ]);
    const clientName = holderLine.replace(/\s*(?:PESEL|NIP|REGON)\s*:.*$/i, "").trim();
    const holderBlock = firstMatch(allText, [
      /(Ubezpieczający\s*\/?\s*(?:Policyholder)?\s*:[\s\S]{0,300}?)(?=Cel podróży|Ubezpieczony 1|Zakres ubezpieczenia)/i,
    ]);
    const periodMatch = allText.match(
      /Okres ubezpieczenia[^:\n]*:\s*od\s+(\d{2}\.\d{2}\.\d{4})\s+do\s+(\d{2}\.\d{2}\.\d{4})/i,
    );
    const policy = {
      clientName,
      identityNumber: firstMatch(holderBlock || allText, [
        /(?:PESEL|NIP|REGON)\s*:\s*([0-9][0-9 .-]{7,18})/i,
      ]).replace(/\D/g, ""),
      contact: findContact(holderBlock),
      policyNumber: firstMatch(allText, [/Numer polisy\s+([0-9A-Z/-]{6,})/i]),
      registration: "Podróż",
      clientAddress: helpers.findClientAddress(holderBlock),
      validFrom: periodMatch ? toIsoDate(periodMatch[1]) : "",
      validUntil: periodMatch ? toIsoDate(periodMatch[2]) : "",
      premium: cleanPremium(firstMatch(allText, [
        /Składka łączna\s*:?\s*([0-9][0-9 .,' ]*)\s*(?:zł|PLN)/i,
      ])),
      riskSummary: buildTravelRiskSummary(allText),
    };
    const missingRequiredFields = ["clientName", "policyNumber", "validUntil"]
      .filter((fieldName) => !policy[fieldName]);
    if (missingRequiredFields.length > 0) {
      const error = new Error("Nie udało się pewnie odczytać danych klienta, numeru polisy lub okresu z polisy PZU Wojażer.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "PZU";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium"]
        .filter((fieldName) => !policy[fieldName]),
    };
  }

  registry.register({
    id: "pzu-wojazer",
    insurer: "PZU",
    product: "Wojażer (podróż)",
    detect: ({ detectionText }) => /POLISA UBEZPIECZENIA PZU WOJAZER/.test(detectionText)
      && /POWSZECHNY ZAKLAD UBEZPIECZEN/.test(detectionText),
    parse: parsePzuTravelPolicy,
  });
})(globalThis);
