'use client'

import { useRef, useState } from 'react'
import { Mic } from 'lucide-react'
import Link from 'next/link'
import { toast } from 'sonner'
import { stateName } from '@/lib/domain/states'
import { formatInches, formatWeight } from '@/lib/format'
import { PilotPreviewBanner } from '@/components/app/pilot-preview-banner'
import { RouteStatusLine } from '@/components/app/pilot-tools/route-status-line'
import { ChatPanel } from '@/components/app/chat-panel'
import { StateNotesDialog } from '@/components/app/state-notes-dialog'
import { demoChatPermits, demoPilotAnswer, demoPilotChat, demoTripFor } from '@/lib/demo/pilot-agent'
import {
  ACCESS_SCOPE_LABELS,
  missingWorkspaceDocs,
  PILOT_INVITE_TARGETS,
  type PilotAccountType,
  paperworkList,
} from '@/lib/domain/pilot'
import {
  DEMO_PILOT_ACTIVITY,
  DEMO_PILOT_ASSIGNMENTS,
  DEMO_PILOT_COMPANY,
  DEMO_PILOT_DRIVERS,
  demoDriver,
  demoVehicle,
  inviterOf,
  scopeSummary,
  type DemoPilotAssignment,
  type DemoPilotDocument,
} from '@/lib/demo/pilot'
import { PILOT_COMPANY_DOCS_KEY, usePreviewValue } from '@/lib/demo/pilot-store'
import { PILOT_PRIVATE_TRIPS_KEY } from '@/app/pd-new-trip/private-trip-form'

const EMPTY_PRIVATE: DemoPilotAssignment[] = []
import { PilotToolsPanel } from '@/components/app/pilot-tools/pilot-tools-panel'
import { MyPilotTab, PaperworkPreviewSwitch, useViewerPaperworkAccess, type MyPilotEntry } from '@/components/app/pilot-tools/my-pilot-tab'
import { useExpenses, useInvoices } from '@/lib/demo/invoicing-store'
import { buildInvoicePdf, buildPaperworkPdf, openPdf } from '@/lib/demo/invoice-pdf'
import { brokerCanSeePilotInvoices } from '@/lib/domain/invoicing'

/**
 * Pilot trip workspace — Phase 1 design replica.
 *
 * Nash, 2026-09-12: "how do I open the trip details and the trip workspace…
 * as a pilot dispatch? … I wanna see what a pilot dispatch can see, right, on
 * how much access. If nothing was shared, he's not gonna see any permit. If
 * one permit is shared… he will see only one."
 *
 * Mirrors the real three-column workspace (trip switcher · chat · trip info
 * tabs) on demo data, filtered to the pilot's access scope. Same page serves
 * the pilot driver (`as=driver`) — the invite target and the documents gate
 * differ per account type.
 */

type Tab = 'overview' | 'documents' | 'people' | 'my-pilot' | 'history'

/** Who is looking: the pilot side, or the carrier / broker side of the same trip. */
export type WorkspaceViewer = PilotAccountType | 'carrier' | 'broker'

