import { NextResponse } from 'next/server'
import { createClient } from '@/lib/supabase/server'
import { getAppOrg } from '@/lib/org'
import { buildTogglCsv, type EligibleEntry } from '@/lib/toggl'
import { chunkIds } from '@/lib/db-chunks'

/**
 * POST with form-encoded body containing one or more `id` fields.
 * Streams a Toggl-format CSV for those entries (no DB write).
 *
 * GET with ?batch_id=<uuid> still works for re-downloading a transfer batch.
 */

async function loadEntries(
  supabase: Awaited<ReturnType<typeof createClient>>,
  orgId: string,
  ids: string[],
): Promise<EligibleEntry[]> {
  const results: EligibleEntry[] = []
  for (const chunk of chunkIds(ids)) {
    const { data, error } = await supabase
      .from('time_entries')
      .select(
        'source_user_email, operator, client, project, description, billable, start_at, end_at, converted_user, converted_duration_seconds',
      )
      .eq('org_id', orgId)
      .in('id', chunk)
      .returns<EligibleEntry[]>()
    if (error) throw new Error(error.message)
    if (data) results.push(...data)
  }
  // Order globally after merging the chunks.
  results.sort((a, b) => a.start_at.localeCompare(b.start_at))
  return results
}

async function loadBatch(
  supabase: Awaited<ReturnType<typeof createClient>>,
  orgId: string,
  batchId: string,
): Promise<EligibleEntry[]> {
  const { data, error } = await supabase
    .from('time_entries')
    .select(
      'source_user_email, operator, client, project, description, billable, start_at, end_at, converted_user, converted_duration_seconds',
    )
    .eq('org_id', orgId)
    .eq('transfer_batch_id', batchId)
    .order('start_at', { ascending: true })
    .returns<EligibleEntry[]>()
  if (error) throw new Error(error.message)
  return data ?? []
}

/** Accepts strings like '2026-04' or '2026-4' (zero-pads the month). Anything else → null. */
function normalizeRelevantMonth(raw: string | null | undefined): string | null {
  if (!raw) return null
  const m = raw.trim().match(/^(\d{4})-(\d{1,2})$/)
  if (!m) return null
  const y = Number(m[1])
  const mo = Number(m[2])
  if (mo < 1 || mo > 12 || y < 2000 || y > 2100) return null
  return `${y}-${mo.toString().padStart(2, '0')}`
}

function csvResponse(
  entries: EligibleEntry[],
  suffix: string,
  relevantMonth: string | null,
): NextResponse {
  const csv = buildTogglCsv(entries, { teams: relevantMonth ?? undefined })
  const stamp = new Date().toISOString().slice(0, 10)
  // If a relevant month was provided, embed it in the filename so the user
  // can tell exports apart at a glance.
  const monthSuffix = relevantMonth ? `-${relevantMonth}` : ''
  const filename = `toggl-import-${stamp}${monthSuffix}-${suffix}.csv`
  return new NextResponse(csv, {
    status: 200,
    headers: {
      'Content-Type': 'text/csv; charset=utf-8',
      'Content-Disposition': `attachment; filename="${filename}"`,
      'Cache-Control': 'no-store',
    },
  })
}

export async function GET(request: Request) {
  try {
    const supabase = await createClient()
    const org = await getAppOrg(supabase)
    if (!org) return NextResponse.json({ error: 'org not found' }, { status: 404 })

    const url = new URL(request.url)
    const batchId = url.searchParams.get('batch_id')
    if (!batchId) {
      return NextResponse.json({ error: 'batch_id required' }, { status: 400 })
    }
    const relevantMonth = normalizeRelevantMonth(url.searchParams.get('relevant_month'))
    console.log('[transfer/download GET] batch_id=', batchId, 'relevant_month=', relevantMonth)
    const entries = await loadBatch(supabase, org.id, batchId)
    console.log('[transfer/download GET] loaded', entries.length, 'rows')
    if (entries.length === 0) {
      return NextResponse.json({ error: 'no entries in batch' }, { status: 404 })
    }
    return csvResponse(entries, batchId.slice(0, 8), relevantMonth)
  } catch (err) {
    console.error('[transfer/download GET] failed', err)
    const msg = err instanceof Error ? err.message : String(err)
    return NextResponse.json({ error: msg }, { status: 500 })
  }
}

export async function POST(request: Request) {
  try {
    const supabase = await createClient()
    const org = await getAppOrg(supabase)
    if (!org) return NextResponse.json({ error: 'org not found' }, { status: 404 })

    const form = await request.formData()
    const ids = form.getAll('id').map(String).filter(Boolean)
    const relevantMonth = normalizeRelevantMonth(String(form.get('relevant_month') ?? ''))
    console.log('[transfer/download POST] ids count=', ids.length, 'relevant_month=', relevantMonth)
    if (ids.length === 0) {
      return NextResponse.json({ error: 'no ids' }, { status: 400 })
    }
    const entries = await loadEntries(supabase, org.id, ids)
    console.log('[transfer/download POST] loaded', entries.length, 'rows for', ids.length, 'ids')
    if (entries.length === 0) {
      return NextResponse.json({ error: 'no matching entries' }, { status: 404 })
    }
    return csvResponse(entries, `${entries.length}rows`, relevantMonth)
  } catch (err) {
    console.error('[transfer/download POST] failed', err)
    const msg = err instanceof Error ? err.message : String(err)
    return NextResponse.json({ error: msg }, { status: 500 })
  }
}
