'use server'

import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'
import { createClient } from '@/lib/supabase/server'
import { getAppOrg } from '@/lib/org'
import { getEffectiveUser } from '@/lib/effective-user'
import { canTransfer } from '@/lib/permissions'
import { chunkIds } from '@/lib/db-chunks'

function fail(msg: string): never {
  redirect(`/transfer?error=${encodeURIComponent(msg)}`)
}

export async function markSelectedTransferred(formData: FormData) {
  const supabase = await createClient()
  const org = await getAppOrg(supabase)
  if (!org) fail('Organization not found.')

  const eu = await getEffectiveUser(supabase, org.id)
  if (!canTransfer(eu)) fail('Only an organization owner can mark entries as transferred.')

  const ids = formData.getAll('id').map(String).filter(Boolean)
  if (ids.length === 0) fail('No entries selected.')

  const batchId = crypto.randomUUID()
  const now = new Date().toISOString()

  // Chunk the `.in('id', ids)` to keep the PostgREST URL under proxy
  // limits (Cloudflare rejects URLs >~16KB; one UUID + comma is 37 chars,
  // so ~150 ids per chunk is a safe ceiling). All chunks share the
  // generated `batch_id` so they land as one transfer batch.
  for (const chunk of chunkIds(ids)) {
    const { error } = await supabase
      .from('time_entries')
      .update({
        transferred_at: now,
        transferred_by: eu?.real_user_id ?? null,
        transfer_batch_id: batchId,
      })
      .eq('org_id', org.id)
      .in('id', chunk)
      .is('transferred_at', null)
      .not('team_member_id', 'is', null)
      .not('converted_duration_seconds', 'is', null)
      .not('operator', 'is', null)
      .not('client', 'is', null)
      .not('project', 'is', null)
      .not('description', 'is', null)
      .not('end_at', 'is', null)
      .not('source_user_email', 'is', null)
      .not('converted_user', 'is', null)
    if (error) fail(error.message)
  }

  revalidatePath('/transfer')
  revalidatePath('/entries')
  redirect(`/transfer?marked=${batchId}`)
}

export async function unmarkBatch(formData: FormData) {
  // DeleteForm posts the value under `id`; accept either.
  const batchId = String(formData.get('id') ?? formData.get('batch_id') ?? '')
  if (!batchId) fail('Missing batch id.')

  const supabase = await createClient()
  const org = await getAppOrg(supabase)
  if (!org) fail('Organization not found.')

  const eu = await getEffectiveUser(supabase, org.id)
  if (!canTransfer(eu)) fail('Only an organization owner can undo a transfer.')

  const { error } = await supabase
    .from('time_entries')
    .update({
      transferred_at: null,
      transferred_by: null,
      transfer_batch_id: null,
    })
    .eq('org_id', org.id)
    .eq('transfer_batch_id', batchId)

  if (error) fail(error.message)

  revalidatePath('/transfer')
  revalidatePath('/entries')
  redirect('/transfer?unmarked=1')
}
