import 'server-only'

import { createAdminClient } from '@/lib/supabase/admin'
import { isMissingColumn } from '@/lib/db-compat'
import type { ChatMessage } from '@/types/db'

/**
 * Chat visibility (2026-09-07).
 *
 * Nash: "let broker and dispatch see my questions and answers, yes or no…
 * if I put no for this trip, then nobody's gonna see my questions and the
 * answers for this trip."
 *
 * Filtering happens HERE, on the server. A private message must never reach
 * another participant's browser and get hidden with CSS — the chat polls every
 * four seconds and the payload is trivially readable.
 *
 * Reporting an answer for human review deliberately overrides this: the
 * moderator path reads with the admin client and no filter, because the asker
 * chose to escalate. Privacy is from co-workers on the trip, not from support.
 */

const PRIVACY_COLUMNS = ['is_private', 'private_for_user_id'] as const

/** Public messages, plus this user's own private ones. */
function visibilityFilter(userId: string): string {
  return `is_private.eq.false,private_for_user_id.eq.${userId}`
}

export async function loadVisibleChat(
  tripId: string,
  userId: string,
  opts: { after?: string | null; limit?: number } = {},
): Promise<{ messages: ChatMessage[]; failed: boolean }> {
  const admin = createAdminClient()
  const build = () => {
    let q = admin.from('chat_messages').select('*').eq('trip_id', tripId).order('created_at')
    if (opts.after) q = q.gt('created_at', opts.after)
    if (opts.limit) q = q.limit(opts.limit)
    return q
  }

  const wide = await build().or(visibilityFilter(userId))
  if (isMissingColumn(wide.error, ...PRIVACY_COLUMNS)) {
    // Migration 0010 not applied — nothing can be private yet.
    const narrow = await build()
    return { messages: (narrow.data ?? []) as ChatMessage[], failed: !!narrow.error }
  }
  return { messages: (wide.data ?? []) as ChatMessage[], failed: !!wide.error }
}
