'use client'

import { createContext, useContext, useRef, useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import {
  COMPANY_ROLES, VERIFICATION_LABELS, canManageCompany, companyRoleLabel,
} from '@/lib/domain/company'
import { formatDateTime, formatFullDate } from '@/lib/format'
import type {
  BrokerPage, Company, CompanyAuditEvent, CompanyClaim, CompanyMembership, CompanyRole,
} from '@/types/db'

export interface MemberView {
  membership: CompanyMembership
  claim: CompanyClaim | null
  name: string
  email: string
  phone: string | null
}

/**
 * Design preview (Task 83): when true, every action is simulated — nothing
 * is written — so the team can walk the admin screens on demo data before
 * the backend exists. Nash: "we should show what happens if API would have
 * worked… give the ability for our UI team to see how this will look."
 */
export const CompanyPreviewContext = createContext(false)

/** One call shape for every company action (see /api/company ops). */
async function companyCallReal(body: Record<string, unknown>) {
  const res = await fetch('/api/company', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  const json = await res.json().catch(() => ({}))
  if (!res.ok) {
    toast.error(json.error ?? 'Action failed')
    return null
  }
  return json
}

function useCompanyCall() {
  const preview = useContext(CompanyPreviewContext)
  if (!preview) return companyCallReal
  return async (body: Record<string, unknown>) => {
    toast.info('Design preview — nothing is saved.')
    return { ok: true, preview: true, slug: body.slug, ...body }
  }
}

/**
 * Corporate Profile (§20) + Company Access (§28) + Audit log — "a control
 * panel for approving people, managing roles, and protecting company access"
 * (§33). Edit controls render only for owner/admin; the API enforces it too.
 */
export function CompanyConsole({
  company,
  myRole,
  members,
  audit,
  brokerPage,
}: {
  company: Company
  myRole: CompanyRole
  members: MemberView[]
  audit: CompanyAuditEvent[]
  brokerPage: BrokerPage | null
}) {
  const canEdit = canManageCompany(myRole)
  const pending = members.filter((m) => m.membership.status === 'pending')
  const [tab, setTab] = useState('profile')

  return (
    <>
      <div className="mt-3 flex flex-wrap items-center gap-4">
        {company.logo_url ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={company.logo_url} alt="" className="h-16 w-16 rounded-xl border bg-white object-contain p-1" />
        ) : (
          <span className="grid h-16 w-16 place-items-center rounded-xl bg-[#0f1b2d] text-xl font-extrabold text-[#f5a623]">
            {company.display_name.slice(0, 1).toUpperCase()}
          </span>
        )}
        <div className="min-w-0">
          <h1 className="truncate text-2xl font-bold tracking-tight">{company.display_name}</h1>
          <p className="text-sm text-neutral-500">
            {company.company_type === 'carrier' ? 'Carrier company' : 'Broker company'}
            {company.mc_number ? ` · MC ${company.mc_number}` : ''} ·{' '}
            {VERIFICATION_LABELS[company.verification_status]} (level {company.verification_level}) · You:{' '}
            {companyRoleLabel(myRole, company.company_type)}
            {!canEdit && ' · Managed by company admin'}
          </p>
        </div>
      </div>

      <Tabs value={tab} onValueChange={setTab} className="mt-6">
        <TabsList>
          <TabsTrigger value="profile">Corporate Profile</TabsTrigger>
          <TabsTrigger value="access">
            Company Access{pending.length > 0 ? ` (${pending.length})` : ''}
          </TabsTrigger>
          <TabsTrigger value="audit">Audit log</TabsTrigger>
        </TabsList>
        <TabsContent value="profile">
          <ProfileTab
            company={company}
            canEdit={canEdit}
            brokerPage={brokerPage}
            pendingCount={pending.length}
            onGoAccess={() => setTab('access')}
          />
        </TabsContent>
        <TabsContent value="access">
          <AccessTab company={company} canEdit={canEdit} members={members} />
        </TabsContent>
        <TabsContent value="audit">
          <AuditTab audit={audit} />
        </TabsContent>
      </Tabs>
    </>
  )
}

/* ---------------- Corporate Profile (§20) ---------------- */

function ProfileTab({
  company,
  canEdit,
  brokerPage,
  pendingCount,
  onGoAccess,
}: {
  company: Company
  canEdit: boolean
  brokerPage: BrokerPage | null
  pendingCount: number
  onGoAccess: () => void
}) {
  const router = useRouter()
  const companyCall = useCompanyCall()
  const preview = useContext(CompanyPreviewContext)
  const logoRef = useRef<HTMLInputElement>(null)
  const [busy, setBusy] = useState(false)
  const [form, setForm] = useState({
    display_name: company.display_name,
    legal_name: company.legal_name,
    mc_number: company.mc_number ?? '',
    dot_number: company.dot_number ?? '',
    physical_address: company.physical_address ?? '',
    corporate_email: company.corporate_email ?? '',
    corporate_phone: company.corporate_phone ?? '',
    website: company.website ?? '',
    notification_recipients: company.notification_recipients.join(', '),
    agents_see_all_trips: company.agents_see_all_trips,
  })
  const [slug, setSlug] = useState(brokerPage?.slug ?? '')
  const [defaults, setDefaults] = useState({
    policy: brokerPage?.default_permit_policy ?? 'ask',
    payment: brokerPage?.default_payment_party ?? 'ask',
  })
  // FMCSA legal name is locked (§20); MC change goes to admin review.
  const legalLocked = !!company.source_fmcsa_id
  const mcChanged = form.mc_number.trim() !== (company.mc_number ?? '')

  const set = (k: keyof typeof form, v: string | boolean) => setForm((f) => ({ ...f, [k]: v }))

  async function saveProfile() {
    setBusy(true)
    try {
      const json = await companyCall({ op: 'profile', ...form })
      if (json) {
        toast.success(json.mc_review ? 'Profile saved — the MC number change was sent for admin review' : 'Corporate profile saved')
        router.refresh()
      }
    } finally {
      setBusy(false)
    }
  }

  async function uploadLogo(file: File) {
    if (preview) {
      toast.info('Design preview — nothing is saved.')
      if (logoRef.current) logoRef.current.value = ''
      return
    }
    setBusy(true)
    try {
      const fd = new FormData()
      fd.set('file', file)
      const res = await fetch('/api/company/logo', { method: 'POST', body: fd })
      const json = await res.json().catch(() => ({}))
      if (!res.ok) toast.error(json.error ?? 'Could not upload the logo')
      else {
        toast.success('Logo updated')
        router.refresh()
      }
    } finally {
      setBusy(false)
      if (logoRef.current) logoRef.current.value = ''
    }
  }

  async function saveSlug() {
    setBusy(true)
    try {
      const json = await companyCall({ op: 'slug', slug })
      if (json) {
        toast.success(`Intake page is now /intake/${json.slug} — the old link redirects`)
        setSlug(json.slug)
        router.refresh()
      }
    } finally {
      setBusy(false)
    }
  }

  async function saveDefaults() {
    setBusy(true)
    try {
      const json = await companyCall({ op: 'defaults', ...defaults })
      if (json) {
        toast.success('Default permit workflow saved')
        router.refresh()
      }
    } finally {
      setBusy(false)
    }
  }

  const field = (label: string, key: keyof typeof form, opts?: { locked?: boolean; hint?: string; type?: string }) => (
    <div className="space-y-1.5">
      <Label>{label}</Label>
      <Input
        type={opts?.type ?? 'text'}
        value={String(form[key])}
        onChange={(e) => set(key, e.target.value)}
        disabled={!canEdit || opts?.locked || busy}
      />
      {opts?.hint && <p className="text-[11px] text-neutral-500">{opts.hint}</p>}
    </div>
  )

  return (
    <div className="mt-4 space-y-5">
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Company logo</CardTitle>
          <CardDescription>Shown on your corporate profile and on your public intake page.</CardDescription>
        </CardHeader>
        <CardContent className="flex flex-wrap items-center gap-4">
          {company.logo_url ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={company.logo_url} alt="" className="h-20 w-20 rounded-xl border bg-white object-contain p-1" />
          ) : (
            <span className="grid h-20 w-20 place-items-center rounded-xl border border-dashed text-xs text-neutral-400">
              No logo
            </span>
          )}
          {canEdit && (
            <div>
              <Input
                ref={logoRef}
                type="file"
                accept=".png,.jpg,.jpeg,.svg"
                disabled={busy}
                onChange={(e) => e.target.files?.[0] && uploadLogo(e.target.files[0])}
              />
              <p className="mt-1 text-[11px] text-neutral-500">PNG, JPG or SVG · up to 2 MB</p>
            </div>
          )}
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Company details</CardTitle>
          <CardDescription>
            {canEdit
              ? 'Editable by Company Owner / Admin. The legal name from FMCSA is locked; an MC number change requires admin review.'
              : 'Managed by company admin — read only.'}
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2">
          {field('Display name', 'display_name')}
          {field('Legal name', 'legal_name', { locked: legalLocked, hint: legalLocked ? 'From FMCSA — locked' : undefined })}
          {field('MC number', 'mc_number', {
            hint: mcChanged ? 'Changing the MC number sends the change to HeavyHaul Agent admin review.' : undefined,
          })}
          {field('DOT number', 'dot_number')}
          <div className="space-y-1.5">
            <Label>Company type</Label>
            <Input value={company.company_type === 'carrier' ? 'Carrier' : 'Broker'} disabled />
          </div>
          {field('Business address', 'physical_address')}
          {field('Corporate email', 'corporate_email', { type: 'email', hint: 'Where company access requests are sent.' })}
          {field('Corporate phone', 'corporate_phone')}
          {field('Website', 'website')}
          {field('Notification recipients', 'notification_recipients', { hint: 'Comma-separated emails.' })}
          <div className="space-y-1.5">
            <Label>Approved permit vendor</Label>
            <Input value="Synchron Permits (our trusted partner)" disabled />
          </div>
          {/* The "Managers see all company trips" switch was removed on
              2026-09-11. Requirement: "Brokers, drivers, and dispatchers
              should only see trips linked to their email or where they are
              assigned" — so company-wide visibility no longer exists, and a
              switch that does nothing must not be shown. The column stays in
              the database (and in the saved profile) untouched. */}
          {canEdit && (
            <div className="sm:col-span-2">
              <Button onClick={saveProfile} disabled={busy} className="bg-[#0f1b2d] font-bold hover:bg-[#1c2f4a]">
                {busy ? 'Saving…' : 'Save company details'}
              </Button>
            </div>
          )}
        </CardContent>
      </Card>

      {company.company_type === 'broker' && (
        <Card>
          <CardHeader>
            <CardTitle className="text-base">Broker intake page</CardTitle>
            <CardDescription>
              The public link carriers use to submit a load. Renaming keeps the old link working.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            {brokerPage ? (
              <>
                <div className="flex flex-wrap items-end gap-2">
                  <div className="min-w-56 flex-1 space-y-1.5">
                    <Label>Intake page URL</Label>
                    <div className="flex items-center gap-1">
                      <span className="text-sm text-neutral-500">/intake/</span>
                      <Input value={slug} onChange={(e) => setSlug(e.target.value)} disabled={!canEdit || busy} />
                    </div>
                  </div>
                  {canEdit && (
                    <Button variant="outline" onClick={saveSlug} disabled={busy || slug === brokerPage.slug}>
                      Rename
                    </Button>
                  )}
                  <Link
                    href={`/intake/${brokerPage.slug}`}
                    target="_blank"
                    className="rounded-lg bg-[#0f1b2d] px-3 py-2 text-xs font-bold text-white hover:bg-[#1c2f4a]"
                  >
                    View public page →
                  </Link>
                </div>
                <div className="grid gap-4 sm:grid-cols-2">
                  <div className="space-y-1.5">
                    <Label>Default permit workflow</Label>
                    <select
                      value={defaults.policy}
                      disabled={!canEdit || busy}
                      onChange={(e) => setDefaults((d) => ({ ...d, policy: e.target.value as typeof d.policy }))}
                      className="w-full rounded-lg border px-3 py-2 text-sm"
                    >
                      <option value="ask">Ask per trip</option>
                      <option value="upload_allowed">Carrier will upload permits</option>
                      <option value="synchron_required">Request permits from Synchron Permits</option>
                    </select>
                  </div>
                  <div className="space-y-1.5">
                    <Label>Default payment responsibility</Label>
                    <select
                      value={defaults.payment}
                      disabled={!canEdit || busy}
                      onChange={(e) => setDefaults((d) => ({ ...d, payment: e.target.value as typeof d.payment }))}
                      className="w-full rounded-lg border px-3 py-2 text-sm"
                    >
                      <option value="ask">Ask per trip</option>
                      <option value="broker">Broker pays</option>
                      <option value="carrier">Carrier pays</option>
                    </select>
                  </div>
                  {canEdit && (
                    <div className="sm:col-span-2">
                      <Button variant="outline" onClick={saveDefaults} disabled={busy}>
                        Save defaults
                      </Button>
                    </div>
                  )}
                </div>
              </>
            ) : (
              <p className="text-sm text-neutral-500">No intake page is linked to this company yet.</p>
            )}
          </CardContent>
        </Card>
      )}

      <div className="grid gap-3 sm:grid-cols-3">
        <button type="button" onClick={onGoAccess} className="rounded-xl border bg-white p-4 text-left text-sm hover:border-neutral-400">
          <span className="block font-semibold">Team members</span>
          <span className="block text-xs text-neutral-500">
            {pendingCount > 0 ? `${pendingCount} pending request${pendingCount === 1 ? '' : 's'}` : 'Company Access tab'}
          </span>
        </button>
        <Link href="/billing" className="rounded-xl border bg-white p-4 text-sm hover:border-neutral-400">
          <span className="block font-semibold">Billing settings</span>
          <span className="block text-xs text-neutral-500">Billing &amp; Wallet</span>
        </Link>
        <div className="rounded-xl border bg-white p-4 text-sm">
          <span className="block font-semibold">Verification</span>
          <span className="block text-xs text-neutral-500">
            {VERIFICATION_LABELS[company.verification_status]} · level {company.verification_level}
          </span>
        </div>
      </div>
    </div>
  )
}

