










import { createPortfolioIssueIdentityHash } from "./xombeztlyiegtybxtzkg.mjs";

const WIENER_PORTAL_HOST = "wienet.pl";
const WIENER_SEARCH_URL = "https://wienet.pl/api/Production/SearchProductionInfo";
const WIENER_PRINT_URL = "https://wienet.pl/api/Files/PrintPolicy";
const WIENER_API_PAGE_SIZE = 500;
const WIENER_API_MAX_PAGES = 40;
const WIENER_MIN_PDF_BYTES = 1000;
const WIENER_MAX_PDF_BYTES = 64 * 1024 * 1024;
const WIENER_PDF_FETCH_TIMEOUT_MS = 45_000;
export const WIENER_PORTFOLIO_COMPLETENESS_ERROR = "PORTFOLIO_COMPLETENESS_FAILED";

function throwWienerCompletenessError(reason) {
  const error = new Error("Nie można potwierdzić kompletności portfela Wiener. Import został przerwany.");
  error.code = WIENER_PORTFOLIO_COMPLETENESS_ERROR;
  error.reason = reason;
  throw error;
}

function addUniqueWienerItems(items, seenIds) {
  for (const item of items) {
    const policyId = String(item?.PolicyId ?? "").trim();
    const offerId = String(item?.OfferId ?? "").trim();
    const number = String(item?.Number ?? item?.policyNumber ?? "").trim().toUpperCase();
    const id = policyId
      ? `P:${policyId}`
      : offerId
        ? `O:${offerId}`
        : number
          ? `N:${number}`
          : "";
    if (!id || seenIds.has(id)) throwWienerCompletenessError(id ? "duplicate_item" : "missing_item_id");
    seenIds.add(id);
  }
}

const WIENER_ISSUE_DATE_FROM = "2015-01-01T00:00:00.000Z";

function compactText(value) {
  return String(value == null ? "" : value).replace(/\s+/g, " ").trim();
}

function getPageHostname(page) {
  try {
    return new URL(page.url()).hostname.toLowerCase();
  } catch {
    return "";
  }
}

export function isOnWienerPortal(page) {
  return getPageHostname(page) === WIENER_PORTAL_HOST;
}



function buildSearchBody(template, { pageNumber, pageSize, issueDateFrom, issueDateTo }) {
  const body = JSON.parse(JSON.stringify(template));
  const filter = body.Filter || (body.Filter = {});
  filter.pageSettings = {
    pageSize,
    pageNumber,
    sortColumn: 6,
    sortAscending: false,
  };
  filter.issueDateFrom = issueDateFrom || WIENER_ISSUE_DATE_FROM;
  filter.issueDateTo = issueDateTo;
  filter.showOnlyPolicies = false;
  filter.selectedProductSpecies = { Id: -1, Name: "", Param: null, ParamInt: null };
  filter.selectedProductType = { Id: 0, Name: "Wszystko", Param: null, ParamInt: null };
  filter.selectedStatusProduction = { Id: -1, Name: "", Param: null, ParamInt: null };
  filter.policyOrOfferNumber = null;
  filter.peselOrRegonOrNip = null;
  filter.lastNameOrCompanyName = null;
  filter.registrationNumber = null;
  return body;
}




