(function registerWienerBiznesPolicyParser(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\s*:?\s*od\s+(\d{2}[.\-/]\d{2}[.\-/]\d{4})(?:\s+godz\s*\.?\s*\d{1,2}:\d{2})?\s+do\s+(\d{2}[.\-/]\d{2}[.\-/]\d{4})(?:\s+godz\s*\.?\s*\d{1,2}:\d{2})?/i,
    );
    return match ? [toIsoDate(match[1]), toIsoDate(match[2])] : ["", ""];
  }

  function findContact(allText) {
    const email = firstMatch(allText, [/Adres e-?mail\s*:\s*([^\s\n,;]+@[^\s\n,;]+)/i]);
    const phone = firstMatch(allText, [/Telefon kontaktowy\s*:\s*([+]?[0-9][0-9 ()-]{6,20})/i])
      .replace(/[()\s-]+/g, "");
    return [phone ? `Telefon: ${phone}` : "", email ? `E-mail: ${email}` : ""]
      .filter(Boolean)
      .join("\n");
  }

  function findPolicyHolderSection(allText) {
    const personalDataStartIndex = allText.search(/(?:^|\n)DANE OSOBOWE\b/i);
    const policyHolderStartIndex = allText.search(
      /(?:^|\n)Ubezpieczający(?:\s*,\s*Ubezpieczony)?\s*:?\s*(?:\n|$)/i,
    );
    const holderStartIndex = personalDataStartIndex >= 0
      ? personalDataStartIndex
      : policyHolderStartIndex;
    
    
    if (holderStartIndex < 0) return "";
    const holderRemainder = allText.slice(holderStartIndex);
    const holderEndIndex = holderRemainder.search(
      /\n(?:ZAKRES UBEZPIECZENIA|SKŁADKA I SPOSÓB PŁATNOŚCI)\b/i,
    );
    return holderEndIndex > 0
      ? holderRemainder.slice(0, holderEndIndex)
      : holderRemainder.slice(0, 2500);
  }

  
  
  
  function findBiznesRiskSummary(allText) {
    const amount = "([0-9][0-9 \\u00a0]{2,12})\\s*z\\u0142";
    const sectionDefinitions = [
      {
        label: "Budynki",
        suffix: "suma",
        marker: /Budynek kl\./i,
        pattern: new RegExp(`Budynek kl\\.[\\s\\S]{0,80}?Liczba budynk\\u00f3w\\s*:\\s*\\d+\\s+${amount}`, "i"),
      },
      {
        label: "Rzeczy ruchome",
        suffix: "suma",
        marker: /Rzeczy ruchome\s*,\s*w tym\s*:/i,
        pattern: new RegExp(`Rzeczy ruchome\\s*,\\s*w tym\\s*:\\s*${amount}`, "i"),
      },
      {
        label: "Kradzież z włamaniem i rozbój",
        suffix: "suma",
        marker: /Kradzież z włamaniem i rozbój/i,
        pattern: new RegExp(`${amount}\\s*-?\\s*Kradzie\\u017c z w\\u0142amaniem i rozb\\u00f3j`, "i"),
      },
      {
        label: "OC działalności",
        suffix: "suma",
        marker: /Odpowiedzialność cywilna/i,
        pattern: new RegExp(`Suma gwarancyjna[\\s\\S]{0,80}?${amount}[\\s\\S]{0,80}?Odpowiedzialno\\u015b\\u0107 cywilna`, "i"),
      },
      {
        label: "Szyby",
        suffix: "suma",
        marker: /Szyby i inne przedmioty szklane/i,
        pattern: new RegExp(`Szyby i inne przedmioty szklane\\s+${amount}`, "i"),
      },
      {
        label: "Przepięcia",
        suffix: "limit",
        marker: /Ubezpieczenie przepięcia/i,
        pattern: new RegExp(`Ubezpieczenie przepi\\u0119cia\\s+${amount}`, "i"),
      },
    ];
    const risks = [];
    const incompleteRisks = [];
    for (const {
      label, suffix, marker, pattern,
    } of sectionDefinitions) {
      const sum = firstMatch(allText, [pattern]);
      if (sum) risks.push(`${label} (${suffix} ${sum} zł)`);
      else if (marker.test(allText)) incompleteRisks.push(label);
    }
    const summary = risks.length > 0
      ? risks.join(" • ").slice(0, 400)
      : helpers.findRiskSummary(allText);
    return {
      summary,
      complete: incompleteRisks.length === 0,
    };
  }

  function parsePolicy({ allText }) {
    const period = findInsurancePeriod(allText);
    const holderSection = findPolicyHolderSection(allText);
    const seatAddress = firstMatch(holderSection, [/Siedziba\s*:\s*([^\n]{6,180})/i]);
    const riskDetails = findBiznesRiskSummary(allText);
    const policy = {
      clientName: firstMatch(holderSection, [
        /Nazwa\s*:\s*([^\n]{3,180})/i,
        /Imię i nazwisko\s*:\s*([^\n]{3,180})/i,
      ]),
      identityNumber: firstMatch(holderSection, [
        /NIP\s*:\s*([0-9][0-9 .-]{7,18})/i,
        /REGON\s*:\s*([0-9][0-9 .-]{7,18})/i,
        /Nr PESEL\s*:\s*(\d{11})/i,
        /PESEL\s*:\s*(\d{11})/i,
      ]).replace(/\D/g, ""),
      contact: findContact(holderSection),
      policyNumber: firstMatch(allText, [/Seria i numer\s*:?\s*([A-Z0-9/-]{6,})/i]),
      registration: "Firma",
      clientAddress: findClientAddress(seatAddress ? `Adres: ${seatAddress}` : holderSection),
      validFrom: period[0],
      validUntil: period[1],
      premium: cleanPremium(firstMatch(allText, [
        /Składka łączna\s*:\s*([0-9][0-9 .,' ]*)\s*zł/i,
        /([0-9][0-9 .,' ]*)\s*zł\s+Składka łączna/i,
      ])),
      riskSummary: riskDetails.summary,
    };
    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 BIZNES.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "Wiener";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium", "riskSummary"]
        .filter((fieldName) => !policy[fieldName] || (
          fieldName === "riskSummary" && !riskDetails.complete
        )),
    };
  }

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