'use client'

/**
 * Form Schema pane — inline inspector opened from the Forms list "Schema"
 * action (design's 390px schema panel; previously the `FormSchemaDrawer`
 * overlay). Four tabs: Fields (versioned schema editor), Embed (public
 * snippets + domain restrictions), Notifications (email settings),
 * Integrations (CRM webhooks / Zapier).
 *
 * Saving the Fields tab creates a new schema version server-side; existing
 * submissions keep referencing the version they were captured against, so
 * historical entries never break when the schema changes.
 */
import * as Tabs from '@radix-ui/react-tabs'
import { useEffect, useState } from 'react'
import { toast } from 'sonner'
import { fetchFormSchema, saveFormSchema, type FormField } from '../../lib/forms-service.js'
import type { FormListItem } from '../../lib/forms-service.js'
import { emitFormsChanged } from '../../lib/forms-events.js'
import { ConfirmDialog } from '../ui/ConfirmDialog.js'
import { InspectorPaneBody, InspectorPaneFooter, InspectorPaneHeader } from '../ui/InspectorPane.js'
import { FieldsPanel } from './FieldsPanel.js'
import { EmbedPanel } from './EmbedPanel.js'
import { NotificationsPanel } from './NotificationsPanel.js'
import { WebhooksPanel } from './WebhooksPanel.js'
import { FormsErrorState, FormsLoading, btnPrimary } from './primitives.js'

const TABS = [
  { id: 'fields', label: 'Fields' },
  { id: 'embed', label: 'Embed' },
  { id: 'notifications', label: 'Notifications' },
  { id: 'integrations', label: 'Integrations' },
] as const

export function FormSchemaPane({
  form,
  onClose,
  onSaved,
}: {
  form: FormListItem
  onClose: () => void
  /** Called after a schema/settings change so the list can refetch. */
  onSaved?: () => void
}) {
  const [tab, setTab] = useState<string>('fields')
  const [fields, setFields] = useState<FormField[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [dirty, setDirty] = useState(false)
  const [saving, setSaving] = useState(false)
  const [confirmDiscard, setConfirmDiscard] = useState(false)

  const formId = form.id
  const hasSubmissions = (form.totalEntries ?? 0) > 0

  useEffect(() => {
    setTab('fields')
    setDirty(false)
    setLoading(true)
    setError(null)
    let active = true
    fetchFormSchema(formId)
      .then((schema) => {
        if (active) setFields(schema.fields)
      })
      .catch((e: unknown) => {
        if (active) setError(e instanceof Error ? e.message : 'Failed to load schema')
      })
      .finally(() => {
        if (active) setLoading(false)
      })
    return () => {
      active = false
    }
  }, [formId])

  function handleFieldsChange(next: FormField[]) {
    setFields(next)
    setDirty(true)
  }

  async function handleSave() {
    setSaving(true)
    const res = await saveFormSchema(
      formId,
      fields.map((f, i) => ({ ...f, sortOrder: i })),
    )
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
      return
    }
    setDirty(false)
    toast.success('Schema saved.')
    emitFormsChanged()
    onSaved?.()
  }

  function requestClose() {
    if (dirty) {
      setConfirmDiscard(true)
      return
    }
    onClose()
  }

  return (
    <>
      <InspectorPaneHeader onClose={requestClose} closeLabel="Close schema panel">
        <div className="truncate text-[13.5px] font-semibold text-[var(--txt)]">{form.name}</div>
        <div className="mt-0.5 truncate font-mono text-[11.5px] text-[var(--muted)]">
          /{form.slug}
        </div>
      </InspectorPaneHeader>

      <Tabs.Root value={tab} onValueChange={setTab} className="flex min-h-0 flex-1 flex-col">
        <Tabs.List
          className="flex shrink-0 gap-0.5 overflow-x-auto border-b border-[var(--bdr)] px-2"
          aria-label="Form schema sections"
        >
          {TABS.map((t) => (
            <Tabs.Trigger
              key={t.id}
              value={t.id}
              className="-mb-px border-b-2 border-transparent px-2.5 py-2 text-[12.5px] font-medium whitespace-nowrap text-[var(--sub)] transition-colors hover:text-[var(--txt)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none data-[state=active]:border-[var(--acc)] data-[state=active]:text-[var(--txt)]"
            >
              {t.label}
            </Tabs.Trigger>
          ))}
        </Tabs.List>

        <InspectorPaneBody>
          <div className="px-4 py-3.5">
            <Tabs.Content value="fields" tabIndex={-1}>
              {loading ? (
                <FormsLoading label="Loading schema…" />
              ) : error ? (
                <FormsErrorState message={error} onRetry={() => setTab('fields')} />
              ) : (
                <FieldsPanel
                  fields={fields}
                  onChange={handleFieldsChange}
                  hasSubmissions={hasSubmissions}
                />
              )}
            </Tabs.Content>

            <Tabs.Content value="embed" tabIndex={-1}>
              <EmbedPanel formId={formId} slug={form.slug} status={form.status} />
            </Tabs.Content>

            <Tabs.Content value="notifications" tabIndex={-1}>
              <NotificationsPanel formId={formId} onChanged={onSaved} />
            </Tabs.Content>

            <Tabs.Content value="integrations" tabIndex={-1}>
              <WebhooksPanel formId={formId} formSlug={form.slug} />
            </Tabs.Content>
          </div>
        </InspectorPaneBody>

        {tab === 'fields' && (
          <InspectorPaneFooter>
            <button
              type="button"
              className={`${btnPrimary} w-full`}
              onClick={() => void handleSave()}
              disabled={saving || loading}
            >
              {saving ? 'Saving…' : 'Save Schema'}
            </button>
          </InspectorPaneFooter>
        )}
      </Tabs.Root>

      <ConfirmDialog
        open={confirmDiscard}
        onClose={() => setConfirmDiscard(false)}
        onConfirm={() => {
          setDirty(false)
          setConfirmDiscard(false)
          onClose()
        }}
        title="Discard unsaved changes?"
        description="You have unsaved schema changes. Closing now will discard them."
        confirmLabel="Discard"
        cancelLabel="Keep editing"
        destructive
      />
    </>
  )
}
