import type { DatabaseSync } from 'node:sqlite';
import { asRow, asRows } from '../row.ts';
import type { FeedRow } from '../../types/db.js';

export interface NewFeed {
  url: string;
  next_poll_at: string;
  created_at: string;
  title?: string | null;
  description?: string | null;
  site_url?: string | null;
  etag?: string | null;
  last_modified?: string | null;
  last_fetched_at?: string | null;
  last_success_at?: string | null;
  failure_count?: number | null;
  last_error?: string | null;
}

export type FeedPatch = Partial<Omit<FeedRow, 'id'>>;

export function createFeed(db: DatabaseSync, feed: NewFeed): FeedRow | null {
  const stmt = db.prepare(`
    INSERT INTO feeds (url, title, description, site_url, etag, last_modified, last_fetched_at, last_success_at, failure_count, last_error, next_poll_at, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  `);
  const info = stmt.run(
    feed.url,
    feed.title ?? null,
    feed.description ?? null,
    feed.site_url ?? null,
    feed.etag ?? null,
    feed.last_modified ?? null,
    feed.last_fetched_at ?? null,
    feed.last_success_at ?? null,
    feed.failure_count ?? 0,
    feed.last_error ?? null,
    feed.next_poll_at,
    feed.created_at,
  );
  return getFeedById(db, Number(info.lastInsertRowid));
}

export function getFeedByUrl(db: DatabaseSync, url: string): FeedRow | null {
  return asRow<FeedRow>(db.prepare('SELECT * FROM feeds WHERE url = ?').get(url)) ?? null;
}

export function getFeedById(db: DatabaseSync, id: number): FeedRow | null {
  return asRow<FeedRow>(db.prepare('SELECT * FROM feeds WHERE id = ?').get(id)) ?? null;
}

export function listFeedsDue(db: DatabaseSync, nowIso: string): FeedRow[] {
  return asRows<FeedRow>(db.prepare('SELECT * FROM feeds WHERE next_poll_at <= ?').all(nowIso));
}

export function updateFeed(db: DatabaseSync, id: number, patch: FeedPatch): FeedRow | null {
  const fields = Object.keys(patch) as (keyof FeedPatch)[];
  if (!fields.length) return getFeedById(db, id);
  const set = fields.map((f) => `${f} = ?`).join(', ');
  const vals = fields.map((f) => patch[f] ?? null);
  db.prepare(`UPDATE feeds SET ${set} WHERE id = ?`).run(...vals, id);
  return getFeedById(db, id);
}

export function deleteFeed(db: DatabaseSync, id: number): void {
  db.prepare('DELETE FROM feeds WHERE id = ?').run(id);
}
