import { createHash, randomUUID } from "node:crypto";
import { getDatabase } from "../cache/db.js";
import { createLogger } from "../logger.js";
const log = createLogger("cache");
function rowToJob(row, now) {
  const job = {
    id: row.id,
    url: row.url,
    interval_seconds: row.interval_seconds,
    ...row.selector ? { selector: row.selector } : {},
    ...row.last_check_at !== null ? { last_check_at: row.last_check_at } : {},
    ...row.last_content_hash !== null ? { last_content_hash: row.last_content_hash } : {},
    status: row.status,
    notification: row.notification,
    created_at: row.created_at
  };
  const ref = row.last_check_at ?? row.created_at;
  const dueAt = ref + row.interval_seconds * 1e3;
  job.staleness_seconds = Math.floor((now - dueAt) / 1e3);
  return job;
}
function fingerprint(url, intervalSeconds, selector) {
  return createHash("sha256").update(`${url}\0${intervalSeconds}\0${selector ?? ""}`).digest("hex");
}
function createJob(input) {
  const db = getDatabase();
  const fp = fingerprint(input.url, input.intervalSeconds, input.selector);
  const existing = db.prepare(
    `SELECT id, url, interval_seconds, selector, last_check_at, last_content_hash, status, notification, created_at
       FROM watch_jobs WHERE id = ?`
  ).get(fp);
  const now = Date.now();
  if (existing) {
    return rowToJob(existing, now);
  }
  const row = {
    id: fp,
    url: input.url,
    interval_seconds: input.intervalSeconds,
    selector: input.selector ?? null,
    last_check_at: null,
    last_content_hash: null,
    status: "active",
    notification: input.notification,
    created_at: now
  };
  db.prepare(
    `INSERT INTO watch_jobs (id, url, interval_seconds, selector, last_check_at, last_content_hash, status, notification, created_at)
     VALUES (@id, @url, @interval_seconds, @selector, @last_check_at, @last_content_hash, @status, @notification, @created_at)`
  ).run(row);
  log.info("watch job created", { id: row.id, url: row.url, interval: row.interval_seconds });
  return rowToJob(row, now);
}
function listJobs() {
  const db = getDatabase();
  const rows = db.prepare(
    `SELECT id, url, interval_seconds, selector, last_check_at, last_content_hash, status, notification, created_at
       FROM watch_jobs ORDER BY created_at ASC`
  ).all();
  const now = Date.now();
  return rows.map((r) => rowToJob(r, now));
}
function getJob(id) {
  const db = getDatabase();
  const row = db.prepare(
    `SELECT id, url, interval_seconds, selector, last_check_at, last_content_hash, status, notification, created_at
       FROM watch_jobs WHERE id = ?`
  ).get(id);
  if (!row) return null;
  return rowToJob(row, Date.now());
}
function deleteJob(id) {
  const db = getDatabase();
  const r = db.prepare("DELETE FROM watch_jobs WHERE id = ?").run(id);
  if (r.changes > 0) log.info("watch job deleted", { id });
  return r.changes > 0;
}
function setJobStatus(id, status) {
  const db = getDatabase();
  const r = db.prepare("UPDATE watch_jobs SET status = ? WHERE id = ?").run(status, id);
  if (r.changes === 0) return null;
  return getJob(id);
}
function recordCheck(id, checkedAt, contentHash) {
  const db = getDatabase();
  const r = db.prepare(
    `UPDATE watch_jobs
         SET last_check_at = ?, last_content_hash = ?
       WHERE id = ?`
  ).run(checkedAt, contentHash, id);
  if (r.changes === 0) return null;
  return getJob(id);
}
function getOverdueJobs(now = Date.now()) {
  const db = getDatabase();
  const rows = db.prepare(
    `SELECT id, url, interval_seconds, selector, last_check_at, last_content_hash, status, notification, created_at
         FROM watch_jobs
        WHERE status = 'active'
          AND (
            (last_check_at IS NULL AND created_at + (interval_seconds * 1000) <= ?)
            OR (last_check_at IS NOT NULL AND last_check_at + (interval_seconds * 1000) <= ?)
          )
        ORDER BY created_at ASC`
  ).all(now, now);
  return rows.map((r) => rowToJob(r, now));
}
function _generateAdHocId() {
  return randomUUID();
}
export {
  _generateAdHocId,
  createJob,
  deleteJob,
  getJob,
  getOverdueJobs,
  listJobs,
  recordCheck,
  setJobStatus
};
//# sourceMappingURL=store.js.map