'use client'

/**
 * Forms list — manage forms and view high-level submission status. Matches the
 * Forms list screenshot: summary chips, search + status filter pills, and a
 * compact table (Form / Fields / Status / Entries / Last Entry / Notify /
 * Schema). All data flows through `lib/forms-service.ts`; the Schema action
 * opens the right-side `FormSchemaDrawer`.
 */
import { ChevronRight, ClipboardList, Plus, Search, Settings2 } from 'lucide-react'
import * as Switch from '@radix-ui/react-switch'
import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react'
import { toast } from 'sonner'
import { sortByRelevance } from '../lib/search.js'
import {
  fetchForms,
  fetchFormStats,
  setNotifyEnabled,
  type FormListItem,
  type FormStats,
  type FormStatus,
} from '../lib/forms-service.js'
import { emitFormsChanged, onFormsChanged } from '../lib/forms-events.js'
import { FormSchemaDrawer } from '../components/forms/FormSchemaDrawer.js'
import {
  FieldTypeBadge,
  FormStatusBadge,
  FormsEmptyState,
  FormsErrorState,
  FormsLoading,
  FormsPagination,
  SummaryChip,
  UnreadBadge,
  btnPrimary,
} from '../components/forms/primitives.js'

const PAGE_SIZE = 10

export interface FormsProps {
  onNavigate?: (path: string) => void
}

type StatusFilter = 'all' | FormStatus

const FILTERS: { id: StatusFilter; label: string }[] = [
  { id: 'all', label: 'All' },
  { id: 'active', label: 'Active' },
  { id: 'draft', label: 'Draft' },
  { id: 'archived', label: 'Archived' },
]

function formatRelative(iso: string | null | undefined): string {
  if (!iso) return '—'
  const then = new Date(iso).getTime()
  if (Number.isNaN(then)) return '—'
  const diff = Date.now() - then
  const mins = Math.round(diff / 60000)
  if (mins < 1) return 'just now'
  if (mins < 60) return `${mins} min ago`
  const hrs = Math.round(mins / 60)
  if (hrs < 24) return `${hrs} hour${hrs === 1 ? '' : 's'} ago`
  const days = Math.round(hrs / 24)
  if (days < 7) return `${days} day${days === 1 ? '' : 's'} ago`
  return new Date(iso).toLocaleDateString(undefined, {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  })
}

