







import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
import { dirname } from "node:path";



const SINCE_OVERLAP_DAYS = 7;

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

function normalizeKey(key) {
  const normalized = String(key || "").trim();
  
  
  return /^[a-z0-9][a-z0-9:_-]{0,79}$/i.test(normalized) ? normalized : "";
}

export function createPortfolioImportState({ storagePath }) {
  let writeQueue = Promise.resolve();

  async function readState({ failClosed = false } = {}) {
    try {
      const raw = await readFile(storagePath, "utf8");
      const parsed = JSON.parse(raw);
      if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
      if (!failClosed) return {};
      throw new TypeError("Nieprawidłowy dokument checkpointów importu.");
    } catch (error) {
      if (!failClosed || error?.code === "ENOENT") return {};
      const unreadable = new Error("Nie można bezpiecznie odczytać checkpointów importu.");
      unreadable.code = "PORTFOLIO_IMPORT_STATE_UNREADABLE";
      throw unreadable;
    }
  }

  async function writeState(state) {
    await mkdir(dirname(storagePath), { recursive: true }).catch(() => {});
    const temporaryPath = `${storagePath}.tmp`;
    await writeFile(temporaryPath, `${JSON.stringify(state, null, 2)}\n`, "utf8");
    await rename(temporaryPath, storagePath);
  }

  function enqueueWrite(operation) {
    writeQueue = writeQueue
      .catch(() => {})
      .then(operation);
    return writeQueue;
  }

  
  async function getImportSinceDate(key) {
    const normalizedKey = normalizeKey(key);
    if (!normalizedKey) return "";
    const state = await readState();
    const lastImportAt = String(state[normalizedKey]?.lastImportAt || "");
    const parsed = new Date(lastImportAt);
    if (!lastImportAt || Number.isNaN(parsed.getTime())) return "";
    parsed.setDate(parsed.getDate() - SINCE_OVERLAP_DAYS);
    return formatDateYmd(parsed);
  }

  
  
  function markImportCompleted(key) {
    const normalizedKey = normalizeKey(key);
    if (!normalizedKey) {
      const error = new TypeError("Nieprawidłowy klucz checkpointu importu.");
      error.code = "PORTFOLIO_CHECKPOINT_KEY_INVALID";
      return Promise.reject(error);
    }
    return enqueueWrite(async () => {
      const state = await readState({ failClosed: true });
      state[normalizedKey] = { lastImportAt: new Date().toISOString() };
      await writeState(state);
    });
  }

  
  
  function resetImportCheckpoint(key) {
    const normalizedKey = normalizeKey(key);
    if (!normalizedKey || normalizedKey !== String(key || "").trim()) {
      const error = new TypeError("Nieprawidłowy klucz checkpointu importu.");
      error.code = "PORTFOLIO_CHECKPOINT_KEY_INVALID";
      return Promise.reject(error);
    }
    return enqueueWrite(async () => {
      const state = await readState({ failClosed: true });
      if (!Object.prototype.hasOwnProperty.call(state, normalizedKey)) {
        return { key: normalizedKey, removed: false };
      }
      delete state[normalizedKey];
      await writeState(state);
      return { key: normalizedKey, removed: true };
    });
  }

  return { getImportSinceDate, markImportCompleted, resetImportCheckpoint };
}