function defaultSearchTemplate() {
  return {
    Filter: {
      searchingLevel: 1,
      restore: false,
      pageSettings: { pageSize: WIENER_API_PAGE_SIZE, pageNumber: 1, sortColumn: 6, sortAscending: false },
      selectedProductSpecies: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedDocumentSource: [{ Id: 0, Name: "Wszystko", Param: null, ParamInt: null }],
      selectedMobileOfferStatus: [{ Id: 0, Name: "Wszystko", Param: null, ParamInt: null }],
      selectedTelematicsStatuses: [{ Id: 0, Name: "Wszystko", Param: null, ParamInt: null }],
      selectedSettlementStatus: [],
      showOnlyPolicies: false,
      ignoreRemotePoliciesRestrictions: false,
      issueDateFrom: WIENER_ISSUE_DATE_FROM,
      issueDateTo: WIENER_ISSUE_DATE_FROM,
      defaultNumberOfMonthRangeForIssueDate: 1,
      policyOrOfferNumber: null,
      peselOrRegonOrNip: null,
      lastNameOrCompanyName: null,
      additionalExpanded: false,
      registrationNumber: null,
      selectedProductType: { Id: 0, Name: "Wszystko", Param: null, ParamInt: null },
      selectedStatusProduction: { Id: -1, Name: "", Param: null, ParamInt: null },
      startDateFrom: null,
      startDateTo: null,
      endDateFrom: null,
      endDateTo: null,
      selectedPolicyAnnexed: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedContractSource: { Id: 10, Name: "Wszystkie", Param: null, ParamInt: null },
      endAnnexDateFrom: null,
      endAnnexDateTo: null,
      pwAgencyCode: null,
      selectedAcceptanceStatus: { Id: 0, Name: "Wszystkie", Param: null, ParamInt: null },
      acceptanceFullNumber: null,
      nextInstallmentPaymentDateFrom: null,
      nextInstallmentPaymentDateTo: null,
    },
    FilterUserStructure: {
      selectedMs: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedAgencySalesChannel: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedAgency: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedRegion: { Id: -1, Name: "", Param: null, ParamInt: null },
      selectedUserStatus: { Id: 0, Name: "", Param: null, ParamInt: null },
      selectedUserType: { Id: 0, Name: "Wszystkie", Param: null, ParamInt: null },
      selectedWorker: { Id: -1, Name: "", Param: null, ParamInt: null },
    },
  };
}


async function fetchWienerSearchPage(page, { bearer, template, pageNumber, issueDateFrom, issueDateTo }) {
  const body = buildSearchBody(template, { pageNumber, pageSize: WIENER_API_PAGE_SIZE, issueDateFrom, issueDateTo });
  return page.evaluate(async ({ url, bearer: token, payload }) => {
    try {
      const response = await fetch(url, {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json", Accept: "application/json", Authorization: token },
        body: JSON.stringify(payload),
      });
      if (!response.ok) return { ok: false, status: response.status, items: [], total: 0 };
      const data = await response.json().catch(() => null);
      const value = data && data.Response ? data.Response : null;
      const items = value && Array.isArray(value.ProductionItems) ? value.ProductionItems : [];
      const total = value ? Number(value.ItemsCount) : Number.NaN;
      return { ok: Boolean(data && data.IsSuccess), status: response.status, items, total };
    } catch (error) {
      return { ok: false, status: 0, items: [], total: 0, error: String(error && error.message || error) };
    }
  }, { url: WIENER_SEARCH_URL, bearer, payload: body });
}




export async function fetchWienerProductionItems(page, { bearer, template = null, onProgress = () => {}, issueDateFrom = "" } = {}) {
  if (!bearer) throw new Error("Nie udało się rozpocząć pobierania polis. Spróbuj ponownie.");
  const searchTemplate = template || defaultSearchTemplate();
  const now = new Date();
  const issueDateTo = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 22, 0, 0)).toISOString();
  const issueFrom = /^\d{4}-\d{2}-\d{2}$/.test(issueDateFrom) ? `${issueDateFrom}T00:00:00.000Z` : "";

  const first = await fetchWienerSearchPage(page, { bearer, template: searchTemplate, pageNumber: 1, issueDateFrom: issueFrom, issueDateTo });
  if (!first.ok) {
    console.error(`Import Wiener: API portfela odpowiedziało błędem (status ${first.status || "sieciowy"}${first.error ? `: ${first.error}` : ""}).`);
    throw new Error("Nie udało się pobrać polis. Spróbuj ponownie za chwilę.");
  }
  const items = [...first.items];
  const total = Number(first.total);
  if (!Number.isSafeInteger(total) || total < 0) throwWienerCompletenessError("invalid_total");
  const pageQuantity = Math.max(1, Math.ceil(total / WIENER_API_PAGE_SIZE));
  if (pageQuantity > WIENER_API_MAX_PAGES) throwWienerCompletenessError("page_limit");
  const expectedFirstCount = Math.min(WIENER_API_PAGE_SIZE, total);
  if (items.length !== expectedFirstCount) throwWienerCompletenessError("short_page");
  const seenIds = new Set();
  addUniqueWienerItems(items, seenIds);
  onProgress({ collected: items.length, total, page: 1, pageQuantity });

  for (let pageNumber = 2; pageNumber <= pageQuantity; pageNumber += 1) {
    const slice = await fetchWienerSearchPage(page, { bearer, template: searchTemplate, pageNumber, issueDateFrom: issueFrom, issueDateTo });
    if (!slice.ok) {
      console.error(`Import Wiener: pobieranie przerwane na stronie ${pageNumber} (status ${slice.status || "sieciowy"}).`);
      throw new Error("Pobieranie polis zostało przerwane. Spróbuj ponownie za chwilę.");
    }
    if (!Number.isSafeInteger(Number(slice.total)) || Number(slice.total) !== total) {
      throwWienerCompletenessError("total_changed");
    }
    const expectedCount = Math.min(
      WIENER_API_PAGE_SIZE,
      Math.max(0, total - ((pageNumber - 1) * WIENER_API_PAGE_SIZE)),
    );
    if (slice.items.length !== expectedCount) throwWienerCompletenessError("short_page");
    addUniqueWienerItems(slice.items, seenIds);
    items.push(...slice.items);
    onProgress({ collected: items.length, total, page: pageNumber, pageQuantity });
  }
  if (items.length !== total) throwWienerCompletenessError("count_mismatch");
  return items;
}

