import { eq } from 'drizzle-orm'
import type { Querier } from '@platform-modules/db'
import { ReviewNotFoundError, ReviewValidationError } from './errors.js'
import { assertReviewId } from './ids.js'
import { review, type ReviewsSchema } from './schema.js'

const isConcrete = (v: string | null | undefined): v is string =>
  typeof v === 'string' && v.length > 0

export const REVIEW_REPLY_MAX = 5000

export async function replyToReview(
  q: Querier<ReviewsSchema>,
  reviewId: string,
  vendorId: string,
  reply: string,
): Promise<void> {
  // D9: validate the untrusted reviewId at the boundary BEFORE it reaches the
  // uuid column — a non-uuid id otherwise raises a raw Postgres error (info-leak)
  // and breaks the D6 no-oracle property. Malformed → typed ReviewValidationError.
  assertReviewId(reviewId)

  if (typeof reply !== 'string' || reply.length > REVIEW_REPLY_MAX) {
    throw new ReviewValidationError('reply')
  }

  const [existing] = await q.select().from(review).where(eq(review.id, reviewId)).limit(1)

  if (
    !existing ||
    !isConcrete(existing.vendorId) ||
    !isConcrete(vendorId) ||
    existing.vendorId !== vendorId
  ) {
    throw new ReviewNotFoundError(reviewId)
  }

  const now = new Date()
  const [updated] = await q
    .update(review)
    .set({ vendorReply: reply, updatedAt: now })
    .where(eq(review.id, reviewId))
    .returning()

  if (!updated) {
    throw new ReviewNotFoundError(reviewId)
  }
}
