







import { stat } from "node:fs/promises";
import {
  najpozniejszaZnanaChwila,
  ocenStanLicencji,
  odczytajPodpisanaLicencje,
  PRZYPISANY_KLUCZ_PUBLICZNY_LICENCJI,
} from "./inccghfibgvxcyvvtkjp.mjs";

const ODSTEP_PONOWNEGO_SPRAWDZENIA_MS = 10 * 60 * 1000;

export function createLicencjaProgramu({
  store,
  updateService,
  sciezkiZnacznikow = [],
  teraz = () => Date.now(),
  trustedPublicKey = PRZYPISANY_KLUCZ_PUBLICZNY_LICENCJI,
} = {}) {
  if (!store) throw new Error("Usługa licencji wymaga magazynu licencji.");
  let ostatniaProbaSprawdzenia = 0;
  let ostatnieSprawdzenieUdane = true;
  let stanWPamieci = null;

  
  
  async function znacznikiZPlikow() {
    const wyniki = await Promise.all(sciezkiZnacznikow.map(async (sciezka) => {
      try {
        return (await stat(sciezka)).mtime;
      } catch {
        return null;
      }
    }));
    return wyniki.filter(Boolean);
  }

  async function zbierzZnanaChwile(licencja) {
    const [zapamietany, znacznikiPlikow] = await Promise.all([
      store.pobierzZapamietanyZegar().catch(() => ""),
      znacznikiZPlikow(),
    ]);
    return najpozniejszaZnanaChwila([zapamietany, licencja?.wydane, ...znacznikiPlikow]);
  }

  async function wczytajLicencje() {
    const zapisana = await store.pobierzLicencje().catch(() => null);
    return zapisana ? odczytajPodpisanaLicencje(zapisana, trustedPublicKey) : null;
  }

  
  
  
  async function odswiez(daneLogowania = null) {
    if (!updateService?.pobierzPodpisanaLicencje) throw new Error("Brak połączenia z serwerem licencji.");
    ostatniaProbaSprawdzenia = teraz();
    const podpisana = await updateService.pobierzPodpisanaLicencje(daneLogowania);
    const tresc = odczytajPodpisanaLicencje(podpisana, trustedPublicKey);
    if (!tresc) throw new Error("Serwer przysłał licencję, której nie udało się potwierdzić.");
    await store.zapiszLicencje(podpisana);
    await store.zapiszZnacznikCzasu(tresc.wydane, { zaufaneZrodlo: true });
    await store.zapamietajStanZSerwera({
      nazwa: tresc.nazwa,
      abonamentDo: tresc.wazneDo,
      aktualizacjeWlaczone: tresc.aktualizacjeWlaczone,
      powod: tresc.powodProgramu === "OK" ? "OK" : tresc.powodProgramu,
    }, { pelnyStan: true }).catch(() => {});
    ostatnieSprawdzenieUdane = true;
    return tresc;
  }

  async function ocen({ licencja = undefined } = {}) {
    const tresc = licencja === undefined ? await wczytajLicencje() : licencja;
    const znanaChwila = await zbierzZnanaChwile(tresc);
    const chwilaTeraz = teraz();
    
    await store.zapiszZnacznikCzasu(new Date(chwilaTeraz)).catch(() => {});
    const stan = ocenStanLicencji({
      licencja: tresc,
      teraz: chwilaTeraz,
      znanaChwila,
      ostatnieSprawdzenieUdane,
    });
    stanWPamieci = {
      ...stan,
      nazwa: tresc?.nazwa || "",
      login: tresc?.login || "",
      sprawdzone: new Date(ostatniaProbaSprawdzenia || 0).toISOString(),
    };
    return stanWPamieci;
  }

  
  
  async function zapewnijStan({ wymusSprawdzenie = false, daneLogowania = null } = {}) {
    let stan = await ocen();
    const odKolejnejProby = teraz() - ostatniaProbaSprawdzenia;
    const wolnoSprawdzic = wymusSprawdzenie || odKolejnejProby > ODSTEP_PONOWNEGO_SPRAWDZENIA_MS;
    if ((stan.wymagaSprawdzenia || wymusSprawdzenie) && wolnoSprawdzic) {
      try {
        const tresc = await odswiez(daneLogowania);
        stan = await ocen({ licencja: tresc });
      } catch (error) {
        ostatnieSprawdzenieUdane = false;
        ostatniaProbaSprawdzenia = teraz();
        stan = await ocen();
        stan.bladSprawdzenia = error?.message || "Nie udało się potwierdzić licencji.";
        stan.powodBledu = error?.code || "";
      }
    }
    return stan;
  }

  function stanZPamieci() {
    return stanWPamieci;
  }

  async function zapomnij() {
    stanWPamieci = null;
    ostatniaProbaSprawdzenia = 0;
    ostatnieSprawdzenieUdane = true;
  }

  return { zapewnijStan, odswiez, ocen, stanZPamieci, zapomnij };
}
