














import { bringPageWindowToFront } from "./etrzxtbsmrmtpfpyetfs.mjs";
import {
  preparePzuPortfolioPdfEntries,
  runPzuPortfolioPdfBatch,
} from "./rrggzdzfzkivpjgwfgpo.mjs";
import {
  enrichPzuPremiums,
  enrichPzuVehicleInfo,
  filterPzuRowsSince,
  isOnPzuEverest,
  makePzuPolicyPeriodKey,
  mapPzuPolicyRows,
  scrapePzuPolicyRows,
} from "./yaxipmszsvwumoupiueuomtrrrwvtxmfjdeeikliqxv.mjs";
import {
  assertPortfolioMappingComplete,
  createPortfolioEmissionResult,
  createPortfolioMappingCollector,
} from "./fgroazrhswhewnaqxvgl.mjs";
import {
  countUnskippedPortfolioPdfSelectors,
} from "./abywezhrsiqkqfhujfvq.mjs";
import { createPortfolioPdfIdentity } from "./ldpwrbpjqvuxzylkmjve.mjs";

const PZU_URL = "https://everest.pzu.pl/pc/PolicyCenter.do";
const PZU_GATEWAY_URL = "https://everest.pzu.pl/";

const PZU_LOGGED_IN_SELECTOR = "#TabBar-DesktopTab";

const PZU_POLICIES_PARENT_SELECTOR = "#Desktop-MenuLinks-Desktop_PolicyLocationPzu";

const PZU_MY_POLICIES_LINK_SELECTOR = "#Desktop-MenuLinks-Desktop_PolicyLocationPzu-PolicyLocationPzu_DesktopPoliciesPzu";

const PZU_DESKTOP_TAB_SELECTOR = "#TabBar-DesktopTab";
const PZU_GRID_PAGING_SELECTOR = "#DesktopPoliciesPzu-DesktopPoliciesScreen-DesktopPoliciesLV-_ListPaging";



const PZU_FILTER_MODE_SELECT_NAME = "DesktopPoliciesPzu-DesktopPoliciesScreen-mainQueryActivity";
const PZU_FILTER_SEARCH_BUTTON_SELECTOR = "#DesktopPoliciesPzu-DesktopPoliciesScreen-PolicyFilterPzuDV-ToolbarButtonSearch";
const PZU_PAGING_INFO_SELECTOR = ".gw--paging-info";


const PZU_INCREMENTAL_WINDOW_DAYS = 25;

function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

function formatDateYmd(date) {
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
}

function normalizePzuPolicyKey(value) {
  return String(value || "").replace(/[^0-9A-Za-z]/g, "");
}


function normalizePdfKey(value) {
  return String(value || "").replace(/[^0-9A-Za-z]/g, "").toUpperCase();
}




export function buildPzuPolicySets(rows, {
  sinceDate = "",
  minEndDate = "",
  includeFullPortfolio = false,
  mappingCollector = null,
} = {}) {
  const freshRows = filterPzuRowsSince(rows, sinceDate);
  const mappedPolicies = mapPzuPolicyRows(rows, { minEndDate, mappingCollector });
  const freshKeys = new Set(
    freshRows.map((row) => makePzuPolicyPeriodKey(row)).filter(Boolean),
  );
  const freshPolicies = sinceDate
    ? mappedPolicies.filter((policy) => freshKeys.has(makePzuPolicyPeriodKey(policy)))
    : mappedPolicies;
  return {
    freshPolicies,
    allPolicies: includeFullPortfolio ? mappedPolicies : freshPolicies,
  };
}

function emptyPzuPdfRetry() {
  return {
    attempted: 0,
    succeeded: 0,
    failed: 0,
    backoff: 0,
    quarantined: 0,
    unsupported: 0,
    deferred: 0,
    remaining: 0,
    batchComplete: true,
    circuitOpen: false,
    circuitCode: null,
    manualRetryAvailable: false,
  };
}

