import 'server-only'

import { createAdminClient } from '@/lib/supabase/admin'
import { linkModeratorGrants } from '@/lib/data/moderator-access'
import { setSessionCookie } from '@/lib/auth/session'
import { emailPattern } from '@/lib/like'
import { slugify, slugAlternatives } from '@/lib/domain/slug'
import type { EnvUser } from '@/lib/auth/env-users'
import { evaluateParticipantRules } from '@/lib/data/auto-participants'
import type { TripParticipant } from '@/types/db'

/** Create the app session and link the verified identity to existing work. */
export async function establishSession(user: EnvUser, internal: boolean, originSub: string, authMethod?: 'google') {
  const admin = createAdminClient()
  const { error } = await admin.from('profiles').upsert({
    id: user.id, email: user.email, full_name: user.name, phone: user.phone,
    company_name: user.company, default_role: user.role,
  }, { onConflict: 'id' })
  if (error) throw new Error('Could not prepare the account profile.')

  await linkModeratorGrants({ id: user.id, email: user.email, name: user.name })
  if (user.role === 'broker') await ensureBrokerPage(user.id, user.company || user.name)
  const { data: linked } = await admin.from('trip_participants').update({ user_id: user.id }).is('user_id', null).ilike('email', emailPattern(user.email)).select('*')
  // Invitations waiting for this account can now apply the person's rules.
  for (const row of ((linked ?? []) as TripParticipant[]).filter((r) => (r.status === 'invited' || r.status === 'active') && !r.rules_evaluated_at)) {
    await evaluateParticipantRules({ tripId: row.trip_id, participant: row, trigger: 'participation', session: { id: user.id, originId: originSub, preview: null, contextKey: null } })
  }
  await setSessionCookie({ sub: user.id, email: user.email, name: user.name, role: user.role, company: user.company, internal, origin_sub: originSub, auth_method: authMethod })
}

/** Creates the broker intake page with a unique slug (idempotent). */
export async function ensureBrokerPage(ownerId: string, companyName: string) {
  const admin = createAdminClient()
  const { data: existing } = await admin.from('broker_pages').select('id').eq('owner_id', ownerId).maybeSingle()
  if (existing) return
  const base = slugify(companyName) || 'broker'
  const candidates = [base, ...slugAlternatives(base)]
  for (const slug of candidates) {
    const { error } = await admin.from('broker_pages').insert({ owner_id: ownerId, slug, display_name: companyName })
    if (!error) return
    if (!error.message.includes('duplicate')) break
  }
  await admin.from('broker_pages').insert({ owner_id: ownerId, slug: `${base}-${Math.random().toString(36).slice(2, 7)}`, display_name: companyName })
}