function classifyWienerPdfHttpFailure(status) {
  const normalizedStatus = Number(status);
  
  
  
  if (normalizedStatus === 204) return { type: "document_failure", code: "not_found" };
  if (normalizedStatus >= 200 && normalizedStatus <= 299) {
    return { type: "global_failure", code: "portal_unavailable" };
  }
  if (normalizedStatus === 401) return { type: "global_failure", code: "session_expired" };
  if (normalizedStatus === 403) return { type: "global_failure", code: "authorization" };
  if (normalizedStatus === 408) return { type: "global_failure", code: "timeout" };
  if (normalizedStatus === 429) return { type: "global_failure", code: "rate_limited" };
  if (normalizedStatus >= 500 && normalizedStatus <= 599) {
    return { type: "global_failure", code: "portal_unavailable" };
  }
  if (normalizedStatus === 404) return { type: "document_failure", code: "not_found" };
  return { type: "global_failure", code: "unknown" };
}

function decodeWienerSuccessfulPdf(result) {
  const maximumBase64Length = Math.ceil(WIENER_MAX_PDF_BYTES / 3) * 4;
  if (
    typeof result?.base64 !== "string"
    || !Number.isSafeInteger(result.size)
    || result.size < WIENER_MIN_PDF_BYTES
    || result.size > WIENER_MAX_PDF_BYTES
    || result.base64.length !== Math.ceil(result.size / 3) * 4
    || result.base64.length > maximumBase64Length
    || result.base64.length % 4 !== 0
    || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(result.base64)
  ) {
    return { type: "document_failure", code: "invalid_pdf" };
  }
  let bytes;
  try {
    bytes = Buffer.from(result.base64, "base64");
  } catch {
    return { type: "document_failure", code: "invalid_pdf" };
  }
  if (
    bytes.byteLength !== result.size
    || bytes.toString("base64") !== result.base64
    || bytes[0] !== 0x25
    || bytes[1] !== 0x50
    || bytes[2] !== 0x44
    || bytes[3] !== 0x46
    || bytes[4] !== 0x2d
  ) {
    return { type: "document_failure", code: "invalid_pdf" };
  }
  return {
    type: "success",
    base64: result.base64,
    size: result.size,
  };
}




