(function registerWienerTravelPolicyParser(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 { firstMatch, toIsoDate, findClientAddress, cleanPremium } = helpers;

  function findInsurancePeriod(allText) {
    const match = allText.match(
      /OKRES UBEZPIECZENIA[^\n:]*:\s*od\s*\/\s*from\s*\/[^0-9\n]*(\d{2}-\d{2}-\d{4})(?:\s+godz\.\s*\d{1,2}:\d{2})?\s+do\s*\/\s*at\s*\/[^0-9\n]*(\d{2}-\d{2}-\d{4})/i,
    );
    return match ? [toIsoDate(match[1]), toIsoDate(match[2])] : ["", ""];
  }

  function findTravelRiskSummary(allText) {
    const treatmentPremium = cleanPremium(firstMatch(allText, [
      /Koszty leczenia[^\n]*[\s\S]{0,600}?([0-9][0-9 .,'\u00a0]*)\s*zł/i,
    ]));
    const genericRisks = helpers.findRiskSummary(allText)
      .split(" • ")
      .filter((risk) => risk && !/^(?:Koszty leczenia|Assistance)(?:\s|$)/.test(risk));
    if (treatmentPremium) genericRisks.unshift(`Koszty leczenia i Assistance ${treatmentPremium} zł`);
    return genericRisks.join(" • ").slice(0, 400);
  }

  function parsePolicy({ allText }) {
    const period = findInsurancePeriod(allText);
    const holderStartIndex = allText.search(/DANE OSOBOWE/i);
    const holderRemainder = holderStartIndex >= 0 ? allText.slice(holderStartIndex) : allText;
    const holderEndIndex = holderRemainder.search(/\nZAKRES UBEZPIECZENIA/i);
    const holderSection = holderEndIndex > 0
      ? holderRemainder.slice(0, holderEndIndex)
      : holderRemainder.slice(0, 2500);
    const policy = {
      clientName: firstMatch(holderSection, [
        /Nazwa\s*\/\s*Name[^:]*:\s*([^\n]{3,180})/i,
        /Ubezpieczający[\s\S]{0,300}?Imię i nazwisko[^:]*:\s*([^\n]{3,180})/i,
      ]),
      identityNumber: firstMatch(holderSection, [
        /REGON[^:]*:\s*([0-9][0-9 .-]{6,19})/i,
        /NIP[^:]*:\s*([0-9][0-9 .-]{8,15})/i,
        /PESEL[^:]*:\s*(\d{11})/i,
      ]).replace(/\D/g, ""),
      contact: "",
      policyNumber: firstMatch(allText, [/Seria i numer\s+([A-Z0-9/-]{6,})/i]),
      registration: "Podróż",
      clientAddress: firstMatch(holderSection, [
        /Siedziba\s*\/\s*Registered office[^:]*:\s*([^\n]{3,180})/i,
        /Adres[^:]*:\s*([^\n]{3,180})/i,
      ]),
      validFrom: period[0],
      validUntil: period[1],
      premium: cleanPremium(firstMatch(allText, [
        /Składka łączna\s*\/\s*Total premium[^:]*:\s*([0-9][0-9 .,'\u00a0]*)\s*zł/i,
      ])),
      riskSummary: findTravelRiskSummary(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 z polisy Wiener Pakiet PODRÓŻ.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "Wiener";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium", "riskSummary"]
        .filter((fieldName) => !policy[fieldName]),
    };
  }

  registry.register({
    id: "wiener-podroz",
    insurer: "Wiener",
    product: "Pakiet PODRÓŻ",
    detect: ({ detectionText }) => /POLISA PAKIET PODROZ/.test(detectionText)
      && /COMPENSA/.test(detectionText)
      && /WIENER/.test(detectionText),
    parse: parsePolicy,
  });
})(globalThis);