export function PilotAssignmentWorkspace({
  assignmentKey,
  as,
  initialTab = 'overview',
  isAdmin = false,
}: {
  /** Trip number (`ref`) or demo assignment id. */
  assignmentKey: string
  as: WorkspaceViewer
  initialTab?: Tab
  /** Internal admin — may bypass the documents gate (Nash, 2026-09-12). */
  isAdmin?: boolean
}) {
  const privateTrips = usePreviewValue<DemoPilotAssignment[]>(PILOT_PRIVATE_TRIPS_KEY, EMPTY_PRIVATE)
  const trip =
    [...privateTrips, ...DEMO_PILOT_ASSIGNMENTS].find((a) => a.ref === assignmentKey || a.id === assignmentKey) ?? DEMO_PILOT_ASSIGNMENTS[0]
  const [tab, setTab] = useState<Tab>(initialTab)
  // Nash: "for admin, add a button in there that will say admin bypass, which
  // when he clicks, it takes him to the trip info of the pilot dispatch."
  const [bypassed, setBypassed] = useState(false)
  // Below lg the chat and the trip-info panel share the screen via a toggle
  // (Mobile QA 2026-09-13) — same pattern as the real trip workspace.
  // Nash, 2026-09-13: same phone logic as the freight broker trip view — land
  // on Trip Info; buttons, swipe and a floating microphone reach the chat.
  const [mobileView, setMobileView] = useState<'chat' | 'info'>('info')
  const swipeStart = useRef<{ x: number; y: number; skip: boolean } | null>(null)
  function onSwipeStart(e: React.TouchEvent) {
    const t = e.touches[0]
    const target = e.target as HTMLElement | null
    swipeStart.current = { x: t.clientX, y: t.clientY, skip: !!target?.closest('.overflow-x-auto, input, textarea, select') }
  }
  function onSwipeEnd(e: React.TouchEvent) {
    const start = swipeStart.current
    swipeStart.current = null
    if (!start || start.skip) return
    const t = e.changedTouches[0]
    const dx = t.clientX - start.x
    const dy = t.clientY - start.y
    if (Math.abs(dx) < 70 || Math.abs(dx) < Math.abs(dy) * 1.5) return
    setMobileView(dx < 0 ? 'chat' : 'info')
  }
  // Section 2 is the same Agent chat the broker/carrier workspace has (Nash,
  // 2026-09-13: "identical… type, microphone, change languages"), scoped to
  // the shared permits. "Ask about this permit" focuses it on one permit.
  const [scopedPermitId, setScopedPermitId] = useState<string | null>(null)
  // "View state notes" on a permit card (same dialog as the driver screens).
  const [notesState, setNotesState] = useState<string | null>(null)
  const isDispatch = as === 'pilot_company'
  const homeHref = isDispatch ? '/pd-dashboard' : '/pc-dashboard'

  // The documents gate reads what the dispatch dashboard's Documents tab
  // uploaded in this browser session (demo store); nothing reaches a server.
  const companyDocs = usePreviewValue<DemoPilotDocument[]>(PILOT_COMPANY_DOCS_KEY, DEMO_PILOT_COMPANY.documents)
  const missing = isDispatch ? missingWorkspaceDocs(Object.fromEntries(companyDocs.map((d) => [d.key, d.status]))) : []

  // Carrier / broker side: the "My Pilot" tab as they see it (design review).
  if (as === 'carrier' || as === 'broker') return <CarrierSidePreview trip={trip} viewer={as} />

  if (missing.length > 0 && !bypassed) {
    return (
      <div className="mx-auto max-w-2xl px-4 py-8">
        <PilotPreviewBanner screen="Pilot Dispatch trip workspace — documents gate" />
        <div className="mt-6 rounded-2xl border border-danger/30 bg-danger-bg p-6">
          <p className="text-[10px] font-bold uppercase tracking-[0.14em] text-danger">Documents required</p>
          <h1 className="mt-1 text-xl font-extrabold tracking-tight">Upload your company documents before opening this trip</h1>
          <p className="mt-2 text-sm text-slate-body">
            The pilot dispatch controls the paperwork, so the certificate of insurance, W-9 and business license must be on file before the trip info opens. Still missing:
          </p>
          <ul className="mt-3 space-y-1 text-sm">
            {missing.map((s) => (
              <li key={s.key} className="flex items-center gap-2"><span className="text-danger">●</span> {s.label}</li>
            ))}
          </ul>
          <div className="mt-5 flex flex-wrap gap-2">
            <Link href="/pd-dashboard?tab=documents" className="rounded-lg bg-navy-900 px-4 py-2 text-sm font-bold text-white hover:bg-navy-800">Upload documents</Link>
            <Link href={homeHref} className="rounded-lg border border-line bg-white px-4 py-2 text-sm font-semibold text-slate-body">Back to assignments</Link>
            {isAdmin && (
              <button
                onClick={() => setBypassed(true)}
                className="ml-auto rounded-lg border border-amber-300 bg-amber-50 px-4 py-2 text-sm font-bold text-amber-900 hover:bg-amber-100"
                title="Internal admin only — skips the documents gate and opens the trip info"
              >
                Admin bypass →
              </button>
            )}
          </div>
          <p className="mt-4 text-xs text-slate-body">
            Assignment {trip.ref} · {trip.origin} → {trip.destination} · invited by {trip.carrier}. The invitation stays in Pending Assignments until the documents are in.
          </p>
        </div>
      </div>
    )
  }

  const shared = trip.permits.filter((p) => p.shared)
  const states = [...new Set(shared.map((p) => p.state))]
  const nothingShared = trip.scopes.length === 0
  const full = trip.scopes.some((s) => s.type === 'full_trip')
  const drv = demoDriver(trip.pilotDriverId)
  const veh = demoVehicle(trip.vehicleId)
  const invitees = PILOT_INVITE_TARGETS[as]

  return (
    <div className="flex h-[calc(100vh-3.5rem)] min-h-0 bg-neutral-50" onTouchStart={onSwipeStart} onTouchEnd={onSwipeEnd}>
      {/* ===== Section 1: assignment switcher (mirrors TripSidebar) ===== */}
      <aside className="hidden w-64 shrink-0 flex-col border-r bg-white lg:flex">
        <div className="border-b px-4 py-3">
          <p className="text-[10px] font-bold uppercase tracking-[0.14em] text-slate-body/70">{isDispatch ? 'Assignments' : 'My assignments'}</p>
          <Link href={homeHref} className="mt-1 block text-xs font-semibold text-info hover:underline">← Dashboard</Link>
        </div>
        <div className="min-h-0 flex-1 overflow-y-auto p-2">
          {DEMO_PILOT_ASSIGNMENTS.filter((a) => isDispatch || a.pilotDriverId === trip.pilotDriverId || a.id === trip.id).map((a) => (
            <Link
              key={a.id}
              href={`/${isDispatch ? 'pd' : 'pc'}-trip-workspace/${a.ref}`}
              className={`block rounded-xl p-3 text-xs ${a.id === trip.id ? 'bg-navy-900 text-white' : 'hover:bg-paper'}`}
            >
              <p className="truncate font-bold">{a.origin} → {a.destination}</p>
              <p className={`truncate ${a.id === trip.id ? 'text-navy-100' : 'text-slate-body'}`}>{a.ref} · {scopeSummary(a.scopes)}</p>
            </Link>
          ))}
        </div>
      </aside>

      {/* ===== Section 2: chat (pilot assignment chat + agent) ===== */}
      <main className={`${mobileView === 'info' ? 'hidden' : 'flex'} min-w-0 flex-1 flex-col lg:flex`}>
        <div className="border-b bg-white px-4 py-2.5">
          <PilotPreviewBanner screen={isDispatch ? 'Pilot Dispatch trip workspace' : 'Pilot Driver trip workspace'} />
          {bypassed && missing.length > 0 && (
            <p className="mt-2 rounded-lg border border-amber-300 bg-amber-50 px-3 py-1.5 text-[11px] font-semibold text-amber-900">
              Admin bypass — the documents gate was skipped. Still missing: {missing.map((m) => m.label).join(', ')}. A pilot dispatch would not get past the gate.
            </p>
          )}
          <div className="mt-2 flex items-center justify-between gap-3">
            <div className="min-w-0">
              <p className="truncate text-sm font-bold tracking-tight">{trip.origin} → {trip.destination}</p>
              <p className="truncate text-xs text-neutral-500">{trip.commodity} · {trip.carrier} · <span className="font-mono">{trip.ref}</span></p>
            </div>
            <div className="flex shrink-0 items-center gap-2">
              <span className="rounded-full bg-paper px-2.5 py-1 text-[11px] font-bold capitalize ring-1 ring-inset ring-line">{trip.status}</span>
              <button onClick={() => setMobileView('info')} className="rounded-lg bg-[#0f1b2d] px-4 py-2.5 text-sm font-bold text-white shadow-sm hover:bg-[#16263e] lg:hidden">📋 Trip Info</button>
            </div>
          </div>
        </div>
        {/* Section 2: the same Agent chat as the broker/carrier trip view —
            type or tap to talk, languages, state selector limited to the
            shared states, share-my-questions choice. Offline replica. */}
        <div className="flex min-h-0 flex-1 flex-col">
          {nothingShared ? (
            <div className="m-4 rounded-2xl border border-dashed border-line bg-white p-8 text-center text-sm text-slate-body">
              The carrier has not shared any permits yet. You can accept the assignment and message the carrier; the agent has nothing to answer from until access is shared.
            </div>
          ) : (
            <ChatPanel
              key={trip.id}
              trip={demoTripFor(trip)}
              chat={demoPilotChat(trip, isDispatch ? 'pilot-dispatch' : (drv?.id ?? 'pilot-driver'), isDispatch ? DEMO_PILOT_COMPANY.mainContact.split(' (')[0] : (drv?.name ?? 'Pilot driver'))}
              permits={demoChatPermits(trip)}
              myRole="pilot"
              myUserId={isDispatch ? 'pilot-dispatch' : (drv?.id ?? 'pilot-driver')}
              participants={[]}
              scopedPermit={demoChatPermits(trip).find((p) => p.id === scopedPermitId) ?? null}
              onExitScope={() => setScopedPermitId(null)}
              shareChat
              offline={{ answer: demoPilotAnswer(trip), wholeTrip: full }}
            />
          )}
        </div>
      </main>

      {/* ===== Section 3: trip info ===== */}
      <aside className={`${mobileView === 'chat' ? 'hidden' : 'flex'} w-full flex-col border-l bg-white lg:flex lg:max-w-md lg:shrink-0`}>
        <div className="flex items-center justify-between border-b px-4 py-2.5 lg:hidden">
          <p className="text-sm font-bold">Trip information</p>
          <button onClick={() => setMobileView('chat')} className="rounded-lg bg-[#f5a623] px-4 py-2.5 text-sm font-bold text-[#0f1b2d] shadow-sm hover:bg-[#d98b06]">🎙 Ask the Agent</button>
        </div>
        <div className="space-y-2 border-b p-4">
          <p className="text-[10px] font-bold uppercase tracking-[0.14em] text-slate-body/70">Shared with {isDispatch ? DEMO_PILOT_COMPANY.name : drv?.name ?? 'you'}</p>
          <p className="text-sm font-semibold">{scopeSummary(trip.scopes)}</p>
          {trip.scopes.map((s, i) => (
            <p key={i} className="text-xs text-slate-body">{ACCESS_SCOPE_LABELS[s.type]}</p>
          ))}
          {trip.status === 'invited' && (
            <button onClick={() => toast.success('Preview: assignment accepted')} className="w-full rounded-lg bg-amber-brand py-2 text-xs font-bold text-navy-950">Accept assignment</button>
          )}
        </div>
        <div className="flex border-b text-xs font-semibold">
          {(['overview', 'documents', 'people', 'my-pilot', 'history'] as Tab[]).map((t) => (
            <button key={t} onClick={() => setTab(t)} className={`flex-1 border-b-2 py-2 capitalize ${tab === t ? 'border-amber-brand text-ink' : 'border-transparent text-slate-body'}`}>{t === 'my-pilot' ? 'My Pilot' : t}</button>
          ))}
        </div>
        <div className="min-h-0 flex-1 overflow-y-auto p-4">
          {tab === 'overview' && (
            <div className="space-y-3">
              <p className="text-[10px] font-bold uppercase tracking-[0.14em] text-slate-body/70">Permits ({shared.length} of {trip.permits.length} visible)</p>
              {nothingShared && (
                <p className="rounded-xl border border-dashed border-line p-6 text-center text-xs text-slate-body">No permits shared with you on this trip. The carrier chose “decide later” — they can share states, permits or the full trip at any time.</p>
              )}
              {/* Overall dimensions — same block the broker overview shows above
                  its permits (Nash, 2026-09-13: "the overall dimensions are
                  missing in that overview section"). */}
              {!nothingShared && (
                <div className="rounded-xl border border-line p-3">
                  <p className="text-[10px] font-bold uppercase tracking-wide text-slate-body/70">Overall dimensions</p>
                  <div className="mt-2 grid grid-cols-2 gap-2 text-xs">
                    {([
                      ['Width', trip.overallDims?.w, formatInches],
                      ['Height', trip.overallDims?.h, formatInches],
                      ['Length', trip.overallDims?.l, formatInches],
                      ['Weight', trip.overallDims?.gvw, formatWeight],
                    ] as const).map(([k, v, fmt]) => (
                      <div key={k} className="rounded-lg bg-paper px-2.5 py-1.5">
                        <p className="text-[10px] font-bold uppercase text-slate-body/60">{k}</p>
                        <p className="font-semibold">{v == null ? '—' : fmt(v)}</p>
                      </div>
                    ))}
                  </div>
                  <p className="mt-1.5 text-[11px] text-slate-body">Truck + trailer combined — every shared permit is cross-checked against these.</p>
                </div>
              )}

              {states.map((s) => (
                <div key={s} className="space-y-2">
                  {shared.filter((p) => p.state === s).map((p) => {
                    const bad = (permitValue: number | undefined, needed: number | undefined) =>
                      permitValue != null && needed != null && permitValue < needed
                    const anyBad = !!p.dims && !!trip.overallDims && (p.dims.w < trip.overallDims.w || p.dims.h < trip.overallDims.h || p.dims.l < trip.overallDims.l || p.dims.gvw < trip.overallDims.gvw)
                    return (
                      /* Same card as the broker / carrier trip view (TripPermitCard):
                         state name opens the state notes, W·H·L·GVW row against the
                         overall dimensions, then Ask about this permit · View permit ·
                         View provisions · View state notes. */
                      <div key={p.id} className={`rounded-lg border p-2.5 ${anyBad ? 'border-red-200 bg-red-50/40' : 'bg-neutral-50'}`}>
                        <div className="flex flex-wrap items-center justify-between gap-2">
                          <p className="min-w-0 flex-1 basis-[12rem] truncate text-sm font-semibold">
                            <button type="button" onClick={() => setNotesState(p.state)} className="rounded-sm decoration-neutral-300 underline-offset-2 hover:underline" title={`Learn more about ${stateName(p.state)} — travel info, escorts, limits`}>
                              {stateName(p.state) || p.state}
                            </button>
                            <span className="ml-1.5 font-mono text-[11px] text-neutral-400">{p.permitNumber}</span>
                            <span className="ml-1.5 text-[11px] font-normal text-neutral-500">{p.effective.slice(5)} – {p.expires.slice(5)}</span>
                          </p>
                          <RouteStatusLine route={p.route ?? null} compact />
                        </div>
                        <div className="mt-1.5 flex items-center gap-3 text-[11px] text-neutral-600">
                          {([
                            ['W', p.dims?.w, trip.overallDims?.w, formatInches],
                            ['H', p.dims?.h, trip.overallDims?.h, formatInches],
                            ['L', p.dims?.l, trip.overallDims?.l, formatInches],
                            ['GVW', p.dims?.gvw, trip.overallDims?.gvw, formatWeight],
                          ] as const).map(([label, value, needed, fmt]) => (
                            <span key={label} className={bad(value, needed) ? 'font-bold text-red-600' : ''}>
                              <span className={`font-bold ${bad(value, needed) ? 'text-red-400' : 'text-neutral-400'}`}>{label} </span>
                              {value == null ? '—' : fmt(value)}
                              {bad(value, needed) && ' ⚠'}
                            </span>
                          ))}
                        </div>
                        <p className="mt-1 text-[11px] text-slate-body">Escort: {p.escort} · Curfew: {p.curfew}</p>
                        <div className="mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px]">
                          <button type="button" onClick={() => { setScopedPermitId(p.id); setMobileView('chat') }} className="font-semibold text-[#0f1b2d] hover:underline" title="Focus the Agent chat on this exact permit">💬 Ask about this permit</button>
                          <button type="button" onClick={() => toast.success('Preview: permit PDF would open here')} className="font-semibold text-info hover:underline">View permit</button>
                          <button type="button" onClick={() => toast.info('Provisions come from Synchron Permits — available once the connection is live.')} className="font-semibold text-neutral-400 hover:text-neutral-600" title="Provisions arrive with the Synchron connection">View provisions</button>
                          <button type="button" onClick={() => setNotesState(p.state)} className="font-semibold text-info hover:underline">View state notes</button>
                        </div>
                      </div>
                    )
                  })}
                </div>
              ))}
              {trip.permits.some((p) => !p.shared) && !nothingShared && (
                <p className="rounded-xl bg-neutral-50 p-3 text-xs text-slate-body">🔒 {trip.permits.filter((p) => !p.shared).length} more permit(s) on this trip are outside your access.</p>
              )}
              {full && (
                <div className="space-y-1 rounded-xl border border-line p-3 text-xs">
                  <p className="font-bold">Trip overview</p>
                  <p>Carrier dispatcher: {trip.carrierDispatcher.name} · {trip.carrierDispatcher.phone}</p>
                  <p>Carrier driver: {trip.carrierDriver.name} · {trip.carrierDriver.phone}</p>
                  <p>Truck / trailer: {trip.truck} · {trip.trailer}</p>
                  <p>Overall: {trip.overall} · {trip.weight}</p>
                </div>
              )}
              <div className="rounded-xl border border-line p-3 text-xs">
                <p className="font-bold">Our assignment</p>
                <p className="text-slate-body">Position {trip.position} · driver {drv?.name ?? 'unassigned'} · unit {veh?.unitNumber ?? '—'}</p>
              </div>
            </div>
          )}

          {tab === 'documents' && (
            <div className="space-y-2">
              <p className="text-[10px] font-bold uppercase tracking-[0.14em] text-slate-body/70">Shared files</p>
              {shared.length === 0 && <p className="rounded-xl border border-dashed border-line p-6 text-center text-xs text-slate-body">No files shared with you yet.</p>}
              {shared.map((p) => (
                <button key={p.id} onClick={() => toast.success('Preview: permit PDF would open here')} className="flex w-full items-center justify-between rounded-xl border border-line p-3 text-left text-xs hover:bg-paper">
                  <span>📄 {p.state} permit · {p.permitNumber}</span>
                  <span className="text-info">Open</span>
                </button>
              ))}
              <p className="rounded-xl bg-danger-bg p-3 text-xs text-danger">Never shown to pilot accounts: rate confirmation, pricing, billing, broker/carrier private notes, unshared permits.</p>
            </div>
          )}

          {tab === 'people' && (
            <PeoplePanel trip={trip} as={as} invitees={invitees} />
          )}

          {/* Nash, 2026-09-12: "section three could have a tab there that'll
              say my pilot. And in there, we can have all these tools for the
              pilot dispatch… he can invite the driver in there. He can
              generate the invoice on behalf of the driver." */}
          {tab === 'my-pilot' && (
            <div className="space-y-4">
              <div className="rounded-xl border border-line p-3 text-xs">
                <p className="font-bold">Our pilot on this trip</p>
                <p className="mt-0.5 text-slate-body">
                  {drv ? `${drv.name} · ${drv.phone}` : 'No driver assigned yet'} · unit {veh?.unitNumber ?? '—'} · position {trip.position}
                </p>
                {isDispatch && (
                  <button onClick={() => setTab('people')} className="mt-2 rounded-lg border border-line bg-white px-3 py-1.5 text-xs font-semibold">+ Add / invite another driver (same access)</button>
                )}
              </div>
              <PilotToolsPanel assignment={trip} actor={as} independentDriver={false} />
            </div>
          )}

          {tab === 'history' && (
            <div className="space-y-2">
              {DEMO_PILOT_ACTIVITY.filter((e) => e.detail.includes(trip.ref)).map((e, i) => (
                <div key={i} className="rounded-xl border border-line p-3 text-xs">
                  <p className="font-semibold">{e.action}</p>
                  <p className="text-slate-body">{e.detail}</p>
                  <p className="mt-0.5 font-mono text-[10px] text-slate-body/70">{e.at}</p>
                </div>
              ))}
              {DEMO_PILOT_ACTIVITY.filter((e) => e.detail.includes(trip.ref)).length === 0 && (
                <p className="rounded-xl border border-dashed border-line p-6 text-center text-xs text-slate-body">No activity recorded yet.</p>
              )}
            </div>
          )}
        </div>
      </aside>
      <StateNotesDialog code={notesState} onClose={() => setNotesState(null)} />

      {/* Phone only: floating microphone opens the chat while Trip Info is showing. */}
      {mobileView === 'info' && (
        <button
          type="button"
          onClick={() => setMobileView('chat')}
          className="fixed bottom-5 right-5 z-40 grid h-14 w-14 place-items-center rounded-full bg-[#f5a623] text-[#0f1b2d] shadow-lg ring-4 ring-white transition hover:bg-[#d98b06] lg:hidden"
          title="Ask the Agent"
          aria-label="Open the Agent chat"
        >
          <Mic className="size-6" />
        </button>
      )}
    </div>
  )
}

