'use client'

import { useState, type ReactNode } from 'react'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { canUploadDocuments } from '@/lib/domain/permissions'
import { stateName } from '@/lib/domain/states'
import { formatFullDate } from '@/lib/format'
import type { ServiceRequest, Trip, TripRole } from '@/types/db'

/**
 * Section 2 while a trip has ZERO permits and is still waiting (Task 84).
 *
 * Nash (2026-09-08): "if the trip has zero permits, the agent is not needed.
 * It's not valid until we have at least one permit attached… Section 2 should
 * be more of a drag and drop, upload permits — or, if it's required to be
 * executed by Synchron Permits, a visual representation showing that it's
 * being processed right now. If it's more than zero permits attached, then
 * Section 2 will show the chat."
 *
 * The workspace mounts this INSTEAD of `ChatPanel` when
 * `permits.length === 0 && status ∈ {draft, waiting_for_permits}`; the moment
 * the first permit row exists the chat comes back on its own.
 */
export function PermitsGate({
  trip,
  myRole,
  requests,
  orderAction,
  onOpenInfo,
}: {
  trip: Trip
  myRole: TripRole | null
  requests: ServiceRequest[]
  /** The existing "Order permits from our trusted partner Synchron Permits"
      dialog — rendered by the workspace, shown here in the no-order state. */
  orderAction?: ReactNode
  /** Below xl the Section 3 banner lives on the "Trip Info" view. */
  onOpenInfo?: () => void
}) {
  const synchron = trip.permit_policy === 'synchron_required'
  return (
    <div className="flex min-h-0 flex-1 flex-col overflow-y-auto p-4 sm:p-6">
      {synchron ? (
        <SynchronProcessing trip={trip} requests={requests} orderAction={orderAction} onOpenInfo={onOpenInfo} />
      ) : (
        <PermitDropZone trip={trip} myRole={myRole} />
      )}
    </div>
  )
}

/* ---------------- Branch A: carrier-upload flow ---------------- */

const ACCEPT = '.pdf,.jpg,.jpeg,.png,.docx'

function PermitDropZone({ trip, myRole }: { trip: Trip; myRole: TripRole | null }) {
  const router = useRouter()
  const [dragOver, setDragOver] = useState(false)
  const [files, setFiles] = useState<File[]>([])
  const [uploading, setUploading] = useState<string | null>(null)

  const canUpload = !!myRole && canUploadDocuments(myRole)

  function addFiles(list: FileList | File[] | null | undefined) {
    if (!list) return
    const incoming = [...list]
    if (incoming.length === 0) return
    setFiles((prev) => {
      const seen = new Set(prev.map((f) => `${f.name}:${f.size}`))
      return [...prev, ...incoming.filter((f) => !seen.has(`${f.name}:${f.size}`))]
    })
  }

  // Same pipeline as the Docs tab: one POST per file, kind=permit, so
  // extraction, warnings and auto-activation all run unchanged.
  async function submit() {
    if (files.length === 0) return
    try {
      let ok = 0
      for (let i = 0; i < files.length; i++) {
        setUploading(files.length > 1 ? `Uploading ${i + 1} of ${files.length}…` : 'Uploading…')
        const fd = new FormData()
        fd.set('file', files[i])
        fd.set('kind', 'permit')
        const res = await fetch(`/api/trips/${trip.id}/documents`, { method: 'POST', body: fd })
        const json = await res.json().catch(() => ({}))
        if (!res.ok) toast.error(`${files[i].name}: ${json.error ?? 'upload failed'}`)
        else ok++
      }
      if (ok > 0) {
        toast.success(ok === 1 ? 'Permit uploaded' : `${ok} permits uploaded`)
        setFiles([])
        router.refresh()
      }
    } finally {
      setUploading(null)
    }
  }

  if (!canUpload) {
    return (
      <div className="m-auto max-w-md rounded-2xl border border-dashed border-amber-300 bg-amber-50 p-6 text-center">
        <p className="text-2xl">⏳</p>
        <h3 className="mt-2 font-bold text-amber-800">This trip is waiting on permits</h3>
        <p className="mt-2 text-sm leading-relaxed text-neutral-600">
          The carrier dispatcher has been asked to upload the permits. Once the first permit is
          uploaded, the Agent can answer permit questions here.
        </p>
      </div>
    )
  }

  return (
    <div className="m-auto w-full max-w-xl">
      <div className="text-center">
        <p className="text-2xl">⏳</p>
        <h3 className="mt-2 text-lg font-bold">This trip is waiting on permits</h3>
        <p className="mt-1 text-sm text-neutral-600">
          Upload the permits here. The Agent opens the moment the first one is attached.
        </p>
      </div>

      <label
        onDragOver={(e) => {
          e.preventDefault()
          setDragOver(true)
        }}
        onDragLeave={() => setDragOver(false)}
        onDrop={(e) => {
          e.preventDefault()
          setDragOver(false)
          addFiles(e.dataTransfer.files)
        }}
        className={`mt-5 block cursor-pointer rounded-2xl border-2 border-dashed p-10 text-center text-sm transition ${
          dragOver ? 'border-[#f5a623] bg-amber-50' : 'border-neutral-300 hover:border-neutral-400'
        }`}
      >
        <span className="block text-base font-bold">Drop permits here</span>
        <span className="mt-1 block text-xs text-neutral-500">
          or click to choose files · PDF, JPG, PNG or DOCX · several at once
        </span>
        <input
          type="file"
          multiple
          accept={ACCEPT}
          className="hidden"
          onChange={(e) => {
            addFiles(e.target.files)
            e.target.value = ''
          }}
        />
      </label>

      {files.length > 0 && (
        <ul className="mt-4 space-y-1.5">
          {files.map((f) => (
            <li
              key={`${f.name}:${f.size}`}
              className="flex items-center justify-between gap-3 rounded-lg border bg-white px-3 py-2 text-sm"
            >
              <span className="min-w-0 truncate">📄 {f.name}</span>
              <button
                type="button"
                disabled={!!uploading}
                onClick={() => setFiles((prev) => prev.filter((x) => x !== f))}
                className="shrink-0 text-xs text-neutral-400 hover:text-red-600 disabled:opacity-50"
              >
                Remove
              </button>
            </li>
          ))}
        </ul>
      )}

      <Button
        type="button"
        onClick={submit}
        disabled={files.length === 0 || !!uploading}
        className="mt-4 w-full bg-[#f5a623] font-bold text-[#0f1b2d] hover:bg-[#d98b06]"
      >
        {uploading ?? `Submit permit${files.length === 1 ? '' : 's'}`}
      </Button>
      <p className="mt-2 text-center text-[11px] text-neutral-400">
        Permit uploads are read automatically — dimensions, dates and warnings appear in Trip
        information. The first processed permit activates the trip.
      </p>
    </div>
  )
}