export function Forms({ onNavigate }: FormsProps) {
  const [forms, setForms] = useState<FormListItem[]>([])
  const [stats, setStats] = useState<FormStats | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [search, setSearch] = useState('')
  const [filter, setFilter] = useState<StatusFilter>('all')
  const [page, setPage] = useState(1)
  const [schemaForm, setSchemaForm] = useState<FormListItem | null>(null)
  const [schemaOpen, setSchemaOpen] = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const [formsData, statsData] = await Promise.all([fetchForms(), fetchFormStats()])
      setForms(formsData)
      setStats(statsData)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Failed to load forms')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    void load()
  }, [load])

  // Refresh when another surface signals a forms/submission change.
  useEffect(() => onFormsChanged(() => void load()), [load])

  const filtered = useMemo(() => {
    let results = forms
    if (filter !== 'all') results = results.filter((f) => f.status === filter)
    const q = search.trim().toLowerCase()
    if (q) {
      results = results.filter(
        (f) =>
          f.name.toLowerCase().includes(q) ||
          f.slug.toLowerCase().includes(q) ||
          (f.description ?? '').toLowerCase().includes(q) ||
          f.fields.some(
            (field) =>
              field.label.toLowerCase().includes(q) || field.type.toLowerCase().includes(q),
          ),
      )
      results = sortByRelevance(results, search, (f) => [
        f.name,
        f.slug,
        f.description ?? '',
        ...f.fields.map((field) => field.label),
      ])
    }
    return results
  }, [forms, filter, search])

  const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE))

  // Keep the page in range when the filtered set shrinks (filters, refresh).
  useEffect(() => {
    if (page > totalPages) setPage(totalPages)
  }, [page, totalPages])

  const paged = useMemo(
    () => filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE),
    [filtered, page],
  )

  const openSchema = useCallback((form: FormListItem) => {
    setSchemaForm(form)
    setSchemaOpen(true)
  }, [])

  const handleNotifyToggle = useCallback(async (form: FormListItem, next: boolean) => {
    // Optimistic update; roll back on error.
    setForms((cur) => cur.map((f) => (f.id === form.id ? { ...f, notifyEnabled: next } : f)))
    const res = await setNotifyEnabled(form.id, next)
    if (res.error) {
      setForms((cur) => cur.map((f) => (f.id === form.id ? { ...f, notifyEnabled: !next } : f)))
      toast.error(res.error)
      return
    }
    emitFormsChanged()
  }, [])

  return (
    <div className="space-y-5 p-6">
      <header className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 className="text-foreground text-2xl font-medium">Forms</h1>
          <p className="text-muted-foreground mt-1 text-sm">
            Manage forms and view incoming submissions
          </p>
        </div>
        <button className={btnPrimary} onClick={() => onNavigate?.('/forms/new')}>
          <Plus className="h-4 w-4" aria-hidden />
          New Form
        </button>
      </header>

      {stats && (
        <div className="flex flex-wrap gap-2">
          <SummaryChip value={stats.totalForms} label={stats.totalForms === 1 ? 'form' : 'forms'} />
          <SummaryChip value={stats.activeForms} label="active" tone="success" />
          <SummaryChip value={stats.totalEntries} label="total entries" />
          <SummaryChip
            value={stats.unreadEntries}
            label="unread"
            tone={stats.unreadEntries > 0 ? 'destructive' : 'neutral'}
          />
        </div>
      )}

      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="relative w-full sm:max-w-xs">
          <Search
            className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2"
            aria-hidden
          />
          <input
            type="search"
            placeholder="Search forms…"
            value={search}
            onChange={(e) => {
              setSearch(e.target.value)
              setPage(1)
            }}
            aria-label="Search forms"
            className="border-border bg-input-background text-foreground focus-visible:ring-ring w-full rounded-lg border py-2 pr-3 pl-9 text-sm focus-visible:ring-2 focus-visible:outline-none"
          />
        </div>
        <div className="flex gap-1" role="group" aria-label="Filter by status">
          {FILTERS.map((f) => (
            <button
              key={f.id}
              type="button"
              onClick={() => {
                setFilter(f.id)
                setPage(1)
              }}
              aria-pressed={filter === f.id}
              className={`rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${
                filter === f.id
                  ? 'bg-primary text-primary-foreground'
                  : 'text-muted-foreground hover:bg-accent hover:text-foreground'
              }`}
            >
              {f.label}
            </button>
          ))}
        </div>
      </div>

      {error ? (
        <FormsErrorState message={error} onRetry={load} />
      ) : loading ? (
        <FormsLoading label="Loading forms…" />
      ) : forms.length === 0 ? (
        <FormsEmptyState
          icon={<ClipboardList className="h-6 w-6" aria-hidden />}
          title="No forms yet"
          description="Create your first form to start collecting submissions."
          action={
            <button className={btnPrimary} onClick={() => onNavigate?.('/forms/new')}>
              <Plus className="h-4 w-4" aria-hidden />
              Create New Form
            </button>
          }
        />
      ) : filtered.length === 0 ? (
        <FormsEmptyState
          title="No forms match your filters"
          description="Try a different search term or status filter."
          action={
            <button
              type="button"
              onClick={() => {
                setSearch('')
                setFilter('all')
                setPage(1)
              }}
              className="text-primary text-sm font-medium hover:underline"
            >
              Clear filters
            </button>
          }
        />
      ) : (
        <FormsTable
          forms={paged}
          onOpenForm={(id) => onNavigate?.(`/forms/${id}/edit`)}
          onOpenEntries={(id) => onNavigate?.(`/forms/${id}/submissions`)}
          onOpenSchema={openSchema}
          onNotifyToggle={handleNotifyToggle}
          footer={
            <FormsPagination
              page={page}
              pageSize={PAGE_SIZE}
              total={filtered.length}
              onPageChange={setPage}
              noun="form"
              label="Forms pagination"
            />
          }
        />
      )}

      <FormSchemaDrawer
        form={schemaForm}
        open={schemaOpen}
        onOpenChange={setSchemaOpen}
        onSaved={load}
      />
    </div>
  )
}

