'use client'

import { useEffect, useMemo, useState } from 'react'
import { Plus, RefreshCw, Save, Trash2 } from 'lucide-react'
import { AdminShell } from '@/components/admin/AdminShell'
import { backend, type BackendConsultingOption, type BackendConsultingOptionSet } from '@/lib/backend'

function sortByOrder<T extends { sortOrder: number }>(items: T[]) {
  return [...items].sort((a, b) => a.sortOrder - b.sortOrder)
}

function optionCode(label: string, fallback: string) {
  const text = label.trim().toLowerCase()
  if (!text) return fallback
  return text
    .replace(/data_service_/g, '')
    .replace(/[^\w\u4e00-\u9fa5]+/g, '_')
    .replace(/^_+|_+$/g, '')
    .slice(0, 40) || fallback
}

export default function AdminDataServiceOptionsPage() {
  const [optionSets, setOptionSets] = useState<BackendConsultingOptionSet[]>([])
  const [selectedCode, setSelectedCode] = useState('')
  const [error, setError] = useState('')
  const [message, setMessage] = useState('')
  const [loading, setLoading] = useState(false)
  const [saving, setSaving] = useState(false)

  async function reload() {
    setLoading(true)
    setError('')
    setMessage('')
    try {
      const result = await backend.adminDataServiceOptions()
      const sets = sortByOrder(result.optionSets || []).map((set) => ({ ...set, options: sortByOrder(set.options || []) }))
      setOptionSets(sets)
      setSelectedCode((current) => current || sets[0]?.code || '')
    } catch (err) {
      setError(err instanceof Error ? err.message : '数据服务选项加载失败')
    } finally {
      setLoading(false)
    }
  }

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

  const selectedSet = useMemo(
    () => optionSets.find((set) => set.code === selectedCode) || optionSets[0],
    [optionSets, selectedCode],
  )

  function updateSet(code: string, patch: Partial<BackendConsultingOptionSet>) {
    setOptionSets((current) => current.map((set) => set.code === code ? { ...set, ...patch } : set))
  }

  function updateOption(setCode: string, index: number, patch: Partial<BackendConsultingOption>) {
    setOptionSets((current) => current.map((set) => set.code === setCode
      ? { ...set, options: (set.options || []).map((option, optionIndex) => optionIndex === index ? { ...option, ...patch } : option) }
      : set))
  }

  function addOption(setCode: string) {
    setOptionSets((current) => current.map((set) => {
      if (set.code !== setCode) return set
      const nextIndex = (set.options || []).length + 1
      return {
        ...set,
        options: [
          ...(set.options || []),
          {
            code: `${set.code.replace(/^data_service_/, '')}_${nextIndex}`,
            label: '新选项',
            description: '',
            sortOrder: nextIndex * 10,
            status: 'active',
            metadata: {},
          },
        ],
      }
    }))
  }

  function removeOption(setCode: string, index: number) {
    setOptionSets((current) => current.map((set) => set.code === setCode
      ? { ...set, options: (set.options || []).filter((_, optionIndex) => optionIndex !== index) }
      : set))
  }

  async function save() {
    setSaving(true)
    setError('')
    setMessage('')
    try {
      const payload = sortByOrder(optionSets).map((set) => ({
        ...set,
        options: sortByOrder(set.options || []).map((option, index) => ({
          ...option,
          code: option.code || optionCode(option.label, `${set.code.replace(/^data_service_/, '')}_${index + 1}`),
          sortOrder: Number(option.sortOrder || (index + 1) * 10),
        })),
      }))
      const result = await backend.saveAdminDataServiceOptions(payload)
      if ('optionSets' in result) {
        const sets = sortByOrder(result.optionSets || []).map((set) => ({ ...set, options: sortByOrder(set.options || []) }))
        setOptionSets(sets)
      }
      setMessage('服务选项已保存，Web 和小程序申请表会读取这套配置。')
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存失败')
    } finally {
      setSaving(false)
    }
  }

  return (
    <AdminShell title="数据服务选项配置" description="维护申请表和案例筛选使用的服务类型、行业场景、预算范围、交付方式等字典。">
      <div className="flex h-[calc(100vh-178px)] min-h-[620px] flex-col overflow-hidden">
        <div className="mb-3 flex shrink-0 flex-wrap items-center justify-between gap-2 border border-line bg-white px-3 py-2">
          <div className="text-xs font-bold text-muted">停用后不会出现在用户申请表；历史申请里的旧值保留。</div>
          <div className="flex gap-2">
            <button type="button" onClick={() => void reload()} className="inline-flex h-8 items-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-muted hover:border-brand hover:text-brand">
              <RefreshCw className="h-3.5 w-3.5" />
              {loading ? '刷新中' : '刷新'}
            </button>
            <button type="button" onClick={() => void save()} disabled={saving} className="inline-flex h-8 items-center gap-1.5 rounded-[4px] bg-brand px-3 text-xs font-extrabold text-white hover:bg-brand-dark disabled:bg-line-dark">
              <Save className="h-3.5 w-3.5" />
              {saving ? '保存中' : '保存'}
            </button>
          </div>
        </div>
        {(error || message) && <div className={`mb-3 shrink-0 border px-3 py-2 text-xs font-bold ${error ? 'border-red-200 bg-red-50 text-red-700' : 'border-green-100 bg-green-50 text-green'}`}>{error || message}</div>}

        <div className="grid min-h-0 flex-1 gap-3 lg:grid-cols-[260px_minmax(0,1fr)]">
          <aside className="min-h-0 overflow-y-auto border border-line bg-white">
            <div className="border-b border-line px-3 py-2 text-xs font-extrabold text-soft">选项集</div>
            {optionSets.map((set) => (
              <button
                key={set.code}
                type="button"
                onClick={() => setSelectedCode(set.code)}
                className={`block w-full border-b border-line px-3 py-3 text-left hover:bg-bg ${selectedSet?.code === set.code ? 'bg-brand-light/40' : ''}`}
              >
                <div className="flex items-center justify-between gap-2">
                  <span className="text-sm font-extrabold text-ink">{set.name}</span>
                  <span className="text-[11px] font-extrabold text-brand">{(set.options || []).filter((item) => item.status !== 'disabled').length}</span>
                </div>
                <div className="mt-1 truncate text-[11px] font-bold text-soft">{set.code}</div>
              </button>
            ))}
          </aside>

          <section className="min-h-0 overflow-hidden border border-line bg-white">
            {selectedSet ? (
              <div className="flex h-full min-h-0 flex-col">
                <div className="shrink-0 border-b border-line p-3">
                  <div className="grid gap-2 lg:grid-cols-[180px_minmax(0,1fr)_90px_100px]">
                    <input value={selectedSet.name} onChange={(event) => updateSet(selectedSet.code, { name: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-sm font-extrabold" />
                    <input value={selectedSet.description || ''} onChange={(event) => updateSet(selectedSet.code, { description: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" />
                    <input value={selectedSet.sortOrder} onChange={(event) => updateSet(selectedSet.code, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-8 rounded-[4px] border border-line px-2 text-xs" />
                    <select value={selectedSet.status} onChange={(event) => updateSet(selectedSet.code, { status: event.target.value as BackendConsultingOptionSet['status'] })} className="h-8 rounded-[4px] border border-line px-2 text-xs">
                      <option value="active">启用</option>
                      <option value="disabled">停用</option>
                    </select>
                  </div>
                </div>
                <div className="min-h-0 flex-1 overflow-y-auto">
                  <div className="grid grid-cols-[42px_minmax(120px,1fr)_minmax(160px,1.2fr)_80px_88px_58px] border-b border-line px-3 py-2 text-[11px] font-extrabold text-soft">
                    <span>序</span><span>显示名称</span><span>说明</span><span>排序</span><span>状态</span><span />
                  </div>
                  {(selectedSet.options || []).map((option, index) => (
                    <div key={`${option.code}-${index}`} className="grid grid-cols-[42px_minmax(120px,1fr)_minmax(160px,1.2fr)_80px_88px_58px] items-center gap-2 border-b border-line px-3 py-2">
                      <span className="text-xs font-extrabold text-soft">{index + 1}</span>
                      <div>
                        <input value={option.label} onChange={(event) => updateOption(selectedSet.code, index, { label: event.target.value })} className="h-8 w-full rounded-[4px] border border-line px-2 text-sm font-bold" />
                        <input value={option.code} onChange={(event) => updateOption(selectedSet.code, index, { code: event.target.value })} className="mt-1 h-7 w-full rounded-[4px] border border-line px-2 text-[11px] text-soft" />
                      </div>
                      <input value={option.description || ''} onChange={(event) => updateOption(selectedSet.code, index, { description: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" />
                      <input value={option.sortOrder} onChange={(event) => updateOption(selectedSet.code, index, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-8 rounded-[4px] border border-line px-2 text-xs" />
                      <select value={option.status} onChange={(event) => updateOption(selectedSet.code, index, { status: event.target.value as BackendConsultingOption['status'] })} className="h-8 rounded-[4px] border border-line px-2 text-xs">
                        <option value="active">启用</option>
                        <option value="disabled">停用</option>
                      </select>
                      <button type="button" onClick={() => removeOption(selectedSet.code, index)} className="grid h-8 w-8 place-items-center rounded-[4px] border border-line text-red-600 hover:border-red-200 hover:bg-red-50" aria-label="删除选项">
                        <Trash2 className="h-3.5 w-3.5" />
                      </button>
                    </div>
                  ))}
                  <div className="p-3">
                    <button type="button" onClick={() => addOption(selectedSet.code)} className="inline-flex h-8 items-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
                      <Plus className="h-3.5 w-3.5" />
                      新增选项
                    </button>
                  </div>
                </div>
              </div>
            ) : (
              <div className="grid h-full place-items-center text-sm font-bold text-muted">暂无选项配置</div>
            )}
          </section>
        </div>
      </div>
    </AdminShell>
  )
}
