(function registerDirectCommunicationPolicyParser(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,
    firstMatch,
    toIsoDate,
    normalizeVehicleIdentifier,
    findVehicleExtraDetails,
    findFirstRegistrationDate,
    cleanPremium,
  } = helpers;

  
  
  
  function buildRiskSummary(allText) {
    const riskDefinitions = [
      ["OC", /\bOC(?:\s+KOMUNIKAC[A-Z ]*)?\b/i],
      ["AC", /\bAC\b|AUTOCASCO/i],
      ["NNW", /\bNNW\b/i],
      ["Assistance", /ASSISTANCE(?:\s+PODSTAWOW[A-Z ]*)?/i],
      ["Zielona Karta", /\bZK\b|ZIELONA\s+KARTA/i],
      ["Kluczyki", /KLUCZYKI/i],
      ["Opony", /OPONY/i],
      ["Opieka po wypadku", /OPIEKA\s+PO\s+W[A-Z ]*PADKU/i],
    ];
    const risks = [];
    
    
    
    
    for (const match of allText.matchAll(/(\p{Lu}[\p{L} ]{1,30}?)\s+([0-9]+(?:[.,][0-9]{2})?)\s*zł/gu)) {
      const definition = riskDefinitions.find(([, pattern]) => pattern.test(match[1]));
      if (!definition || risks.some(([label]) => label === definition[0])) continue;
      risks.push([definition[0], normalizeLine(match[2]).replace(".", ",")]);
    }
    return risks
      .map(([label, amount]) => `${label} ${amount} zł`)
      .join(" • ")
      .slice(0, 400);
  }

  function findVehicle(allText) {
    const match = allText.match(
      /Marka\s*:\s*(\S[^\n:]*?)\s+Model\s*:\s*([^\n]+?)(?=\s+(?:Rok produkcji|samochód|Rodzaj)\b|$)/i,
    );
    return {
      vehicleMake: normalizeLine(match?.[1] || ""),
      vehicleModel: normalizeLine(match?.[2] || "").replace(/\s+samoch[óo]d osobowy$/i, ""),
    };
  }

  function parseDirectCommunicationPolicy({ allText }) {
    const holderText = firstMatch(allText, [
      /Dane Ubezpieczającego\s*:?([\s\S]{0,500}?)(?=Zakres ubezpieczenia|Dane Ubezpieczonego|Dane przedmiotu)/i,
    ]);
    const periodMatch = allText.match(
      /Okres ubezpieczenia\s*:\s*Od\s*:\s*(\d{2}[.\-]\d{2}[.\-]\d{4})[\s\S]{0,40}?(\d{2}[.\-]\d{2}[.\-]\d{4})/i,
    );
    const policy = {
      clientName: firstMatch(holderText || allText, [
        /Imię i Nazwisko(?:\s*\/\s*Nazwa)?\s*:\s*([^\n]+?)(?=\s+(?:PESEL|Identyfikator|Email|E-mail|Telefon)\b|$)/i,
      ]),
      identityNumber: firstMatch(holderText, [/(?:PESEL|NIP|REGON)\s*:\s*([0-9]{9,11})\b/i]),
      contact: "",
      policyNumber: firstMatch(allText, [/Numer polisy\s*:\s*([0-9]{6,})/i]),
      registration: firstMatch(allText, [/Numer rejestracyjny\s*:\s*([A-Z0-9]{4,10})/i])
        .toLocaleUpperCase("pl"),
      ...findVehicle(allText),
      vin: normalizeVehicleIdentifier(firstMatch(allText, [
        /Numer VIN\s*:\s*([A-Z0-9]{11,17})/i,
      ])),
      firstRegistrationDate: findFirstRegistrationDate(allText),
      ...findVehicleExtraDetails(allText),
      clientAddress: firstMatch(holderText, [
        /Adres zameldowania\/siedziby\s*:\s*([^\n]+)/i,
      ]),
      validFrom: periodMatch ? toIsoDate(periodMatch[1].replace(/-/g, ".")) : "",
      validUntil: periodMatch ? toIsoDate(periodMatch[2].replace(/-/g, ".")) : "",
      premium: cleanPremium(firstMatch(allText, [
        /Całkowita kwota składki\s*:\s*([0-9][0-9 .,]*)\s*(?:zł|PLN)/i,
        /Łączna kwota do zapłaty\s*:\s*([0-9][0-9 .,]*)\s*(?:zł|PLN)/i,
      ]).replace(".", ",")),
      riskSummary: buildRiskSummary(allText),
    };
    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 Direct.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "Direct";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium"]
        .filter((fieldName) => !policy[fieldName]),
    };
  }

  registry.register({
    id: "direct-komunikacja",
    insurer: "Direct",
    product: "Komunikacja",
    detect: ({ detectionText }) => /DIRECT POJISTOVNA/.test(detectionText)
      && /NUMER POLISY\s*:/.test(detectionText),
    parse: parseDirectCommunicationPolicy,
  });
})(globalThis);
