import type { DatabaseSync } from 'node:sqlite';
import { listItems } from '../db/repos/items.ts';
import { listFeedIdsForUser } from '../db/repos/subscriptions.ts';
import { readIdsForUser, markRead, markUnread, unreadCount } from '../db/repos/readState.ts';
import { getFeedById } from '../db/repos/feeds.ts';
import type { Cursor } from './cursor.ts';

export type Limit = number;
export type FeedId = number | null;

export interface ListUserItemsOptions {
  cursor?: Cursor | null;
  limit?: Limit;
  feedId?: FeedId;
}

export interface UserItem {
  id: number;
  feedId: number;
  feedTitle: string | null;
  title: string;
  url: string;
  author: string | null;
  publishedAt: string;
  contentHtml: string | null;
  contentText: string | null;
  read: boolean;
}

export function listUserItems(
  db: DatabaseSync,
  userId: number,
  { cursor, limit = 30, feedId = null }: ListUserItemsOptions = {},
): UserItem[] {
  let feedIds = listFeedIdsForUser(db, userId);
  if (feedId) feedIds = feedIds.filter((id) => id === feedId);
  const rows = listItems(db, { feedIds, cursor, limit });
  const readSet = readIdsForUser(
    db,
    userId,
    rows.map((r) => r.id),
  );
  return rows.map((r) => {
    const feed = getFeedById(db, r.feed_id);
    return {
      id: r.id,
      feedId: r.feed_id,
      feedTitle: feed ? feed.title : null,
      title: r.title,
      url: r.url,
      author: r.author,
      publishedAt: r.published_at,
      contentHtml: r.content_html,
      contentText: r.content_text,
      read: readSet.has(r.id),
    };
  });
}

export function markItemRead(db: DatabaseSync, userId: number, itemId: number): void {
  markRead(db, userId, itemId);
}
export function markItemUnread(db: DatabaseSync, userId: number, itemId: number): void {
  markUnread(db, userId, itemId);
}
export function markItemsRead(db: DatabaseSync, userId: number, ids: number[]): void {
  for (const id of ids) markRead(db, userId, id);
}
export function markItemsUnread(db: DatabaseSync, userId: number, ids: number[]): void {
  for (const id of ids) markUnread(db, userId, id);
}
export function getUserUnreadCount(db: DatabaseSync, userId: number): number {
  return unreadCount(db, userId);
}