/* ---------------- Company Access (§28) ---------------- */

function AccessTab({ company, canEdit, members }: { company: Company; canEdit: boolean; members: MemberView[] }) {
  const router = useRouter()
  const companyCall = useCompanyCall()
  const [busy, setBusy] = useState(false)
  const [invite, setInvite] = useState({ email: '', role: 'broker_agent' as CompanyRole })
  const [infoFor, setInfoFor] = useState<string | null>(null)
  const [infoText, setInfoText] = useState('')

  async function act(body: Record<string, unknown>, done: string) {
    setBusy(true)
    try {
      const json = await companyCall(body)
      if (json) {
        toast.success(done)
        router.refresh()
      }
      return json
    } finally {
      setBusy(false)
    }
  }

  const approved = members.filter((m) => m.membership.status === 'approved')
  const pending = members.filter((m) => m.membership.status === 'pending')
  const rejected = members.filter((m) => m.membership.status === 'rejected' || m.membership.status === 'revoked')

  return (
    <div className="mt-4 space-y-5">
      {canEdit && (
        <Card>
          <CardHeader>
            <CardTitle className="text-base">Invite user</CardTitle>
            <CardDescription>
              Give a HeavyHaul Agent account access under {company.display_name}. Approved by you, as
              Company Admin.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <form
              onSubmit={async (e) => {
                e.preventDefault()
                const json = await act({ op: 'invite', ...invite }, 'User added to the company')
                if (json) setInvite({ email: '', role: 'broker_agent' })
              }}
              className="flex flex-wrap items-end gap-3"
            >
              <div className="min-w-56 flex-1 space-y-1.5">
                <Label>Email</Label>
                <Input
                  type="email"
                  required
                  value={invite.email}
                  onChange={(e) => setInvite((i) => ({ ...i, email: e.target.value }))}
                />
              </div>
              <div className="space-y-1.5">
                <Label>Role</Label>
                <RoleSelect value={invite.role} type={company.company_type} onChange={(r) => setInvite((i) => ({ ...i, role: r }))} />
              </div>
              <Button type="submit" disabled={busy} className="bg-[#0f1b2d] font-bold hover:bg-[#1c2f4a]">
                Invite
              </Button>
            </form>
          </CardContent>
        </Card>
      )}

      <Section title={`Pending requests (${pending.length})`}>
        {pending.length === 0 && <Empty>No pending requests.</Empty>}
        {pending.map((m) => (
          <div key={m.membership.id} className="rounded-xl border bg-white p-4">
            <div className="flex flex-wrap items-start justify-between gap-3">
              <div className="text-sm">
                <p className="font-bold">{m.name}</p>
                <p className="text-neutral-600">
                  {m.email}
                  {m.phone ? ` · ${m.phone}` : ''}
                </p>
                <p className="mt-1 text-xs text-neutral-500">
                  Requested {companyRoleLabel(m.claim?.requested_role ?? m.membership.role, company.company_type)} ·{' '}
                  {formatFullDate(m.claim?.created_at ?? m.membership.created_at)}
                  {m.claim?.mc_number ? ` · MC ${m.claim.mc_number}` : ''}
                </p>
                {m.claim?.info_request && (
                  <p className="mt-1 text-xs text-amber-700">More info requested: {m.claim.info_request}</p>
                )}
              </div>
              {canEdit && m.claim && (
                <div className="flex flex-wrap gap-2">
                  <Button
                    size="sm"
                    onClick={() => act({ op: 'decide', claim_id: m.claim!.id, decision: 'approve' }, 'Request approved')}
                    disabled={busy}
                    className="bg-green-700 hover:bg-green-800"
                  >
                    Approve
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => act({ op: 'decide', claim_id: m.claim!.id, decision: 'deny' }, 'Request denied')}
                    disabled={busy}
                  >
                    Deny
                  </Button>
                  <Button size="sm" variant="ghost" onClick={() => setInfoFor(infoFor === m.claim!.id ? null : m.claim!.id)} disabled={busy}>
                    Request more info
                  </Button>
                </div>
              )}
            </div>
            {canEdit && infoFor === m.claim?.id && (
              <form
                onSubmit={async (e) => {
                  e.preventDefault()
                  const json = await act(
                    { op: 'decide', claim_id: m.claim!.id, decision: 'request_info', note: infoText },
                    'Sent — the user sees your question in their settings',
                  )
                  if (json) {
                    setInfoFor(null)
                    setInfoText('')
                  }
                }}
                className="mt-3 flex flex-wrap gap-2"
              >
                <Input
                  value={infoText}
                  onChange={(e) => setInfoText(e.target.value)}
                  placeholder="What do you need from this person?"
                  required
                  className="min-w-56 flex-1"
                />
                <Button size="sm" type="submit" disabled={busy}>
                  Send
                </Button>
              </form>
            )}
          </div>
        ))}
      </Section>

      <Section title={`Approved users (${approved.length})`}>
        {approved.length === 0 && <Empty>No approved users yet.</Empty>}
        {approved.map((m) => (
          <div key={m.membership.id} className="flex flex-wrap items-center justify-between gap-3 rounded-xl border bg-white p-4 text-sm">
            <div>
              <p className="font-bold">
                {m.name}{' '}
                <span className="ml-1 rounded-full bg-green-50 px-2 py-0.5 text-[11px] font-semibold text-green-700">
                  Approved company agent
                </span>
              </p>
              <p className="text-neutral-600">{m.email}</p>
              <p className="mt-0.5 text-xs text-neutral-500">
                {companyRoleLabel(m.membership.role, company.company_type)} · approved{' '}
                {m.membership.approved_at ? formatFullDate(m.membership.approved_at) : '—'}
                {m.membership.approved_by ? ` by ${m.membership.approved_by}` : ''} · Last login —
              </p>
            </div>
            {canEdit && (
              <div className="flex flex-wrap items-center gap-2">
                <RoleSelect
                  value={m.membership.role}
                  type={company.company_type}
                  onChange={(role) => act({ op: 'role', membership_id: m.membership.id, role }, 'Role updated')}
                  disabled={busy}
                />
                <Button
                  size="sm"
                  variant="outline"
                  className="text-red-700"
                  disabled={busy}
                  onClick={() => {
                    if (confirm(`Remove ${m.name}'s access to ${company.display_name}?`)) {
                      act({ op: 'revoke', membership_id: m.membership.id }, 'Access removed')
                    }
                  }}
                >
                  Remove access
                </Button>
              </div>
            )}
          </div>
        ))}
      </Section>

      <Section title={`Rejected / removed (${rejected.length})`}>
        {rejected.length === 0 && <Empty>Nothing here.</Empty>}
        {rejected.map((m) => (
          <div key={m.membership.id} className="rounded-xl border bg-neutral-50 p-4 text-sm text-neutral-600">
            <p className="font-semibold text-neutral-800">{m.name}</p>
            <p>{m.email}</p>
            <p className="mt-0.5 text-xs">
              {m.membership.status === 'revoked' ? 'Access removed' : 'Not approved'}
              {m.membership.revoked_at ? ` · ${formatFullDate(m.membership.revoked_at)}` : ''}
              {m.membership.revoked_by ? ` by ${m.membership.revoked_by}` : ''}
            </p>
          </div>
        ))}
      </Section>
    </div>
  )
}