export async function downloadWienerPolicyPdfBase64(page, { bearer, number, policyId }) {
  const normalizedBearer = compactText(bearer);
  const normalizedNumber = compactText(number);
  const normalizedPolicyId = compactText(policyId);
  if (!normalizedNumber || !normalizedPolicyId) {
    return { type: "global_failure", code: "unknown" };
  }
  if (!normalizedBearer) {
    return { type: "global_failure", code: "authentication" };
  }

  let result;
  try {
    result = await page.evaluate(async ({
      fetchTimeoutMs,
      maxPdfBytes,
      minPdfBytes,
      url,
      bearer: token,
      num,
      pid,
    }) => {
      const mediaType = (response) => String(
        response?.headers?.get?.("content-type") || "",
      ).split(";", 1)[0].trim().toLowerCase();
      const isJsonMediaType = (value) => value === "application/json"
        || (
          value.includes("/")
          && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+\+json$/.test(value)
        );
      const classifyBodyPrefix = (buffer) => {
        const bytes = new Uint8Array(buffer);
        let offset = 0;
        const skipAsciiWhitespace = () => {
          while (
            offset < bytes.length
            && (
              bytes[offset] === 0x09
              || bytes[offset] === 0x0a
              || bytes[offset] === 0x0b
              || bytes[offset] === 0x0c
              || bytes[offset] === 0x0d
              || bytes[offset] === 0x20
            )
          ) {
            offset += 1;
          }
        };
        skipAsciiWhitespace();
        if (
          bytes[offset] === 0xef
          && bytes[offset + 1] === 0xbb
          && bytes[offset + 2] === 0xbf
        ) {
          offset += 3;
          skipAsciiWhitespace();
        }
        let prefix = "";
        try {
          prefix = String.fromCharCode.apply(
            null,
            bytes.subarray(offset, Math.min(bytes.length, offset + 512)),
          ).toLowerCase();
        } catch {
          return "download_failure";
        }
        if (prefix.startsWith("<")) return "session_content";
        if (prefix.startsWith("{") || prefix.startsWith("[")) {
          return "unexpected_content_type";
        }
        return "";
      };
      const readBodyWithinLimit = async (response) => {
        let rawContentLength = null;
        try {
          rawContentLength = response?.headers?.get?.("content-length");
        } catch {
          return { kind: "unexpected_content_type" };
        }
        if (rawContentLength !== null && rawContentLength !== "") {
          const contentLength = String(rawContentLength).trim();
          if (!/^\d+$/.test(contentLength)) {
            return { kind: "unexpected_content_type" };
          }
          const declaredBytes = Number(contentLength);
          if (!Number.isSafeInteger(declaredBytes)) {
            return { kind: "unexpected_content_type" };
          }
          if (declaredBytes > maxPdfBytes) {
            try {
              const cancellation = response.body?.cancel?.();
              cancellation?.catch?.(() => {});
            } catch {
            }
            return { kind: "invalid_pdf" };
          }
        }

        if (response?.body && typeof response.body.getReader === "function") {
          let reader;
          try {
            reader = response.body.getReader();
          } catch {
            return { kind: "network" };
          }
          const chunks = [];
          let totalBytes = 0;
          while (true) {
            let step;
            try {
              step = await reader.read();
            } catch (error) {
              return {
                kind: error?.name === "AbortError" ? "timeout" : "network",
              };
            }
            if (!step || typeof step !== "object") return { kind: "network" };
            if (step.done) break;
            let chunk;
            if (step.value instanceof Uint8Array) {
              chunk = step.value;
            } else if (step.value instanceof ArrayBuffer) {
              chunk = new Uint8Array(step.value);
            } else {
              return { kind: "network" };
            }
            if (chunk.byteLength > maxPdfBytes - totalBytes) {
              try {
                const cancellation = reader.cancel();
                cancellation?.catch?.(() => {});
              } catch {
              }
              return { kind: "invalid_pdf" };
            }
            totalBytes += chunk.byteLength;
            chunks.push(chunk);
          }
          const buffer = new ArrayBuffer(totalBytes);
          const target = new Uint8Array(buffer);
          let offset = 0;
          for (const chunk of chunks) {
            target.set(chunk, offset);
            offset += chunk.byteLength;
          }
          return { kind: "body", buffer };
        }

        let buffer;
        try {
          buffer = await response.arrayBuffer();
        } catch (error) {
          return {
            kind: error?.name === "AbortError" ? "timeout" : "network",
          };
        }
        if (
          !buffer
          || !(buffer instanceof ArrayBuffer)
          || !Number.isSafeInteger(buffer.byteLength)
          || buffer.byteLength < 0
        ) {
          return { kind: "network" };
        }
        if (buffer.byteLength > maxPdfBytes) return { kind: "invalid_pdf" };
        return { kind: "body", buffer };
      };
      const toBase64 = (buffer) => {
        const bytes = new Uint8Array(buffer);
        let binary = "";
        for (let offset = 0; offset < bytes.length; offset += 0x8000) {
          binary += String.fromCharCode.apply(
            null,
            bytes.subarray(offset, offset + 0x8000),
          );
        }
        return btoa(binary);
      };

      const controller = new AbortController();
      const timer = setTimeout(() => controller.abort(), fetchTimeoutMs);
      try {
        const query = `?number=${encodeURIComponent(num)}&policyId=${encodeURIComponent(btoa(String(pid)))}`;
        const response = await fetch(url + query, {
          credentials: "include",
          headers: { Accept: "application/pdf", Authorization: token },
          signal: controller.signal,
        });
        if (response?.redirected) return { kind: "redirected" };
        const status = Number(response?.status);
        if (status !== 200) return { kind: "http", status };

        const type = mediaType(response);
        if (type === "text/html" || type === "application/xhtml+xml") {
          return { kind: "session_content" };
        }
        if (
          isJsonMediaType(type)
          || (
            type
            && type !== "application/pdf"
            && type !== "application/octet-stream"
          )
        ) {
          return { kind: "unexpected_content_type" };
        }

        const body = await readBodyWithinLimit(response);
        if (body.kind !== "body") return body;
        const prefixKind = classifyBodyPrefix(body.buffer);
        if (prefixKind) return { kind: prefixKind };
        if (body.buffer.byteLength < minPdfBytes) return { kind: "invalid_pdf" };
        const bytes = new Uint8Array(body.buffer);
        if (!(
          bytes[0] === 0x25
          && bytes[1] === 0x50
          && bytes[2] === 0x44
          && bytes[3] === 0x46
          && bytes[4] === 0x2d
        )) return { kind: "invalid_pdf" };
        try {
          return {
            kind: "success",
            base64: toBase64(body.buffer),
            size: bytes.byteLength,
          };
        } catch {
          return { kind: "download_failure" };
        }
      } catch (error) {
        return {
          kind: error?.name === "AbortError" ? "timeout" : "network",
        };
      } finally {
        clearTimeout(timer);
      }
    }, {
      fetchTimeoutMs: WIENER_PDF_FETCH_TIMEOUT_MS,
      maxPdfBytes: WIENER_MAX_PDF_BYTES,
      minPdfBytes: WIENER_MIN_PDF_BYTES,
      url: WIENER_PRINT_URL,
      bearer: normalizedBearer,
      num: normalizedNumber,
      pid: normalizedPolicyId,
    });
  } catch {
    return { type: "global_failure", code: "navigation" };
  }

  if (result?.kind === "success") return decodeWienerSuccessfulPdf(result);
  if (result?.kind === "network") return { type: "global_failure", code: "network" };
  if (result?.kind === "timeout") return { type: "global_failure", code: "timeout" };
  if (result?.kind === "redirected" || result?.kind === "session_content") {
    return { type: "global_failure", code: "session_expired" };
  }
  if (result?.kind === "unexpected_content_type") {
    return { type: "global_failure", code: "portal_unavailable" };
  }
  if (result?.kind === "http") return classifyWienerPdfHttpFailure(result.status);
  if (result?.kind === "invalid_pdf") {
    return { type: "document_failure", code: "invalid_pdf" };
  }
  if (result?.kind === "download_failure") {
    return { type: "document_failure", code: "download_failed" };
  }
  return { type: "global_failure", code: "unknown" };
}