/**
 * Nash: "the access will be replicated to any pilots that he invites to this
 * trip… If the trip was shared with a pilot driver for only one state and
 * that pilot driver will add a dispatch into this, which he can do — he can
 * add only a dispatch — that pilot dispatch also will see only that one."
 */
function PeoplePanel({ trip, as, invitees }: { trip: DemoPilotAssignment; as: PilotAccountType; invitees: string[] }) {
  const isDispatch = as === 'pilot_company'
  const drv = demoDriver(trip.pilotDriverId)
  const [added, setAdded] = useState<{ name: string; role: string }[]>([])
  const [form, setForm] = useState({ name: '', email: '', phone: '' })
  const approved = DEMO_PILOT_DRIVERS.filter((d) => d.relationship === 'Approved')

  const people = [
    { name: trip.carrierDispatcher.name, role: 'Carrier dispatcher', status: 'Joined' },
    { name: trip.carrierDriver.name, role: 'Carrier driver', status: 'Joined' },
    { name: DEMO_PILOT_COMPANY.name, role: 'Pilot dispatch', status: trip.status === 'invited' ? 'Invited' : 'Joined' },
    ...(drv ? [{ name: drv.name, role: 'Pilot driver', status: 'Joined' }] : []),
    ...added.map((a) => ({ ...a, status: 'Invited' })),
  ]

  return (
    <div className="space-y-3">
      <div className="rounded-xl border border-line p-3">
        <p className="text-xs font-bold">Add {invitees.join(' / ').toLowerCase()} to this trip</p>
        <p className="mt-0.5 text-[11px] text-slate-body">
          They get exactly your access — <span className="font-semibold text-ink">{scopeSummary(trip.scopes)}</span> — never more.
          {isDispatch ? ' A pilot dispatch adds pilot drivers.' : ' A pilot driver can add only their pilot dispatch.'}
        </p>
        {isDispatch && approved.length > 0 && (
          <div className="mt-2 flex flex-wrap gap-1.5">
            {approved.map((d) => (
              <button key={d.id} onClick={() => { setAdded((l) => [...l, { name: d.name, role: 'Pilot driver' }]); toast.success(`Preview: ${d.name} added with the same access`) }} className="rounded-full bg-paper px-2.5 py-1 text-[11px] font-semibold ring-1 ring-inset ring-line hover:text-ink">+ {d.name}</button>
            ))}
          </div>
        )}
        <div className="mt-2 grid gap-1.5">
          {(['name', 'email', 'phone'] as const).map((k) => (
            <input key={k} value={form[k]} onChange={(e) => setForm({ ...form, [k]: e.target.value })} placeholder={k === 'name' ? `${invitees[0]} name` : k === 'email' ? 'Email' : 'Phone'} className="rounded-lg border border-line px-2.5 py-1.5 text-xs" />
          ))}
          <button
            onClick={() => { if (!form.name || !form.email) { toast.error('Name and email are required'); return } setAdded((l) => [...l, { name: form.name, role: invitees[0] }]); setForm({ name: '', email: '', phone: '' }); toast.success('Preview: invitation queued with your access (no email in this phase)') }}
            className="rounded-lg bg-navy-900 py-1.5 text-xs font-bold text-white"
          >
            Send invitation · access: {scopeSummary(trip.scopes)}
          </button>
        </div>
      </div>
      <div className="space-y-1.5">
        {people.map((p, i) => (
          <div key={i} className="flex items-center justify-between rounded-xl border border-line p-3 text-xs">
            <div>
              <p className="font-semibold">{p.name}</p>
              <p className="text-slate-body">{p.role}</p>
            </div>
            <span className={`font-semibold ${p.status === 'Joined' ? 'text-ok' : 'text-warn'}`}>{p.status === 'Joined' ? '● Joined' : '○ Invited'}</span>
          </div>
        ))}
      </div>
      <p className="text-[11px] text-slate-body">You see only the people on your side of this assignment and the carrier contacts shared with you — not the full trip contact list.</p>
    </div>
  )
}


