(function registerTrastiCommunicationPolicyParser(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,
    normalizeVehicleIdentifier,
    findVehicleMakeAndModel,
    findFirstRegistrationDate,
    findVehicleExtraDetails,
    findClientAddress,
    cleanPremium,
  } = helpers;

  function findTrastiClientAddress(lines) {
    const nameIndex = lines.findIndex((line) => /Imi\s*ę\s+i\s+nazwisko/i.test(line));
    if (nameIndex < 0) return "";
    return findClientAddress(lines.slice(nameIndex, nameIndex + 8).join("\n"));
  }

  function findInsurancePeriod(allText) {
    const match = allText.match(
      /Okres ubezpieczenia\s+od\s+(\d{2}\.\d{2}\.\d{4})(?:\s+\d{1,2}:\d{2})?\s+do\s+(\d{2}\.\d{2}\.\d{4})(?:\s+\d{1,2}:\d{2})?/i,
    );
    return match ? [toIsoDate(match[1]), toIsoDate(match[2])] : ["", ""];
  }

  function parseTrastiCommunicationPolicy({ lines, allText }) {
    const insurancePeriod = findInsurancePeriod(allText);
    const policy = {
      clientName: firstMatch(allText, [
        /Ubezpieczaj\s*ą\s*cy\s+([^\n]{3,120})/i,
        /Imi\s*ę\s+i nazwisko\s+([^\n]{3,120})/i,
      ]),
      identityNumber: firstMatch(allText, [
        /Pesel\s*:?[ \t]*(\d{11})/i,
      ]),
      contact: "",
      policyNumber: firstMatch(allText, [
        /Polisa nr\s*:\s*([0-9A-Z/-]{6,})/i,
      ]),
      registration: firstMatch(allText, [
        /Nr rejestracyjny\s*:?[ \t]*([A-Z0-9][A-Z0-9 -]{3,11})/i,
      ]).replace(/\s+/g, "").toLocaleUpperCase("pl"),
      ...findVehicleMakeAndModel(allText),
      vin: normalizeVehicleIdentifier(firstMatch(allText, [
        /(?:Nr\s+VIN|VIN)\s*:?[ \t]*([A-Z0-9][A-Z0-9 -]{3,23})/i,
      ])),
      firstRegistrationDate: findFirstRegistrationDate(allText),
      ...findVehicleExtraDetails(allText),
      clientAddress: findTrastiClientAddress(lines),
      validFrom: insurancePeriod[0],
      validUntil: insurancePeriod[1],
      premium: cleanPremium(firstMatch(allText, [
        /Sk\s*ł\s*adka\s+łą\s*cznie(?:\s*\(w tym OC\))?\s+([0-9][0-9 .,'\u00a0]*)\s*z\s*ł/i,
      ])),
      riskSummary: helpers.findRiskSummary(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 Trasti.");
      error.code = "POLICY_FIELDS_MISSING";
      error.insurer = "Trasti";
      error.missingFields = missingRequiredFields;
      throw error;
    }
    return {
      policy,
      missingOptionalFields: ["identityNumber", "validFrom", "premium"]
        .filter((fieldName) => !policy[fieldName]),
    };
  }

  registry.register({
    id: "trasti-komunikacja",
    insurer: "Trasti",
    product: "Komunikacja",
    detect: ({ detectionText }) => /\bTRASTI\b/.test(detectionText)
      && /HPI GMA/.test(detectionText)
      && /POLISA NR/.test(detectionText),
    parse: parseTrastiCommunicationPolicy,
  });
})(globalThis);
