(function registerTuzCommunicationPolicyParser(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 {
    normalizeLine,
    normalizeForDetection,
    firstMatch,
    normalizeVehicleIdentifier,
    splitVehicleMakeAndModel,
    findVehicleExtraDetails,
    cleanPremium,
  } = helpers;

  
  
  
  function findLineAboveLabel(lines, labelPattern) {
    const labelIndex = lines.findIndex((line) => labelPattern.test(normalizeForDetection(line)));
    return labelIndex > 0 ? normalizeLine(lines[labelIndex - 1]) : "";
  }

  function parseTuzCommunicationPolicy({ lines, allText }) {
    const holderLine = findLineAboveLabel(lines, /^IMIE I NAZWISKO \/ NAZWA PODMIOTU\b/);
    const holderMatch = holderLine.match(/^(.+?)\s+([0-9]{9,11})\b/);
    const addressLine = findLineAboveLabel(lines, /^KOD POCZTOWY MIEJSCOWOSC\b/);
    
    
    
    const vehicleSectionIndex = lines.findIndex((line) => /^DANE POJAZDU$/.test(normalizeForDetection(line)));
    let vehicleMatch = null;
    for (let offset = 1; offset <= 5 && vehicleSectionIndex >= 0 && vehicleSectionIndex + offset < lines.length; offset += 1) {
      vehicleMatch = normalizeLine(lines[vehicleSectionIndex + offset])
        .match(/^([A-Z]{2,3}[0-9A-Z]{4,7})\s+([A-ZĄĆĘŁŃÓŚŹŻ-]{2,})\s+(.*)$/);
      if (vehicleMatch) break;
    }
    const seriesMatch = allText.match(/POLISA i WNIOSEK\s+seria\s+([A-Z]{2,4})\s+nr\s+([0-9]{5,})/i);
    const periodMatch = allText.match(
      /Okres ubezpieczenia\s+\w{0,4}\s*od\s+(\d{4}-\d{2}-\d{2})\s+do\s+(\d{4}-\d{2}-\d{2})/i,
    );
    const premium = cleanPremium(firstMatch(allText, [
      /Łączna kwota do zapłaty[^\n0-9]{0,30}([0-9][0-9 .,]*)\s*zł/i,
      /Składka\s+([0-9][0-9.,]*)\s*zł/i,
    ]).replace(".", ","));
    const ocPremium = cleanPremium(firstMatch(allText, [
      /Okres ubezpieczenia OCK[\s\S]{0,120}?Składka\s+([0-9][0-9.,]*)\s*zł/i,
    ]).replace(".", ","));
    const policy = {
      clientName: normalizeLine(holderMatch?.[1] || ""),
      identityNumber: holderMatch?.[2] || "",
      contact: "",
      policyNumber: seriesMatch ? `${seriesMatch[1].toLocaleUpperCase("pl")}${seriesMatch[2]}` : "",
      registration: (vehicleMatch?.[1] || "").toLocaleUpperCase("pl"),
      ...(vehicleMatch
        ? { vehicleMake: vehicleMatch[2], vehicleModel: normalizeLine(vehicleMatch[3]).slice(0, 120) }
        : splitVehicleMakeAndModel("")),
      vin: normalizeVehicleIdentifier(firstMatch(allText, [/\b([A-HJ-NPR-Z0-9]{17})\b/])),
      firstRegistrationDate: "",
      ...findVehicleExtraDetails(allText),
      clientAddress: addressLine,
      validFrom: periodMatch ? periodMatch[1] : "",
      validUntil: periodMatch ? periodMatch[2] : "",
      premium,
      riskSummary: /UBEZPIECZENIE ODPOWIEDZIALNOSCI CYWILNEJ POSIADACZY POJAZDOW/.test(normalizeForDetection(allText))
        ? (ocPremium ? `OC ${ocPremium} zł` : "OC")
        : "",
    };
    const missingRequiredFields = ["clientName", "policyNumber", "registration", "validUntil"]
      .filter((fieldName) => !policy[fieldName]);
    if (missingRequiredFields.length > 0) {
      const error = new Error("Nie udało się pewnie odczytać danych klienta, numeru polisy, rejestracji lub okresu z polisy TUZ.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "TUZ";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium"]
        .filter((fieldName) => !policy[fieldName]),
    };
  }

  registry.register({
    id: "tuz-komunikacja",
    insurer: "TUZ",
    product: "Komunikacja",
    detect: ({ detectionText }) => /TUZ UBEZPIECZENIA TOWARZYSTWO UBEZPIECZEN/.test(detectionText)
      && /POLISA I WNIOSEK\s+SERIA/.test(detectionText),
    parse: parseTuzCommunicationPolicy,
  });
})(globalThis);
