'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import {
  PERMIT_COST_DISCLAIMER, PERMIT_COST_LABEL, canEditPermitCost, canSeePermitCost, displayPermitCost, effectiveCost, tripPermitFees,
} from '@/lib/domain/permit-cost'
import type { Permit, TripRole } from '@/types/db'

/**
 * State permit fee on a permit card, and the fee summary under the permits
 * list (Nash, 2026-09-24).
 *
 * "Keep the cost visible but not visually dominant over the actual permit
 * status/validity." Nothing here renders for a pilot — and the server has
 * already removed the fields from their payload, so there is nothing to
 * render either.
 */

/** One line on a permit card. */
export function PermitFeeLine({ permit, myRole, tripId, isInternal = false, onSaved }: { permit: Permit; myRole: TripRole | null; tripId: string; isInternal?: boolean; onSaved?: () => void }) {
  const router = useRouter()
  const [editing, setEditing] = useState(false)
  const [value, setValue] = useState('')
  const [busy, setBusy] = useState(false)
  if (!canSeePermitCost(myRole)) return null
  const shown = displayPermitCost(permit)
  const canEdit = canEditPermitCost({ role: myRole, isInternal })

  async function save(amount: number | null) {
    setBusy(true)
    try {
      const r = await fetch(`/api/trips/${tripId}/permits/${permit.id}/cost`, {
        method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount }),
      })
      const json = await r.json().catch(() => ({}))
      if (!r.ok) throw new Error(json.error ?? 'Could not save the fee.')
      toast.success(amount === null ? 'Permit fee cleared.' : `Permit fee set to ${amount.toFixed(2)}.`)
      setEditing(false)
      onSaved?.()
      router.refresh()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Could not save the fee.')
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="mt-1.5 flex flex-wrap items-center gap-2 text-[11px]">
      <span className="font-bold text-neutral-400">{PERMIT_COST_LABEL}</span>
      {editing ? (
        <>
          <span className="flex items-center gap-1">
            $<input autoFocus inputMode="decimal" value={value} onChange={(e) => setValue(e.target.value)} placeholder={String(effectiveCost(permit) ?? '')} className="w-20 rounded border px-1.5 py-0.5 text-[11px]" />
          </span>
          <button disabled={busy || !/^\d+(\.\d{1,2})?$/.test(value.trim())} onClick={() => save(Number(value))} className="rounded bg-[#0f1b2d] px-2 py-0.5 font-bold text-white disabled:opacity-50">Save</button>
          <button disabled={busy} onClick={() => save(null)} className="rounded border px-2 py-0.5 font-semibold text-neutral-600">Clear</button>
          <button disabled={busy} onClick={() => setEditing(false)} className="text-neutral-500 underline">Cancel</button>
        </>
      ) : (
        <>
          <span className={shown.needsReview ? 'font-semibold text-amber-700' : 'font-semibold text-neutral-700'} title={shown.hint ?? undefined}>{shown.text}</span>
          {permit.permit_cost_status === 'corrected' && <span className="text-[10px] text-neutral-400" title={`Corrected from ${permit.permit_cost_extracted_amount ?? '—'} by ${permit.permit_cost_updated_by ?? 'staff'}`}>corrected</span>}
          {permit.permit_cost_status === 'manually_entered' && <span className="text-[10px] text-neutral-400">entered by {permit.permit_cost_updated_by ?? 'staff'}</span>}
          {permit.cost_counts_toward_total === false && <span className="text-[10px] text-neutral-400">not counted in the trip total</span>}
          {canEdit && (
            <button onClick={() => { setValue(String(effectiveCost(permit) ?? '')); setEditing(true) }} className="text-[10px] text-neutral-500 underline">
              {effectiveCost(permit) === null ? 'Enter fee' : 'Correct'}
            </button>
          )}
        </>
      )}
    </div>
  )
}

/**
 * The summary under the permits list. Complete and incomplete read
 * differently on purpose (§10): a total that might be missing a fee never
 * claims to be the whole story.
 */
export function PermitFeeSummary({ permits, myRole, showLines = false }: { permits: Permit[]; myRole: TripRole | null; showLines?: boolean }) {
  if (!canSeePermitCost(myRole) || permits.length === 0) return null
  const fees = tripPermitFees(permits)
  if (fees.counted === 0 && fees.missing === 0) return null
  return (
    <div className="mt-4 rounded-xl border bg-neutral-50 p-3">
      {showLines && fees.lines.length > 0 && (
        <ul className="mb-2 space-y-0.5 text-[11px] text-neutral-600">
          {fees.lines.map((l) => (
            <li key={l.permitId} className="flex justify-between gap-3">
              <span>{l.state || 'Permit'}</span>
              <span className={l.counted ? 'font-semibold' : 'text-neutral-400'}>{l.text}</span>
            </li>
          ))}
        </ul>
      )}
      <p className="flex flex-wrap items-baseline justify-between gap-2">
        <span className="text-xs font-bold uppercase tracking-wide text-neutral-500">{fees.label}</span>
        <span className="text-base font-bold">{new Intl.NumberFormat('en-US', { style: 'currency', currency: fees.currency || 'USD' }).format(fees.total)}</span>
      </p>
      {fees.warning && <p className="mt-1 text-[11px] font-semibold text-amber-700">{fees.warning}</p>}
      {fees.notCounted > 0 && (
        <p className="mt-1 text-[11px] text-neutral-500">
          {fees.notCounted} permit{fees.notCounted === 1 ? ' was' : 's were'} left out as a revision or a duplicate upload, so no fee is counted twice.
        </p>
      )}
      <p className="mt-1.5 text-[10px] leading-snug text-neutral-500">{PERMIT_COST_DISCLAIMER}</p>
    </div>
  )
}