/**
 * The carrier's / broker's "My Pilot" tab on this assignment, on demo data —
 * Nash: "We can put it in the design review… show it how it looks… admin can
 * see all the before, after." The real carrier workspace renders the same
 * MyPilotTab from real participants (trip-workspace.tsx).
 */
function CarrierSidePreview({ trip, viewer }: { trip: DemoPilotAssignment; viewer: 'carrier' | 'broker' }) {
  const { invoices } = useInvoices()
  const { expenses } = useExpenses()
  // Paperwork (Nash, 2026-09-13): company documents on the dispatch entry,
  // driver documents on the driver entry; uploads made on the pilot side show here.
  const companyDocs = usePreviewValue<DemoPilotDocument[]>(PILOT_COMPANY_DOCS_KEY, DEMO_PILOT_COMPANY.documents)
  const paperworkAccess = useViewerPaperworkAccess()
  const drv = demoDriver(trip.pilotDriverId)
  const veh = demoVehicle(trip.vehicleId)
  const states = [...new Set(trip.permits.filter((p) => p.shared).map((p) => p.state))]
  const access = scopeSummary(trip.scopes)
  const pilots: MyPilotEntry[] = [
    {
      name: DEMO_PILOT_COMPANY.name,
      kind: 'Pilot dispatch',
      phone: DEMO_PILOT_COMPANY.phone,
      email: DEMO_PILOT_COMPANY.email,
      access,
      states,
      status: trip.status === 'invited' ? 'Invited' : 'Joined',
      invitedBy: `${inviterOf(trip).name} (${inviterOf(trip).role})`,
      dispatch: DEMO_PILOT_COMPANY.mainContact,
      contactHidden: viewer === 'broker' && trip.invitedBy !== 'broker',
      documents: paperworkList('pilot_company', companyDocs),
    },
    ...(drv
      ? [{
          name: drv.name,
          kind: 'Pilot driver' as const,
          phone: drv.phone,
          email: drv.email,
          access,
          states,
          status: 'Joined',
          car: veh ? `${veh.unitNumber} · ${veh.year} ${veh.make} ${veh.model} · ${veh.color} · ${veh.plateState} ${veh.plate}` : undefined,
          dispatch: DEMO_PILOT_COMPANY.name,
          position: trip.position,
          invitedBy: `${DEMO_PILOT_COMPANY.name} (inherited access)`,
          contactHidden: viewer === 'broker' && trip.invitedBy !== 'broker',
          documents: paperworkList('pilot_driver', drv.documents),
        }]
      : []),
  ]
  const showInvoices =
    viewer === 'carrier' || brokerCanSeePilotInvoices({ pilotInvitedByBroker: trip.invitedBy === 'broker', brokerInvitedByPilot: false })
  return (
    <div className="mx-auto max-w-3xl px-4 py-6">
      <PilotPreviewBanner screen={viewer === 'carrier' ? 'Carrier dispatch — “My Pilot” tab' : 'Broker — “My Pilot” tab'} />
      <div className="mt-4 rounded-2xl border border-line bg-white p-4">
        <p className="text-xs text-slate-body">
          {viewer === 'carrier' ? 'Carrier trip workspace' : 'Broker trip view'} · section 3 · tab between People and History · trip {trip.ref}
        </p>
        <div className="mt-3"><PaperworkPreviewSwitch /></div>
        <MyPilotTab
          viewer={viewer}
          pilots={pilots}
          invoices={invoices.filter((i) => i.assignmentId === trip.id)}
          showInvoices={showInvoices}
          onViewInvoice={async (inv) => openPdf(await buildInvoicePdf(inv, expenses), `${inv.invoiceNumber}.pdf`, 'view')}
          paperwork={paperworkAccess.access}
          paperworkPlan={paperworkAccess.plan}
          onViewDocument={async (entry, d) =>
            openPdf(
              await buildPaperworkPdf({ label: d.label, owner: entry.name, ownerKind: entry.kind, status: d.status, expirationDate: d.expirationDate, uploadedAt: d.uploadedAt, tripRef: trip.ref }),
              `${entry.name.replace(/\s+/g, '-')}-${d.key}.pdf`,
              'view',
            )}
        />
      </div>
      <div className="mt-3 flex flex-wrap gap-2 text-xs">
        <Link href={`/admin/pilot-preview/${trip.ref}?as=carrier`} className={`rounded-full px-3 py-1 font-semibold ring-1 ring-inset ${viewer === 'carrier' ? 'bg-navy-900 text-white ring-navy-900' : 'bg-white ring-line'}`}>Carrier view</Link>
        <Link href={`/admin/pilot-preview/${trip.ref}?as=broker`} className={`rounded-full px-3 py-1 font-semibold ring-1 ring-inset ${viewer === 'broker' ? 'bg-navy-900 text-white ring-navy-900' : 'bg-white ring-line'}`}>Broker view</Link>
        <Link href={`/pd-trip-workspace/${trip.ref}`} className="rounded-full bg-white px-3 py-1 font-semibold ring-1 ring-inset ring-line">Pilot dispatch view</Link>
        <Link href={`/pc-trip-workspace/${trip.ref}`} className="rounded-full bg-white px-3 py-1 font-semibold ring-1 ring-inset ring-line">Pilot driver view</Link>
      </div>
    </div>
  )
}