const WIENER_PRODUCT_TYPE_LABELS = {
  1: "Auto",
  2: "Rolne",
  7: "Firma",
  10: "Inne",
  38: "Mieszkanie",
  40: "Podróż",
};


const WIENER_NUMBER_PREFIX_LABELS = {
  KOM: "Auto", KWA: "Auto", KPD: "Auto", KPC: "Auto",
  RPA: "Rolne",
  POD: "Podróż", TPA: "Podróż",
  NNW: "Inne",
  SME: "Firma", BPA: "Firma", PWC: "Mieszkanie",
};


const WIENER_STATUS_LABELS = {
  1: "Kalkulacja",
  3: "Oferta",
  5: "Polisa zatwierdzona",
  6: "Polisa anulowana",
  7: "Polisa wystawiona",
};

function normalizeWienerRegistration(value) {
  return compactText(value).replace(/[^A-Za-z0-9]/g, "").toUpperCase();
}


function resolveWienerIdentity(item) {
  const pesel = compactText(item?.PersonalCode).replace(/\D/g, "");
  if (/^\d{11}$/.test(pesel)) return pesel;
  const nip = compactText(item?.TaxCode).replace(/\D/g, "");
  if (/^\d{10}$/.test(nip)) return nip;
  const regon = compactText(item?.CompanyCode).replace(/\D/g, "");
  if (/^\d{9}$/.test(regon) || /^\d{14}$/.test(regon)) return regon;
  return pesel || nip || regon;
}