export function buildPzuImportCompletion({
  freshCount = 0,
  downloadPdfs = false,
  pdfOutcome = null,
} = {}) {
  const normalizedFreshCount = Number.isSafeInteger(freshCount) && freshCount >= 0
    ? freshCount
    : 0;
  if (!downloadPdfs) {
    return {
      freshCount: normalizedFreshCount,
      pdfSaved: null,
      pdfRemaining: null,
      pdfRetry: null,
      pdfRetryIdentities: [],
    };
  }
  return {
    freshCount: normalizedFreshCount,
    pdfSaved: Number.isSafeInteger(pdfOutcome?.saved)
      ? pdfOutcome.saved
      : 0,
    pdfRemaining: Number.isSafeInteger(pdfOutcome?.remaining)
      ? pdfOutcome.remaining
      : 0,
    pdfRetry: pdfOutcome?.pdfRetry || emptyPzuPdfRetry(),
    pdfRetryIdentities: Array.isArray(pdfOutcome?.pdfRetryIdentities)
      ? pdfOutcome.pdfRetryIdentities
      : [],
  };
}






export async function runPzuPortfolioPdfPhase({
  page,
  retryStore,
  pdfDirectory,
  policies,
  onProgress = () => {},
  skipPolicyNumbers = [],
  knownPolicyNumbers = [],
  limit = null,
  minBatchSize = 3,
  maxBatchSize = 7,
  batchPauseMs = null,
} = {}) {
  if (limit !== null && (!Number.isSafeInteger(limit) || limit <= 0)) {
    throw new TypeError("limit musi byc dodatnia liczba calkowita.");
  }
  if (
    !Number.isSafeInteger(minBatchSize) || minBatchSize <= 0
    || !Number.isSafeInteger(maxBatchSize) || maxBatchSize < minBatchSize
  ) {
    throw new TypeError("Rozmiar partii PDF musi byc dodatnim zakresem calkowitym.");
  }
  if (batchPauseMs !== null && (!Number.isSafeInteger(batchPauseMs) || batchPauseMs < 0)) {
    throw new TypeError("Przerwa miedzy partiami PDF musi byc nieujemna liczba.");
  }
  const eligible = preparePzuPortfolioPdfEntries({
    policies,
    skipPolicyNumbers,
    knownPolicyNumbers,
  });
  if (eligible.length === 0) {
    onProgress({
      status: "running",
      title: "Pobieranie PDF-ów pominięte",
      detail: "Wszystkie polisy mają już podpięte pliki.",
    });
    return {
      attempted: 0,
      saved: 0,
      remaining: 0,
      pdfRetry: emptyPzuPdfRetry(),
      pdfRetryIdentities: [],
    };
  }

  const totalQueued = eligible.length;
  const retryStoreReady = retryStore
    && typeof retryStore.getDecisions === "function"
    && typeof retryStore.recordFailures === "function"
    && typeof retryStore.recordSuccesses === "function"
    && typeof retryStore.markUnsupported === "function";
  if (!retryStoreReady) {
    onProgress({
      status: "running",
      title: "Pobieranie PDF-ów odłożone",
      detail: "Faza dokumentów została bezpiecznie zatrzymana; polisy nadal zostaną zaimportowane.",
    });
    return {
      attempted: 0,
      saved: 0,
      remaining: totalQueued,
      pdfRetry: {
        ...emptyPzuPdfRetry(),
        deferred: totalQueued,
        remaining: totalQueued,
        batchComplete: false,
        circuitOpen: true,
        circuitCode: "store_failed",
      },
      pdfRetryIdentities: [],
    };
  }

  const runQueue = limit === null ? eligible : eligible.slice(0, limit);
  const runTotal = runQueue.length;
  onProgress({
    status: "running",
    title: "Pobieranie PDF-ów…",
    detail: `Do pobrania w tej partii: ${runTotal} z ${totalQueued} zaległych plików.`,
  });

  const processedKeys = new Set();
  const identitiesByKey = new Map();
  const totals = { attempted: 0, succeeded: 0, failed: 0, backoff: 0, quarantined: 0, unsupported: 0 };
  let processedCount = 0;
  let circuitOpen = false;
  let circuitCode = null;

  const entryKey = (entry) => createPortfolioPdfIdentity({
    insurer: "pzu",
    policyNumber: entry?.policyNumber ?? entry?.policy?.policyNumber,
    validFrom: entry?.validFrom ?? entry?.policy?.validFrom,
    validUntil: entry?.validUntil ?? entry?.policy?.validUntil,
  }).key;
  const drawBatchSize = () => minBatchSize + Math.floor(Math.random() * (maxBatchSize - minBatchSize + 1));
  const drawPauseMs = () => (batchPauseMs === null ? 3000 + Math.floor(Math.random() * 4001) : batchPauseMs);

  while (!circuitOpen) {
    
    
    
    const pending = runQueue.filter((entry) => {
      const key = entryKey(entry);
      return key && !processedKeys.has(key) && entry.policy?.pdfAvailable !== true;
    });
    if (pending.length === 0) break;
    const chunk = pending.slice(0, drawBatchSize());
    const batch = await runPzuPortfolioPdfBatch({
      page,
      retryStore,
      pdfDirectory,
      entries: chunk,
      onProgress: ({ processed }) => {
        const overall = processedCount + processed;
        if (overall % 5 === 0 || overall === runTotal) {
          onProgress({
            status: "running",
            title: `Pobieranie PDF-ów… (${overall}/${runTotal})`,
            detail: "",
          });
        }
      },
    });
    for (const entry of chunk) {
      const key = entryKey(entry);
      if (key) processedKeys.add(key);
    }
    processedCount += chunk.length;
    const result = batch.publicResult;
    totals.attempted += result.attempted;
    totals.succeeded += result.succeeded;
    totals.failed += result.failed;
    totals.backoff += result.backoff;
    totals.quarantined += result.quarantined;
    totals.unsupported += result.unsupported;
    for (const identity of batch.privateResult.manualRetryIdentities) {
      identitiesByKey.set(createPortfolioPdfIdentity(identity).key, identity);
    }
    
    
    console.error(
      `PZU PDF partia: rozmiar=${chunk.length} attempted=${result.attempted} ok=${result.succeeded}`
      + ` failed=${result.failed} backoff=${result.backoff} unsupported=${result.unsupported}`
      + ` obwod=${result.circuitOpen ? result.circuitCode || "unknown" : "-"}`
      + ` postep=${processedCount}/${runTotal} (kolejka=${totalQueued})`,
    );
    if (result.circuitOpen) {
      circuitOpen = true;
      circuitCode = result.circuitCode || "unknown";
      break;
    }
    if (pending.length > chunk.length) await delay(drawPauseMs());
  }

  const remaining = Math.max(0, totalQueued - totals.succeeded - totals.unsupported);
  const deferred = Math.max(0, totalQueued - processedCount);
  const pdfRetry = {
    attempted: totals.attempted,
    succeeded: totals.succeeded,
    failed: totals.failed,
    backoff: totals.backoff,
    quarantined: totals.quarantined,
    unsupported: totals.unsupported,
    deferred,
    remaining,
    batchComplete: !circuitOpen && deferred === 0 && remaining === 0,
    circuitOpen,
    circuitCode: circuitOpen ? circuitCode : null,
    manualRetryAvailable: identitiesByKey.size > 0,
  };
  if (pdfRetry.attempted === 0 && pdfRetry.remaining > 0) {
    onProgress({
      status: "running",
      title: "Pobieranie PDF-ów odłożone",
      detail: pdfRetry.circuitOpen
        ? "Faza dokumentów została bezpiecznie zatrzymana; polisy nadal zostaną zaimportowane."
        : "Dokumenty są tymczasowo pomijane po wcześniejszych nieudanych próbach.",
    });
  } else {
    onProgress({
      status: "running",
      title: pdfRetry.circuitOpen
        ? "Pobieranie PDF-ów przerwane"
        : "PDF-y pobrane",
      detail: pdfRetry.circuitOpen
        ? "Faza dokumentów została bezpiecznie zatrzymana; polisy nadal zostaną zaimportowane."
        : `Zapisano ${pdfRetry.succeeded} z ${pdfRetry.attempted} rozpoczętych plików.`,
    });
  }
  return {
    attempted: pdfRetry.attempted,
    saved: pdfRetry.succeeded,
    remaining: pdfRetry.remaining,
    pdfRetry,
    pdfRetryIdentities: [...identitiesByKey.values()],
  };
}




