import { recipes, collections, eq, or, and, inArray, sql } from "@epicure/db";

/**
 * Drizzle condition: true when `viewerId` may view a given recipe row — the
 * author, always; `public`/`unlisted` recipes, to anyone; `followers`-only
 * recipes, only to viewers who follow the author. Meant to be `and()`ed with
 * an `eq(recipes.id, id)` (or similar) in a single query, so the DB does the
 * filtering rather than fetching content the viewer can't see.
 *
 * Uses a literal `user_follows` identifier rather than a Drizzle column
 * proxy for that table — inside `db.query.recipes.findFirst`/`findMany`'s
 * `where`, the relational query builder rewrites embedded column refs to
 * the outer query's own table alias regardless of which table they actually
 * belong to (same issue documented in recipes/page.tsx's search filter),
 * which would otherwise silently produce broken SQL referencing a column
 * that doesn't exist on `recipes`.
 */
export function visibleToViewer(viewerId: string) {
  return or(
    eq(recipes.authorId, viewerId),
    inArray(recipes.visibility, ["public", "unlisted"]),
    and(
      eq(recipes.visibility, "followers"),
      sql`exists (select 1 from user_follows where user_follows.follower_id = ${viewerId} and user_follows.following_id = ${recipes.authorId})`
    )
  );
}

/** Same rationale/pattern as visibleToViewer(), for collections. */
export function collectionVisibleToViewer(viewerId: string) {
  return or(
    eq(collections.userId, viewerId),
    inArray(collections.visibility, ["public", "unlisted"]),
    and(
      eq(collections.visibility, "followers"),
      sql`exists (select 1 from user_follows where user_follows.follower_id = ${viewerId} and user_follows.following_id = ${collections.userId})`
    )
  );
}
