// Metadata Admin page.
//
// Tabbed admin page for browsing and managing all metadata
// definitions: entities, custom fields, permissions, menus,
// forms, and list views. Read-only tabs display DataTables;
// the custom-fields tab supports inline create/edit/delete for
// source='user' rows; the forms and list-views tabs navigate
// to dedicated designer pages.

import { useEffect, useState, type FormEvent, type ReactNode } from 'react'
import { useNavigate } from 'react-router-dom'
import { metadata } from '@/api/client'
import type {
  CustomFieldDef,
  FormDefinition,
  ListViewDefinition,
  MetadataEntity,
  MetadataPermission,
} from '@/types/api'
import { PageHeader } from '@/components/PageHeader'
import { Loading } from '@/components/Loading'
import { ErrorBox } from '@/components/ErrorBox'
import { DataTable, type Column } from '@/components/DataTable'
import { useT } from '@/i18n/LocaleContext'

// ─── Menu row shape (no formal type in api.ts) ─────────────────────

interface MenuRow {
  path: string
  label: string
  icon?: string
  section?: string
  order?: number
  source?: string
}

// ─── Source badge ───────────────────────────────────────────────────

function SourceBadge({ source }: { source: string }) {
  const cls =
    source === 'core'
      ? 'bg-blue-100 text-blue-700'
      : source === 'user'
        ? 'bg-emerald-100 text-emerald-700'
        : 'bg-amber-100 text-amber-700' // plugin:*
  return (
    <span
      className={`inline-block rounded px-1.5 py-0.5 text-xs font-medium ${cls}`}
    >
      {source}
    </span>
  )
}

// ─── Tab definitions ────────────────────────────────────────────────

type TabId =
  | 'entities'
  | 'customFields'
  | 'permissions'
  | 'menus'
  | 'forms'
  | 'listViews'

const TYPE_KINDS = [
  'string',
  'integer',
  'decimal',
  'boolean',
  'date',
  'date_time',
  'enum',
  'uuid',
  'money',
  'quantity',
] as const

// ─── Component ──────────────────────────────────────────────────────