function formatWienerPremium(amount) {
  const value = Number(amount);
  if (!Number.isFinite(value) || value <= 0) return "";
  const fixed = value.toFixed(2);
  return fixed.endsWith(".00") ? fixed.slice(0, -3) : fixed.replace(".", ",");
}


function resolveWienerVehicleMake(item) {
  const brand = compactText(item?.VehicleBrand);
  if (brand) return brand;
  const data = compactText(item?.VehicleData);
  const match = data.match(/^([A-Za-zĄĆĘŁŃÓŚŹŻąćęłńóśźż.\- ]+?)\s+[A-Z0-9]{4,8}\s*\(/);
  return match ? compactText(match[1]) : "";
}

function resolveWienerRegistration(item) {
  const plate = normalizeWienerRegistration(item?.RegistrationNumber);
  if (plate.length >= 4 && plate.length <= 10) return plate;
  const label = WIENER_PRODUCT_TYPE_LABELS[Number(item?.ProductType)];
  if (label) return label;
  const prefix = compactText(item?.Number).slice(0, 3).toUpperCase();
  return WIENER_NUMBER_PREFIX_LABELS[prefix] || "Inne";
}




export function mapWienerProductionItems(items, {
  minEndDate = "",
  mappingCollector = null,
} = {}) {
  const records = [];
  const seen = new Set();
  for (const item of Array.isArray(items) ? items : []) {
    if (item?.IsPolicy !== true) {
      mappingCollector?.recordFiltered("NON_POLICY_ITEM");
      continue;
    }
    const status = Number(item?.Status);
    if (status === 6) {
      mappingCollector?.recordFiltered("CANCELLED_POLICY");
      continue;
    }
    const policyNumber = compactText(item?.Number);
    const clientName = compactText(item?.Insurer);
    const validFrom = compactText(item?.StartDate).slice(0, 10);
    const endDate = compactText(item?.EndDate).slice(0, 10);
    const normalizedPolicyNumber = policyNumber.replace(/[^0-9A-Za-z]/g, "").toLowerCase();
    if (!normalizedPolicyNumber || !clientName) {
      let identityHash = "";
      try {
        identityHash = createPortfolioIssueIdentityHash({
          insurer: "Wiener",
          sourceId: item?.PolicyId != null ? String(item.PolicyId) : "",
          policyNumber,
          validFrom,
          validUntil: endDate,
        });
      } catch {
      }
      mappingCollector?.recordRejected("MISSING_REQUIRED_FIELDS", { identityHash });
      continue;
    }
    if (minEndDate && endDate && endDate < minEndDate) {
      mappingCollector?.recordFiltered("OUTSIDE_DATE_RANGE");
      continue;
    }
    const key = `${normalizedPolicyNumber}\0${validFrom}\0${endDate}`;
    if (seen.has(key)) {
      mappingCollector?.recordDuplicate();
      continue;
    }
    seen.add(key);

    const phone = compactText(item?.PhoneNumber);
    const email = compactText(item?.Email);
    const contactParts = [];
    if (phone) contactParts.push(`Telefon: ${phone}`);
    if (email) contactParts.push(`E-mail: ${email}`);

    records.push({
      insurer: "Wiener",
      policyNumber,
      policyId: item?.PolicyId != null ? String(item.PolicyId) : "",
      clientName: clientName.slice(0, 160),
      identityNumber: resolveWienerIdentity(item),
      contact: contactParts.join("\n"),
      clientAddress: compactText(item?.InsurancePlace),
      registration: resolveWienerRegistration(item),
      vehicleMake: resolveWienerVehicleMake(item),
      vehicleModel: "",
      vin: normalizeWienerRegistration(item?.VINNumber),
      validFrom,
      validUntil: endDate,
      issueDate: compactText(item?.IssueDate ?? item?.CreationDate ?? item?.CreatedAt).slice(0, 10),
      premium: formatWienerPremium(item?.Premium),
      status: WIENER_STATUS_LABELS[status] || "",
      pdfAvailable: false,
    });
    mappingCollector?.recordMapped();
  }
  return records;
}