/* ---------------- Branch B: Synchron flow ---------------- */

const REQUEST_STATUS_LABEL: Record<ServiceRequest['status'], string> = {
  requested: 'Requested',
  in_progress: 'Processing',
  fulfilled: 'Fulfilled',
  cancelled: 'Cancelled',
}

function SynchronProcessing({
  trip,
  requests,
  orderAction,
  onOpenInfo,
}: {
  trip: Trip
  requests: ServiceRequest[]
  orderAction?: ReactNode
  onOpenInfo?: () => void
}) {
  const orders = requests
    .filter((r) => r.type === 'permit_request' && r.status !== 'cancelled')
    .sort((a, b) => (a.created_at < b.created_at ? 1 : -1))
  const newest = orders[0] ?? null
  const states = [...new Set(orders.map((r) => r.state_code).filter((s): s is string => !!s))]
  const orderIds = [...new Set(orders.map((r) => r.vendor_order_id).filter((s): s is string => !!s))]
  const payer =
    trip.payment_responsible_party === 'broker'
      ? 'Broker'
      : trip.payment_responsible_party === 'carrier'
        ? 'Carrier'
        : null

  return (
    <div className="m-auto w-full max-w-xl">
      <div className="text-center">
        <span className="relative mx-auto flex h-14 w-14 items-center justify-center">
          <span className="absolute inset-0 animate-ping rounded-full bg-blue-200/70" />
          <span className="relative flex h-14 w-14 items-center justify-center rounded-full bg-blue-100 text-2xl">
            🛠️
          </span>
        </span>
        <h3 className="mt-3 text-lg font-bold text-blue-900">
          Being processed by our trusted partner Synchron Permits
        </h3>
        <p className="mt-1 text-sm text-neutral-600">
          Permits will appear here as Synchron Permits attaches them; the Agent chat opens with the
          first one.
        </p>
      </div>

      <div className="mt-5 rounded-2xl border border-blue-200 bg-blue-50/60 p-4 text-sm">
        {newest ? (
          <>
            <p className="font-bold text-blue-900">
              Order created
              {orderIds.length > 0 ? ` · Order #${orderIds.join(', #')}` : ''}
            </p>
            <dl className="mt-2 grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-xs text-blue-900">
              <dt className="text-blue-800/70">Status</dt>
              <dd className="font-semibold">{REQUEST_STATUS_LABEL[newest.status]}</dd>
              <dt className="text-blue-800/70">Created</dt>
              <dd>{formatFullDate(orders[orders.length - 1].created_at)}</dd>
              {payer && (
                <>
                  <dt className="text-blue-800/70">Payment responsible party</dt>
                  <dd className="font-semibold">{payer}</dd>
                </>
              )}
              <dt className="text-blue-800/70">States in the order</dt>
              <dd>
                {states.length > 0 ? (
                  <span className="flex flex-wrap gap-1">
                    {states.map((s) => (
                      <span key={s} className="rounded-full border border-blue-200 bg-white px-2 py-0.5 font-semibold">
                        {stateName(s)}
                      </span>
                    ))}
                  </span>
                ) : (
                  <span className="text-blue-800/80">Provided by Synchron Permits with the order</span>
                )}
              </dd>
            </dl>
          </>
        ) : (
          <>
            <p className="font-bold text-blue-900">Order not created yet</p>
            <p className="mt-1 text-xs leading-relaxed text-blue-900/80">
              The carrier dispatcher was asked to order the permits for this trip from our trusted
              partner Synchron Permits.
              {payer ? ` Payment responsible party: ${payer}.` : ''}
            </p>
            {orderAction && <div className="mt-3">{orderAction}</div>}
          </>
        )}
      </div>

      <p className="mt-3 text-center text-[11px] text-neutral-400">
        Routes are included with Synchron-processed permits ·{' '}
        {onOpenInfo ? (
          <button type="button" onClick={onOpenInfo} className="underline hover:text-neutral-600">
            Details in Trip information
          </button>
        ) : (
          'Details in Trip information'
        )}
      </p>
    </div>
  )
}