function FormsTable({
  forms,
  onOpenForm,
  onOpenEntries,
  onOpenSchema,
  onNotifyToggle,
  footer,
}: {
  forms: FormListItem[]
  onOpenForm: (id: string) => void
  onOpenEntries: (id: string) => void
  onOpenSchema: (form: FormListItem) => void
  onNotifyToggle: (form: FormListItem, next: boolean) => void
  footer?: ReactNode
}) {
  return (
    <div className="border-border bg-card rounded-lg border">
      <div className="overflow-x-auto">
        <table className="w-full min-w-[760px] text-sm" aria-label="Forms">
          <thead>
            <tr className="border-border text-muted-foreground border-b text-left text-xs">
              <th scope="col" className="px-4 py-2.5 font-medium">
                Form
              </th>
              <th scope="col" className="px-4 py-2.5 font-medium">
                Fields
              </th>
              <th scope="col" className="px-4 py-2.5 font-medium">
                Status
              </th>
              <th scope="col" className="px-4 py-2.5 font-medium">
                Entries
              </th>
              <th scope="col" className="px-4 py-2.5 font-medium">
                Last Entry
              </th>
              <th scope="col" className="px-4 py-2.5 text-center font-medium">
                Notify
              </th>
              <th scope="col" className="px-4 py-2.5 text-right font-medium">
                <span className="sr-only">Schema</span>
              </th>
            </tr>
          </thead>
          <tbody>
            {forms.map((form) => {
              const fieldCount = form.fieldCount ?? form.fields.length
              const unread = form.unreadEntries ?? 0
              const muted = form.status === 'archived'
              return (
                <tr
                  key={form.id}
                  className={`border-border hover:bg-accent/40 border-b transition-colors last:border-b-0 ${muted ? 'opacity-60' : ''}`}
                >
                  <td className="px-4 py-3">
                    <button
                      type="button"
                      onClick={() => onOpenForm(form.id)}
                      className="block max-w-xs text-left"
                    >
                      <span className="text-foreground block truncate font-medium hover:underline">
                        {form.name}
                      </span>
                      <span className="text-muted-foreground block truncate text-xs">
                        /{form.slug}
                        {form.description ? ` · ${form.description}` : ''}
                      </span>
                    </button>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex flex-wrap items-center gap-1">
                      {form.fields.slice(0, 4).map((field) => (
                        <FieldTypeBadge key={field.id} type={field.type} />
                      ))}
                      <span className="text-muted-foreground text-xs">{fieldCount} fields</span>
                    </div>
                  </td>
                  <td className="px-4 py-3">
                    <FormStatusBadge status={form.status} />
                  </td>
                  <td className="px-4 py-3">
                    <button
                      type="button"
                      onClick={() => onOpenEntries(form.id)}
                      className="text-foreground hover:text-primary focus-visible:ring-ring inline-flex items-center gap-1.5 rounded font-medium tabular-nums focus-visible:ring-2 focus-visible:outline-none"
                      aria-label={`View ${form.totalEntries ?? 0} entries for ${form.name}`}
                    >
                      {form.totalEntries ?? 0}
                      <UnreadBadge count={unread} />
                      <ChevronRight className="text-muted-foreground h-3.5 w-3.5" aria-hidden />
                    </button>
                  </td>
                  <td className="text-muted-foreground px-4 py-3 whitespace-nowrap">
                    {formatRelative(form.lastEntryAt)}
                  </td>
                  <td className="px-4 py-3 text-center">
                    <Switch.Root
                      checked={form.notifyEnabled ?? false}
                      onCheckedChange={(v) => onNotifyToggle(form, v)}
                      aria-label={`Notifications for ${form.name}`}
                      className="bg-destructive data-[state=checked]:bg-success focus-visible:ring-ring relative inline-flex h-[18px] w-8 shrink-0 rounded-full transition-colors focus-visible:ring-2 focus-visible:outline-none"
                    >
                      <Switch.Thumb className="bg-background block h-3.5 w-3.5 translate-x-0.5 rounded-full shadow-sm transition-transform data-[state=checked]:translate-x-[14px]" />
                    </Switch.Root>
                  </td>
                  <td className="px-4 py-3 text-right">
                    <button
                      type="button"
                      onClick={() => onOpenSchema(form)}
                      className="border-border text-foreground hover:bg-accent focus-visible:ring-ring inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none"
                    >
                      <Settings2 className="h-3.5 w-3.5" aria-hidden />
                      Schema
                    </button>
                  </td>
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>
      {footer}
    </div>
  )
}