export function MetadataAdminPage() {
  const t = useT()
  const navigate = useNavigate()
  const [activeTab, setActiveTab] = useState<TabId>('entities')

  // Shared loading / error state
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<Error | null>(null)

  // Tab data
  const [entities, setEntities] = useState<MetadataEntity[]>([])
  const [customFields, setCustomFields] = useState<CustomFieldDef[]>([])
  const [permissions, setPermissions] = useState<MetadataPermission[]>([])
  const [menus, setMenus] = useState<MenuRow[]>([])
  const [forms, setForms] = useState<FormDefinition[]>([])
  const [listViews, setListViews] = useState<ListViewDefinition[]>([])

  // Custom-field inline form state
  const [cfFormOpen, setCfFormOpen] = useState(false)
  const [cfEditingKey, setCfEditingKey] = useState<string | null>(null) // null = create
  const [cfTargetEntity, setCfTargetEntity] = useState('')
  const [cfFieldKey, setCfFieldKey] = useState('')
  const [cfTypeKind, setCfTypeKind] = useState<string>('string')
  const [cfRequired, setCfRequired] = useState(false)
  const [cfPii, setCfPii] = useState(false)
  const [cfLabelEn, setCfLabelEn] = useState('')
  const [cfLabelZh, setCfLabelZh] = useState('')
  const [cfSaving, setCfSaving] = useState(false)

  // ── Loaders ───────────────────────────────────────────────────────

  const loadTab = (tab: TabId) => {
    setLoading(true)
    setError(null)
    const promise: Promise<void> = (() => {
      switch (tab) {
        case 'entities':
          return metadata.entities().then(setEntities).then(() => {})
        case 'customFields':
          return metadata.customFields().then(setCustomFields).then(() => {})
        case 'permissions':
          return metadata.permissions().then(setPermissions).then(() => {})
        case 'menus':
          return metadata
            .menus()
            .then((rows: MenuRow[]) => setMenus(rows))
            .then(() => {})
        case 'forms':
          return metadata.listForms().then(setForms).then(() => {})
        case 'listViews':
          return metadata.listListViews().then(setListViews).then(() => {})
      }
    })()
    promise
      .catch((e: unknown) =>
        setError(e instanceof Error ? e : new Error(String(e))),
      )
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    loadTab(activeTab)
  }, [activeTab]) // eslint-disable-line react-hooks/exhaustive-deps

  // ── Custom-field form helpers ─────────────────────────────────────

  const resetCfForm = () => {
    setCfFormOpen(false)
    setCfEditingKey(null)
    setCfTargetEntity('')
    setCfFieldKey('')
    setCfTypeKind('string')
    setCfRequired(false)
    setCfPii(false)
    setCfLabelEn('')
    setCfLabelZh('')
  }

  const openCfCreate = () => {
    resetCfForm()
    setCfFormOpen(true)
  }

  const openCfEdit = (cf: CustomFieldDef) => {
    setCfEditingKey(cf.key)
    setCfTargetEntity(cf.targetEntity)
    setCfFieldKey(cf.key)
    setCfTypeKind(cf.type.kind)
    setCfRequired(cf.required)
    setCfPii(cf.pii)
    setCfLabelEn(cf.labelTranslations['en'] ?? '')
    setCfLabelZh(cf.labelTranslations['zh-CN'] ?? '')
    setCfFormOpen(true)
  }

  const onCfSubmit = async (e: FormEvent) => {
    e.preventDefault()
    setCfSaving(true)
    setError(null)
    const body: Omit<CustomFieldDef, 'source'> = {
      key: cfFieldKey,
      targetEntity: cfTargetEntity,
      type: { kind: cfTypeKind },
      required: cfRequired,
      pii: cfPii,
      labelTranslations: {
        ...(cfLabelEn ? { en: cfLabelEn } : {}),
        ...(cfLabelZh ? { 'zh-CN': cfLabelZh } : {}),
      },
    }
    try {
      if (cfEditingKey) {
        await metadata.updateCustomField(cfEditingKey, body)
      } else {
        await metadata.createCustomField(body)
      }
      resetCfForm()
      loadTab('customFields')
    } catch (err: unknown) {
      setError(err instanceof Error ? err : new Error(String(err)))
    } finally {
      setCfSaving(false)
    }
  }

  const onCfDelete = async (key: string) => {
    if (!window.confirm(t('confirm.delete'))) return
    setError(null)
    try {
      await metadata.deleteCustomField(key)
      loadTab('customFields')
    } catch (err: unknown) {
      setError(err instanceof Error ? err : new Error(String(err)))
    }
  }

  // ── Form / ListView delete helpers ────────────────────────────────

  const onFormDelete = async (slug: string) => {
    if (!window.confirm(t('confirm.delete'))) return
    setError(null)
    try {
      await metadata.deleteForm(slug)
      loadTab('forms')
    } catch (err: unknown) {
      setError(err instanceof Error ? err : new Error(String(err)))
    }
  }

  const onListViewDelete = async (slug: string) => {
    if (!window.confirm(t('confirm.delete'))) return
    setError(null)
    try {
      await metadata.deleteListView(slug)
      loadTab('listViews')
    } catch (err: unknown) {
      setError(err instanceof Error ? err : new Error(String(err)))
    }
  }

  // ── Column definitions ────────────────────────────────────────────

  const entityCols: Column<MetadataEntity>[] = [
    { header: t('label.name'), key: 'name' },
    { header: 'PBC', key: 'pbc' },
    { header: 'Table', key: 'table' },
    { header: t('label.description'), key: 'description', render: (r) => r.description ?? '—' },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
  ]

  const customFieldCols: Column<CustomFieldDef>[] = [
    { header: t('label.fieldKey'), key: 'key', render: (r) => <span className="font-mono">{r.key}</span> },
    { header: t('label.targetEntity'), key: 'targetEntity' },
    { header: t('label.fieldType'), key: 'type', render: (r) => r.type.kind },
    { header: 'Required', key: 'required', render: (r) => (r.required ? 'Yes' : 'No') },
    { header: 'PII', key: 'pii', render: (r) => (r.pii ? 'Yes' : 'No') },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
    {
      header: '',
      key: '_actions',
      render: (r) =>
        r.source === 'user' ? (
          <span className="flex gap-2">
            <button
              className="text-xs text-blue-600 hover:underline"
              onClick={() => openCfEdit(r)}
            >
              Edit
            </button>
            <button
              className="text-xs text-rose-600 hover:underline"
              onClick={() => onCfDelete(r.key)}
            >
              {t('action.delete')}
            </button>
          </span>
        ) : null,
    },
  ]

  const permissionCols: Column<MetadataPermission>[] = [
    { header: 'Key', key: 'key', render: (r) => <span className="font-mono">{r.key}</span> },
    { header: t('label.description'), key: 'description' },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
  ]

  const menuCols: Column<MenuRow>[] = [
    { header: 'Path', key: 'path', render: (r) => <span className="font-mono">{r.path}</span> },
    { header: 'Label', key: 'label' },
    { header: 'Icon', key: 'icon', render: (r) => r.icon ?? '—' },
    { header: 'Section', key: 'section', render: (r) => r.section ?? '—' },
    { header: 'Order', key: 'order', render: (r) => r.order ?? '—' },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
  ]

  const formCols: Column<FormDefinition>[] = [
    {
      header: t('label.slug'),
      key: 'slug',
      render: (r) => (
        <button
          className="font-mono text-brand-600 hover:underline"
          onClick={() => navigate(`/admin/metadata/forms/${r.slug}/edit`)}
        >
          {r.slug}
        </button>
      ),
    },
    { header: t('label.entity'), key: 'entityName' },
    { header: 'Title', key: 'title' },
    { header: t('label.purpose'), key: 'purpose' },
    { header: 'Version', key: 'version' },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
    {
      header: '',
      key: '_actions',
      render: (r) =>
        r.source === 'user' ? (
          <button
            className="text-xs text-rose-600 hover:underline"
            onClick={() => onFormDelete(r.slug)}
          >
            {t('action.delete')}
          </button>
        ) : null,
    },
  ]

  const listViewCols: Column<ListViewDefinition>[] = [
    {
      header: t('label.slug'),
      key: 'slug',
      render: (r) => (
        <button
          className="font-mono text-brand-600 hover:underline"
          onClick={() =>
            navigate(`/admin/metadata/list-views/${r.slug}/edit`)
          }
        >
          {r.slug}
        </button>
      ),
    },
    { header: t('label.entity'), key: 'entityName' },
    { header: 'Title', key: 'title' },
    { header: t('label.pageSize'), key: 'pageSize' },
    { header: 'Version', key: 'version' },
    { header: t('label.source'), key: 'source', render: (r) => <SourceBadge source={r.source ?? 'core'} /> },
    {
      header: '',
      key: '_actions',
      render: (r) =>
        r.source === 'user' ? (
          <button
            className="text-xs text-rose-600 hover:underline"
            onClick={() => onListViewDelete(r.slug)}
          >
            {t('action.delete')}
          </button>
        ) : null,
    },
  ]

  // ── Tab bar ───────────────────────────────────────────────────────

  const tabs: { id: TabId; label: string }[] = [
    { id: 'entities', label: t('tab.entities') },
    { id: 'customFields', label: t('tab.customFields') },
    { id: 'permissions', label: t('tab.permissions') },
    { id: 'menus', label: t('tab.menus') },
    { id: 'forms', label: t('tab.forms') },
    { id: 'listViews', label: t('tab.listViews') },
  ]

  // ── Tab content renderer ──────────────────────────────────────────

  function renderTabContent(): ReactNode {
    if (loading) return <Loading />
    if (error) return <ErrorBox error={error} />

    switch (activeTab) {
      case 'entities':
        return (
          <DataTable
            rows={entities}
            columns={entityCols}
            rowKey={(r) => r.name}
          />
        )

      case 'customFields':
        return (
          <div>
            <div className="mb-3">
              <button className="btn-primary" onClick={openCfCreate}>
                {t('action.newCustomField')}
              </button>
            </div>
            {cfFormOpen && (
              <form
                onSubmit={onCfSubmit}
                className="card p-4 space-y-3 mt-3 mb-4 max-w-2xl"
              >
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="block text-xs font-medium text-slate-700">
                      {t('label.targetEntity')}
                    </label>
                    <input
                      type="text"
                      required
                      value={cfTargetEntity}
                      onChange={(e) => setCfTargetEntity(e.target.value)}
                      placeholder="Partner"
                      className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm"
                    />
                  </div>
                  <div>
                    <label className="block text-xs font-medium text-slate-700">
                      {t('label.fieldKey')}
                    </label>
                    <input
                      type="text"
                      required
                      value={cfFieldKey}
                      onChange={(e) => setCfFieldKey(e.target.value)}
                      disabled={cfEditingKey !== null}
                      placeholder="custom_my_field"
                      className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm font-mono disabled:opacity-50"
                    />
                  </div>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="block text-xs font-medium text-slate-700">
                      {t('label.fieldType')}
                    </label>
                    <select
                      value={cfTypeKind}
                      onChange={(e) => setCfTypeKind(e.target.value)}
                      className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm"
                    >
                      {TYPE_KINDS.map((k) => (
                        <option key={k} value={k}>
                          {k}
                        </option>
                      ))}
                    </select>
                  </div>
                  <div className="flex items-end gap-4 pb-1">
                    <label className="flex items-center gap-1.5 text-sm text-slate-700">
                      <input
                        type="checkbox"
                        checked={cfRequired}
                        onChange={(e) => setCfRequired(e.target.checked)}
                      />
                      Required
                    </label>
                    <label className="flex items-center gap-1.5 text-sm text-slate-700">
                      <input
                        type="checkbox"
                        checked={cfPii}
                        onChange={(e) => setCfPii(e.target.checked)}
                      />
                      PII
                    </label>
                  </div>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="block text-xs font-medium text-slate-700">
                      Label EN
                    </label>
                    <input
                      type="text"
                      value={cfLabelEn}
                      onChange={(e) => setCfLabelEn(e.target.value)}
                      placeholder="My Field"
                      className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm"
                    />
                  </div>
                  <div>
                    <label className="block text-xs font-medium text-slate-700">
                      Label zh-CN
                    </label>
                    <input
                      type="text"
                      value={cfLabelZh}
                      onChange={(e) => setCfLabelZh(e.target.value)}
                      className="mt-1 w-full rounded-md border border-slate-300 px-2 py-1.5 text-sm"
                    />
                  </div>
                </div>
                <div className="flex gap-2">
                  <button
                    type="submit"
                    className="btn-primary"
                    disabled={cfSaving}
                  >
                    {cfSaving ? '...' : t('action.save')}
                  </button>
                  <button
                    type="button"
                    className="btn-secondary"
                    onClick={resetCfForm}
                  >
                    {t('action.cancel')}
                  </button>
                </div>
              </form>
            )}
            <DataTable
              rows={customFields}
              columns={customFieldCols}
              rowKey={(r) => r.key}
            />
          </div>
        )

      case 'permissions':
        return (
          <DataTable
            rows={permissions}
            columns={permissionCols}
            rowKey={(r) => r.key}
          />
        )

      case 'menus':
        return (
          <DataTable
            rows={menus}
            columns={menuCols}
            rowKey={(r) => r.path}
          />
        )

      case 'forms':
        return (
          <div>
            <div className="mb-3">
              <button
                className="btn-primary"
                onClick={() => navigate('/admin/metadata/forms/new')}
              >
                + New Form
              </button>
            </div>
            <DataTable
              rows={forms}
              columns={formCols}
              rowKey={(r) => r.slug}
            />
          </div>
        )

      case 'listViews':
        return (
          <div>
            <div className="mb-3">
              <button
                className="btn-primary"
                onClick={() => navigate('/admin/metadata/list-views/new')}
              >
                + New List View
              </button>
            </div>
            <DataTable
              rows={listViews}
              columns={listViewCols}
              rowKey={(r) => r.slug}
            />
          </div>
        )
    }
  }

  // ── Render ─────────────────────────────────────────────────────────

  return (
    <div>
      <PageHeader
        title={t('page.metadataAdmin.title')}
        subtitle="Browse and manage metadata definitions"
      />

      {/* Tab bar */}
      <div className="flex border-b border-slate-200 mb-4">
        {tabs.map((tab) => (
          <button
            key={tab.id}
            className={`px-4 py-2 text-sm font-medium -mb-px ${
              activeTab === tab.id
                ? 'border-b-2 border-blue-500 text-blue-600'
                : 'text-slate-500 hover:text-slate-700'
            }`}
            onClick={() => {
              resetCfForm()
              setActiveTab(tab.id)
            }}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* Tab content */}
      {renderTabContent()}
    </div>
  )
}