async function clickElementWithMouse(page, selector) {
  const handle = await page.$(selector);
  if (!handle) return false;
  try {
    await handle.evaluate((el) => el.scrollIntoView({ block: "center", inline: "nearest" })).catch(() => {});
    const box = await handle.boundingBox();
    if (!box || box.width < 1 || box.height < 1) return false;
    await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);
    return true;
  } finally {
    await handle.dispose().catch(() => {});
  }
}

export function createPzuAutomation({
  browserPool,
  pdfRetryStore,
}) {
  let lastVisiblePage = null;

  async function getPage({ focus = true, headless = false } = {}) {
    
    
    
    
    const activeBrowser = await browserPool.getBrowser({ insurerKey: "pzu", headless });
    const livePages = (await activeBrowser.pages().catch(() => []))
      .filter((candidate) => !candidate.isClosed());
    const everestPages = livePages.filter((candidate) => isOnPzuEverest(candidate));
    
    
    
    
    
    let page = null;
    if (everestPages.length > 0) {
      page = lastVisiblePage && !lastVisiblePage.isClosed() && everestPages.includes(lastVisiblePage)
        ? lastVisiblePage
        : everestPages[everestPages.length - 1];
    } else if (
      lastVisiblePage
      && !lastVisiblePage.isClosed()
      
      
      && lastVisiblePage.browser?.() === activeBrowser
    ) {
      page = lastVisiblePage;
    }
    if (!page) {
      page = await browserPool.openPage({ insurerKey: "pzu", headless });
    } else {
      
      
      browserPool.adoptPage("pzu", page);
    }
    page.setDefaultTimeout(15000);
    page.setDefaultNavigationTimeout(60000);
    lastVisiblePage = page;
    
    
    const ownPages = new Set(browserPool.listPages("pzu"));
    for (const other of livePages) {
      if (other === page || other.isClosed()) continue;
      if (isOnPzuEverest(other) || (other.url() === "about:blank" && ownPages.has(other))) {
        await other.close().catch(() => {});
      }
    }
    if (focus) await page.bringToFront().catch(() => {});
    return page;
  }

  
  
  
  async function minimizeWindow(page) {
    try {
      const session = await page.createCDPSession();
      try {
        const { windowId } = await session.send("Browser.getWindowForTarget");
        await session.send("Browser.setWindowBounds", { windowId, bounds: { windowState: "minimized" } });
      } finally {
        await session.detach().catch(() => {});
      }
      return true;
    } catch {
      return false;
    }
  }

  async function isLoggedIn(page) {
    return Boolean(await page.$(PZU_LOGGED_IN_SELECTOR));
  }

  
  
  
  
  
  
  
  
  
  
  
  

  function isOnPzuSsoHost(page) {
    try {
      const hostname = new URL(page.url()).hostname.toLowerCase();
      return hostname.endsWith("pzu.pl") && !isOnPzuEverest(page);
    } catch {
      return false;
    }
  }

  async function findVisibleSsoInput(page, selector) {
    for (const frame of page.frames()) {
      let elements = [];
      try {
        elements = await frame.$$(selector);
        for (const element of elements) {
          const visible = await element.evaluate((candidate) => candidate instanceof HTMLElement
            && candidate.getClientRects().length > 0
            && getComputedStyle(candidate).visibility !== "hidden"
            && !candidate.disabled
            && !candidate.readOnly);
          if (visible) {
            await Promise.all(elements.filter((other) => other !== element).map((other) => other.dispose().catch(() => {})));
            return element;
          }
        }
      } catch {
      }
      await Promise.all(elements.map((element) => element.dispose().catch(() => {})));
    }
    return null;
  }

  
  
  
  async function fillPzuGateForm(page, username, password) {
    const usernameInput = await findVisibleSsoInput(page, "input[name='username' i], input[type='text']");
    if (!usernameInput) return false;
    const passwordInput = await findVisibleSsoInput(page, "input[type='password']");
    if (!passwordInput) {
      await usernameInput.dispose().catch(() => {});
      return false;
    }
    try {
      await usernameInput.click({ count: 3 });
      await usernameInput.press("Backspace").catch(() => {});
      await usernameInput.type(username, { delay: 24 });
      await passwordInput.click({ count: 3 });
      await passwordInput.press("Backspace").catch(() => {});
      await passwordInput.type(password, { delay: 24 });
      await passwordInput.press("Enter");
      return true;
    } catch {
      return false;
    } finally {
      await usernameInput.dispose().catch(() => {});
      await passwordInput.dispose().catch(() => {});
    }
  }

  
  
  async function clickEverestLoginButton(page) {
    return page.evaluate(() => {
      const visible = (el) => el instanceof HTMLElement && el.getClientRects().length > 0
        && getComputedStyle(el).visibility !== "hidden";
      const label = (el) => String(el.value || el.textContent || "").replace(/\s+/g, " ").trim().toLowerCase();
      const target = [...document.querySelectorAll("a, button, input[type='button'], input[type='submit']")]
        .find((el) => visible(el) && /^zaloguj\b/.test(label(el)));
      if (!target) return false;
      target.click();
      return true;
    }).catch(() => false);
  }

  async function pzuSsoPageText(page) {
    const textParts = [];
    for (const frame of page.frames()) {
      try {
        textParts.push(await frame.evaluate(() => String(document.body?.innerText || "").slice(0, 8000)));
      } catch {
      }
    }
    return textParts.join(" ").toLowerCase();
  }

  async function ssoNeedsHuman(page) {
    return /captcha|kod sms|kod jednorazowy|kod weryfikacyjny|dwusk|potwierd[zź] logowanie|token/.test(await pzuSsoPageText(page));
  }

  async function attemptPzuSsoLogin(page, credentials, onProgress = () => {}) {
    const username = String(credentials?.username || "").trim();
    const password = String(credentials?.password || "");
    if (!username || !password) return false;
    onProgress({
      status: "running",
      title: "Logowanie do PZU…",
      detail: "Wpisuję zapisane dane logowania.",
    });
    
    
    await bringPageWindowToFront(page).catch(() => {});
    const deadline = Date.now() + 90000;
    let credentialsSubmitted = false;
    while (Date.now() < deadline) {
      if (isOnPzuEverest(page)) {
        if (await isLoggedIn(page)) return true;
        
        if (await clickEverestLoginButton(page)) {
          await delay(2500);
          continue;
        }
        await delay(900);
        continue;
      }
      if (await ssoNeedsHuman(page)) return false;
      if (isOnPzuSsoHost(page)) {
        const pageText = await pzuSsoPageText(page);
        if (/niepoprawne wywo|ponownie przej/.test(pageText)) {
          
          await page.goto(PZU_GATEWAY_URL, { waitUntil: "domcontentloaded", timeout: 60000 }).catch(() => {});
          await delay(1200);
          continue;
        }
        
        
        if (!credentialsSubmitted && await fillPzuGateForm(page, username, password)) {
          credentialsSubmitted = true;
          await delay(2500);
          continue;
        }
        
      }
      await delay(900);
    }
    return isOnPzuEverest(page) && (await isLoggedIn(page));
  }

  async function ensureLoggedIn(page, onProgress, credentials = null, { headless = false } = {}) {
    if (!isOnPzuEverest(page) || !(await isLoggedIn(page))) {
      onProgress({ status: "running", title: "Sprawdzanie logowania PZU…", detail: "" });
      
      await page.goto(PZU_URL, { waitUntil: "domcontentloaded", timeout: 60000 }).catch(() => {});
      await page.waitForSelector(PZU_LOGGED_IN_SELECTOR, { timeout: 10000 }).catch(() => {});
    }
    if (!(await isLoggedIn(page)) && credentials?.password) {
      
      
      await attemptPzuSsoLogin(page, credentials, onProgress);
    }
    if (!(await isLoggedIn(page))) {
      if (headless) {
        
        
        const error = new Error("Logowanie do PZU wymaga okna przeglądarki.");
        error.code = "MANUAL_INTERACTION_REQUIRED";
        throw error;
      }
      throw new Error("Nie jesteś zalogowany do PZU. Kliknij „Otwórz okno PZU i zaloguj się”, zaloguj się w otwartym oknie, a potem wróć tutaj i kliknij „Importuj polisy z PZU” jeszcze raz.");
    }
  }

  
  
  async function openLogin({ onProgress = () => {}, credentials = null } = {}) {
    const page = await getPage();
    if (isOnPzuEverest(page) && (await isLoggedIn(page))) {
      
      await bringPageWindowToFront(page).catch(() => {});
      return { loggedIn: true };
    }
    await page.goto(PZU_GATEWAY_URL, { waitUntil: "domcontentloaded", timeout: 60000 }).catch(() => {});
    if (credentials?.password && await attemptPzuSsoLogin(page, credentials, onProgress)) {
      await bringPageWindowToFront(page).catch(() => {});
      return { loggedIn: true };
    }
    onProgress({
      status: "running",
      title: "Otwieranie okna PZU…",
      detail: "Zaloguj się w otwartym oknie.",
    });
    await bringPageWindowToFront(page).catch(() => {});
    return { loggedIn: false };
  }

  async function openMyPolicies(page) {
    if (await page.$(PZU_GRID_PAGING_SELECTOR)) return;
    
    
    
    const attempts = [PZU_MY_POLICIES_LINK_SELECTOR, PZU_POLICIES_PARENT_SELECTOR];
    for (let round = 0; round < 2; round += 1) {
      for (const selector of attempts) {
        const clicked = await clickElementWithMouse(page, selector).catch(() => false);
        if (!clicked) continue;
        const appeared = await page.waitForSelector(PZU_GRID_PAGING_SELECTOR, { timeout: 25000 }).catch(() => null);
        if (appeared) return;
      }
      
      await clickElementWithMouse(page, PZU_DESKTOP_TAB_SELECTOR).catch(() => false);
      await delay(2500);
      if (await page.$(PZU_GRID_PAGING_SELECTOR)) return;
    }
    throw new Error("Nie udało się otworzyć ekranu „Moje polisy” w PZU. Otwórz go ręcznie (Pulpit → Polisy → Moje polisy) i kliknij import jeszcze raz.");
  }

  
  
  
  async function applyPoliciesFilterMode(page, mode) {
    const applied = await page.evaluate((selectName, value) => {
      const select = document.querySelector(`select[name="${selectName}"]`);
      if (!select) return false;
      select.value = value;
      return select.value === value;
    }, PZU_FILTER_MODE_SELECT_NAME, mode);
    if (!applied) throw new Error("Nie udało się ustawić filtru listy polis PZU.");

    const clicked = await clickElementWithMouse(page, PZU_FILTER_SEARCH_BUTTON_SELECTOR);
    if (!clicked) throw new Error("Nie udało się uruchomić wyszukiwania polis w PZU.");

    
    let total = 0;
    let sawResult = false;
    for (let i = 0; i < 40 && !sawResult; i += 1) {
      await delay(1000);
      const state = await page.evaluate((pagingSel) => {
        const paging = document.querySelector(pagingSel)?.textContent || "";
        const match = paging.match(/\(\s*\d+\s*-\s*\d+\s*z\s*(\d+)\s*\)/);
        const empty = /Brak danych do wyświetlenia/.test(document.body.innerText || "");
        return { total: match ? Number(match[1]) : 0, empty };
      }, PZU_PAGING_INFO_SELECTOR).catch(() => ({ total: 0, empty: false }));
      if (state.total > 0) {
        total = state.total;
        sawResult = true;
      } else if (state.empty && i >= 5) {
        sawResult = true; 
      }
    }
    if (!sawResult) {
      
      
      throw new Error("Lista polis nie załadowała wyników wyszukiwania w wyznaczonym czasie.");
    }
    return total;
  }

  
  
  
  
  
  
  
  
  async function importPortfolioAttempt({
    onProgress = () => {},
    sinceDate = "",
    downloadPdfs = false,
    pdfDirectory = "",
    pdfPolicyLimit = null,
    skipPdfPolicyNumbers = [],
    knownPdfPolicyNumbers = [],
    credentials = null,
    onCompletion,
  } = {}, { headless = false } = {}) {
    const page = await getPage({ focus: false, headless });
    await ensureLoggedIn(page, onProgress, credentials, { headless });

    
    
    
    
    
    
    let hidden = false;
    if (!headless) {
      await bringPageWindowToFront(page).catch(() => {});
      hidden = await minimizeWindow(page);
      if (hidden) {
        onProgress({
          status: "running",
          title: "Import polis PZU działa w tle…",
          detail: "Okno zostało zminimalizowane na czas importu.",
        });
      }
    }
    try {
      onProgress({ status: "running", title: "Pobieranie polis…", detail: "" });
      await openMyPolicies(page);

      
      const cutoff = new Date();
      cutoff.setFullYear(cutoff.getFullYear() - 1);
      const minEndDate = formatDateYmd(cutoff);

      
      const pdfBacklogCount = countUnskippedPortfolioPdfSelectors({
        known: knownPdfPolicyNumbers,
        skipped: skipPdfPolicyNumbers,
        insurer: "pzu",
      });
      const fetchFullForPdfBacklog = downloadPdfs === true && pdfBacklogCount > 0;

      
      
      
      let filterMode = "all";
      if (sinceDate && !fetchFullForPdfBacklog) {
        const incrementalCutoff = new Date();
        incrementalCutoff.setDate(incrementalCutoff.getDate() - PZU_INCREMENTAL_WINDOW_DAYS);
        if (sinceDate >= formatDateYmd(incrementalCutoff)) filterMode = "issued_last_30days";
      }
      const filterTotal = await applyPoliciesFilterMode(page, filterMode);
      if (filterTotal === 0 && sinceDate && filterMode === "issued_last_30days") {
        const mappingReport = assertPortfolioMappingComplete(
          createPortfolioMappingCollector(0).createReport(),
        );
        const { emittedPolicies, emissionReport } = createPortfolioEmissionResult([], {
          sinceDate,
          sourceAlreadyFilteredToCheckpoint: true,
        });
        onCompletion?.({
          ...buildPzuImportCompletion({
            freshCount: emissionReport.freshCount,
            downloadPdfs,
          }),
          mappingReport,
          emissionReport,
        });
        return emittedPolicies; 
      }

      const {
        rows,
        total,
        sourceCount: rawSourceCount = rows.length,
        duplicateCount: preMappingDuplicateCount = 0,
      } = await scrapePzuPolicyRows(page, {
        onProgress: ({ collected, total: totalRows, page: pageNumber }) => {
          onProgress({
            status: "running",
            title: "Pobieranie polis…",
            detail: `Pobrano ${collected} z ${totalRows} polis.`,
          });
        },
      });

      
      
      
      const mappingCollector = createPortfolioMappingCollector(rawSourceCount);
      if (preMappingDuplicateCount > 0) {
        mappingCollector.recordDuplicate(preMappingDuplicateCount);
      }
      const mappedPolicies = mapPzuPolicyRows(rows, {
        minEndDate,
        mappingCollector,
      });
      const mappingReport = assertPortfolioMappingComplete(mappingCollector.createReport());
      const emissionOptions = {
        sinceDate,
        getFreshnessDates: (policy) => [policy?.issueDate, policy?.validFrom],
        isBacklogPolicy: (policy) => policy?.pdfAvailable === true,
      };
      const previewEmission = createPortfolioEmissionResult(mappedPolicies, emissionOptions);
      const freshPolicies = previewEmission.emittedPolicies;
      const allPolicies = fetchFullForPdfBacklog ? mappedPolicies : freshPolicies;
      if (mappedPolicies.length === 0) {
        if (sinceDate) {
          onCompletion?.({
            ...buildPzuImportCompletion({
              freshCount: previewEmission.emissionReport.freshCount,
              downloadPdfs,
            }),
            mappingReport,
            emissionReport: previewEmission.emissionReport,
          });
          return previewEmission.emittedPolicies;
        }
        throw new Error("Nie znaleziono żadnej polisy do pobrania.");
      }

      if (freshPolicies.length > 0) {
        onProgress({
          status: "running",
          title: "Pobieranie szczegółów polis…",
          detail: "",
        });
        await enrichPzuVehicleInfo(page, freshPolicies, {
          onProgress: ({ done, total: totalAuto, filled }) => {
            onProgress({
              status: "running",
              title: "Pobieranie szczegółów polis…",
              detail: `Uzupełniono ${filled} z ${totalAuto} polis.`,
            });
          },
        });

        
        
        await enrichPzuPremiums(page, freshPolicies, {
          onProgress: ({ done, total: totalPremiums, filled }) => {
            onProgress({
              status: "running",
              title: "Pobieranie składek polis…",
              detail: `Pobrano ${filled} z ${totalPremiums} składek.`,
            });
          },
        });
      }

      let pdfOutcome = null;
      if (downloadPdfs && pdfDirectory) {
        pdfOutcome = await runPzuPortfolioPdfPhase({
          page,
          retryStore: pdfRetryStore,
          pdfDirectory,
          policies: allPolicies,
          onProgress,
          limit: pdfPolicyLimit,
          skipPolicyNumbers: skipPdfPolicyNumbers,
          knownPolicyNumbers: knownPdfPolicyNumbers,
        });
      }

      onProgress({
        status: "running",
        title: "Porządkowanie pobranych polis…",
        detail: `Pobrano ${freshPolicies.length} polis.`,
      });
      const { emittedPolicies, emissionReport } = createPortfolioEmissionResult(
        mappedPolicies,
        emissionOptions,
      );
      onCompletion?.({
        ...buildPzuImportCompletion({
          freshCount: emissionReport.freshCount,
          downloadPdfs,
          pdfOutcome,
        }),
        mappingReport,
        emissionReport,
      });
      return emittedPolicies;
    } catch (error) {
      if (hidden) await bringPageWindowToFront(page).catch(() => {});
      throw error;
    } finally {
      
      
      
      if (headless) await page.close().catch(() => {});
    }
  }

  
  
  
  async function importPortfolio(options) {
    const groupHeadless = browserPool.isHeadless("pzu");
    const startHeadless = groupHeadless === null ? true : groupHeadless === true;
    if (!startHeadless) return importPortfolioAttempt(options, { headless: false });
    try {
      return await importPortfolioAttempt(options, { headless: true });
    } catch (error) {
      if (error?.code !== "MANUAL_INTERACTION_REQUIRED") throw error;
      options?.onProgress?.({
        status: "running",
        title: "Potrzebne jest okno przeglądarki…",
        detail: "Program otworzy okno PZU - dokończ w nim logowanie, jeśli poprosi.",
      });
      return importPortfolioAttempt(options, { headless: false });
    }
  }

  async function focusWindow() {
    const candidates = [];
    if (lastVisiblePage && !lastVisiblePage.isClosed()) candidates.push(lastVisiblePage);
    for (const page of [...browserPool.listPages("pzu")].reverse()) {
      if (page && !page.isClosed() && !candidates.includes(page)) candidates.push(page);
    }
    for (const candidate of candidates) {
      if (await bringPageWindowToFront(candidate)) return true;
    }
    return false;
  }

  async function close() {
    lastVisiblePage = null;
    
    
    await browserPool.closeInsurer("pzu");
  }

  return { openLogin, importPortfolio, focusWindow, close };
}