function RoleSelect({
  value,
  type,
  onChange,
  disabled,
}: {
  value: CompanyRole
  type: Company['company_type']
  onChange: (r: CompanyRole) => void
  disabled?: boolean
}) {
  return (
    <select
      value={value}
      disabled={disabled}
      onChange={(e) => onChange(e.target.value as CompanyRole)}
      className="rounded-lg border px-2 py-1.5 text-sm"
    >
      {COMPANY_ROLES.map((r) => (
        <option key={r} value={r}>
          {companyRoleLabel(r, type)}
        </option>
      ))}
    </select>
  )
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <section>
      <h3 className="mb-2 text-xs font-bold uppercase tracking-wide text-neutral-500">{title}</h3>
      <div className="space-y-2">{children}</div>
    </section>
  )
}

function Empty({ children }: { children: React.ReactNode }) {
  return <p className="rounded-xl border border-dashed p-4 text-center text-sm text-neutral-500">{children}</p>
}

/* ---------------- Audit log (§21) ---------------- */

function AuditTab({ audit }: { audit: CompanyAuditEvent[] }) {
  return (
    <div className="mt-4 overflow-x-auto rounded-2xl border bg-white">
      <table className="w-full min-w-[640px] text-sm">
        <thead>
          <tr className="border-b text-left text-[11px] font-bold uppercase tracking-wide text-neutral-500">
            <th className="px-4 py-3">When</th>
            <th className="px-4 py-3">Who</th>
            <th className="px-4 py-3">Event</th>
            <th className="px-4 py-3">Change</th>
          </tr>
        </thead>
        <tbody>
          {audit.map((e) => (
            <tr key={e.id} className="border-b last:border-0 align-top">
              <td className="whitespace-nowrap px-4 py-2.5 text-xs text-neutral-500">{formatDateTime(e.created_at)}</td>
              <td className="px-4 py-2.5">{e.actor_label}</td>
              <td className="px-4 py-2.5 font-mono text-xs">{e.event_type}</td>
              <td className="px-4 py-2.5 font-mono text-[11px] text-neutral-600">
                {e.old_value ? <span className="line-through">{JSON.stringify(e.old_value)} </span> : null}
                {e.new_value ? JSON.stringify(e.new_value) : null}
              </td>
            </tr>
          ))}
          {audit.length === 0 && (
            <tr>
              <td colSpan={4} className="px-4 py-8 text-center text-neutral-500">
                No events yet.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  )
}
