'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 { canManageImports } from '@/lib/permissions'
import {
  parseClockifyCsv,
  type DateFormat,
  type TimeFormat,
} from '@/lib/clockify'
import { getTeamForUser } from '@/lib/teams'
import { guardImport } from '@/lib/view-as-guards'

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

/**
 * Step 1 of the two-step import flow. Parse the CSV, stash the result
 * in `pending_imports`, and redirect to the resolver page where the
 * user picks "create new" / "map to existing" for any unknown
 * operator / client / project names. The actual insert happens in
 * `commitPendingImport` (see /import/resolve/actions.ts).
 */
export async function uploadClockifyCsv(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 (!canManageImports(eu)) fail('You do not have permission to import.')

  const file = formData.get('file') as File | null
  const sourceRaw = String(formData.get('source') ?? 'clockify').toLowerCase()
  const source: 'clockify' | 'toggl' =
    sourceRaw === 'toggl' ? 'toggl' : 'clockify'
  const dateFormat = String(
    formData.get('date_format') ??
      (source === 'toggl' ? 'YYYY-MM-DD' : 'MM/DD/YYYY'),
  ) as DateFormat
  const timeFormat = String(
    formData.get('time_format') ?? (source === 'toggl' ? '24h' : '12h'),
  ) as TimeFormat
  const batchName = String(formData.get('name') ?? '').trim() || null
  const notes = String(formData.get('notes') ?? '').trim() || null

  if (!file || file.size === 0) fail('Please choose a CSV file to upload.')
  if (file.size > 25 * 1024 * 1024) fail('File too large (25MB max).')

  const text = await file.text()
  const result = parseClockifyCsv(text, dateFormat, timeFormat)

  if (result.entries.length === 0) {
    fail(
      result.errors[0]?.message ||
        'No valid rows found in the CSV. Check the format selections.',
    )
  }

  if (!eu) fail('Not authenticated.')

  // Validate the importer has a team in the org — we need this to
  // resolve email → team_member during commit. Fail fast here so the
  // user doesn't get the resolver UI only to have commit fail.
  const team = await getTeamForUser(supabase, org.id, eu.effective_user_id)
  if (!team) {
    fail(
      "You don't have a team in this organization yet. An org owner needs to create one for you before you can import.",
    )
  }

  // Stage the parsed entries. The resolver page reads from here.
  const { data: pending, error: insertErr } = await supabase
    .from('pending_imports')
    .insert({
      org_id: org.id,
      uploaded_by: eu.effective_user_id,
      filename: file.name,
      batch_name: batchName,
      notes,
      source,
      date_format: dateFormat,
      time_format: timeFormat,
      // `parsed_entries` is a jsonb column — supabase-js serializes the
      // value transparently.
      parsed_entries: result.entries,
    })
    .select('id')
    .single<{ id: string }>()
  if (insertErr || !pending) {
    fail(insertErr?.message ?? 'Failed to stage import for resolution.')
  }

  redirect(`/import/resolve?id=${pending.id}`)
}


export async function deleteImportBatch(formData: FormData) {
  const id = String(formData.get('id') ?? '')
  if (!id) 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 (!canManageImports(eu)) fail('You do not have permission to delete batches.')
  const vasError = await guardImport(supabase, eu, org.id, id)
  if (vasError) fail(vasError)

  // Safety: refuse if any entry in this batch is transferred.
  const { count: transferredCount, error: countErr } = await supabase
    .from('time_entries')
    .select('id', { count: 'exact', head: true })
    .eq('org_id', org.id)
    .eq('import_id', id)
    .not('transferred_at', 'is', null)
  if (countErr) fail(countErr.message)
  if ((transferredCount ?? 0) > 0) {
    fail(
      `Can't delete: ${transferredCount} entries in this batch have already been transferred. Undo those transfers first.`,
    )
  }

  // Delete entries first (FK is ON DELETE SET NULL, which would orphan them).
  const { error: delEntriesErr } = await supabase
    .from('time_entries')
    .delete()
    .eq('org_id', org.id)
    .eq('import_id', id)
  if (delEntriesErr) fail(delEntriesErr.message)

  const { error: delBatchErr } = await supabase
    .from('clockify_imports')
    .delete()
    .eq('org_id', org.id)
    .eq('id', id)
  if (delBatchErr) fail(delBatchErr.message)

  revalidatePath('/import')
  revalidatePath('/transfer')
  revalidatePath('/entries')
  redirect('/import')
}
