import 'server-only'

import { createAdminClient } from '@/lib/supabase/admin'
import { isMissingColumn } from '@/lib/db-compat'
import { readPermitCost, readSuppliedCost, type PermitCostReading } from '@/lib/domain/permit-cost'
import type { PermitExtraction } from '@/lib/adapters/flask'

/**
 * Permit cost — the I/O (Nash, 2026-09-24). Rules in
 * src/lib/domain/permit-cost.ts. Needs migration 0033; without it the writes
 * fall back to the old shape and cost simply never appears.
 */

type Admin = ReturnType<typeof createAdminClient>

/**
 * What to store for a freshly extracted permit. A fee the extractor names
 * outright is trusted; otherwise the fee is read out of the permit's text.
 */
export function costFieldsFromExtraction(ex: PermitExtraction | null | undefined): Record<string, unknown> {
  if (!ex) return { permit_cost_status: 'not_found' }
  const currency = (ex.currency ?? 'USD').toUpperCase()
  const supplied = readSuppliedCost(ex.permit_fee ?? ex.permit_cost ?? ex.fee_amount, currency)
  const raw = ex.raw ?? {}
  const text = ex.text ?? (typeof raw.text === 'string' ? raw.text : null) ?? (typeof raw.full_text === 'string' ? raw.full_text : null)
  const reading: PermitCostReading = supplied ?? readPermitCost(text, currency)
  return {
    permit_cost_amount: reading.amount,
    permit_cost_extracted_amount: reading.amount,
    permit_cost_currency: reading.currency,
    permit_cost_status: reading.status,
    permit_cost_confidence: reading.confidence,
    permit_cost_source: reading.amount === null ? null : supplied ? 'api' : 'extraction',
    permit_cost_extracted_text: reading.extractedText,
    permit_cost_last_updated_at: new Date().toISOString(),
  }
}

/** Insert a permit row, dropping the cost fields when migration 0033 is not applied. */
export async function insertPermitWithCost(row: Record<string, unknown>, costFields: Record<string, unknown>, admin: Admin = createAdminClient()) {
  const full = await admin.from('permits').insert({ ...row, ...costFields }).select().single()
  if (!full.error) return full
  if (!isMissingColumn(full.error, 'permit_cost_amount', 'permit_cost_status', 'permit_cost_currency', 'permit_cost_confidence', 'permit_cost_source', 'permit_cost_extracted_text', 'permit_cost_extracted_amount', 'permit_cost_last_updated_at')) return full
  return admin.from('permits').insert(row).select().single()
}

export interface CostCorrection {
  permitId: string
  tripId: string
  amount: number | null
  reason?: string | null
  actor: { id: string | null; label: string }
  /** True when the permit is a revision that carried no new state charge. */
  countsTowardTotal?: boolean
}

/**
 * §4: someone corrects the fee. The extracted value is kept, the correction is
 * what shows, and the change is written to permit_cost_history.
 */
export async function correctPermitCost(input: CostCorrection, admin: Admin = createAdminClient()) {
  const { data: before, error: readErr } = await admin.from('permits').select('*').eq('id', input.permitId).eq('trip_id', input.tripId).maybeSingle()
  if (readErr || !before) return { ok: false as const, error: 'That permit is not on this trip.' }
  const prev = before as Record<string, unknown>
  const now = new Date().toISOString()
  const hadExtraction = prev.permit_cost_extracted_amount !== null && prev.permit_cost_extracted_amount !== undefined
  const patch: Record<string, unknown> = {
    permit_cost_manual_override: input.amount,
    permit_cost_amount: input.amount,
    permit_cost_status: input.amount === null ? 'not_found' : hadExtraction ? 'corrected' : 'manually_entered',
    permit_cost_confidence: input.amount === null ? null : 'high',
    permit_cost_source: input.amount === null ? null : 'manual',
    permit_cost_verified: input.amount !== null,
    permit_cost_updated_by: input.actor.label,
    permit_cost_updated_by_user_id: input.actor.id,
    permit_cost_last_updated_at: now,
    ...(input.countsTowardTotal === undefined ? {} : { cost_counts_toward_total: input.countsTowardTotal }),
  }
  const { error } = await admin.from('permits').update(patch).eq('id', input.permitId)
  if (error) return { ok: false as const, error: isMissingColumn(error, 'permit_cost_manual_override', 'permit_cost_amount') ? 'Permit cost needs database migration 0033.' : error.message }
  const { error: histErr } = await admin.from('permit_cost_history').insert({
    permit_id: input.permitId, trip_id: input.tripId,
    previous_amount: (prev.permit_cost_amount as number | null) ?? null, new_amount: input.amount,
    previous_status: (prev.permit_cost_status as string | null) ?? null, new_status: patch.permit_cost_status as string,
    source: 'manual', reason: input.reason?.trim() || null, actor_label: input.actor.label, actor_user_id: input.actor.id,
  })
  if (histErr) console.error('permit cost history not recorded', histErr.message)
  return { ok: true as const, status: patch.permit_cost_status as string }
}

/** Re-read the fee from a permit's stored extraction, for the historical backfill (§20). */
export function costFieldsFromStoredExtraction(extraction: Record<string, unknown> | null | undefined): Record<string, unknown> | null {
  if (!extraction) return null
  return costFieldsFromExtraction(extraction as PermitExtraction)
}
