'use client'

import Link from 'next/link'
import { useEffect, useState } from 'react'
import { Check, Plus, Upload, X } from 'lucide-react'
import { AdminShell } from '@/components/admin/AdminShell'
import { apiBase, backend, type BackendExpert, type BackendSiteHome, type BackendSiteHomeAsset, type BackendSiteHomeSlide, type BackendSitePageBlock, type BackendSitePageBlockItem, yuan } from '@/lib/backend'

function absoluteApiUrl(path: string) {
  if (/^https?:\/\//.test(path) || path.startsWith('data:')) return path
  return `${apiBase.replace(/\/api$/, '')}${path}`
}

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

const emptyHome: BackendSiteHome = { slides: [], loginSlides: [], assets: [], featuredExperts: [], blocks: [] }

export default function AdminSiteHomePage() {
  const [home, setHome] = useState<BackendSiteHome>(emptyHome)
  const [experts, setExperts] = useState<BackendExpert[]>([])
  const [error, setError] = useState('')
  const [saving, setSaving] = useState(false)
  const [uploading, setUploading] = useState('')

  useEffect(() => {
    void Promise.all([backend.adminSiteHome(), backend.adminExperts()]).then(([result, expertResult]) => {
      setHome({
        slides: sortItems(result.slides),
        loginSlides: sortItems(result.loginSlides || []),
        assets: sortItems(result.assets),
        featuredExperts: result.featuredExperts || [],
        blocks: sortItems(result.blocks || []).map((block) => ({ ...block, items: sortItems(block.items || []) })),
      })
      setExperts(expertResult.items)
    }).catch((err) => setError(err instanceof Error ? err.message : '首页配置加载失败'))
  }, [])

  async function uploadImage(file: File, onDone: (url: string) => void) {
    if (!['image/jpeg', 'image/png', 'image/webp'].includes(file.type)) {
      setError('图片只支持 JPG、PNG、WebP。')
      return
    }
    setUploading(file.name)
    try {
      const uploaded = await backend.uploadAdminFile(file)
      onDone(absoluteApiUrl(uploaded.url))
    } catch (err) {
      setError(err instanceof Error ? err.message : '上传失败')
    } finally {
      setUploading('')
    }
  }

  function updateSlide(index: number, patch: Partial<BackendSiteHomeSlide>) {
    setHome((current) => ({
      ...current,
      slides: current.slides.map((slide, slideIndex) => slideIndex === index ? { ...slide, ...patch } : slide),
    }))
  }

  function updateLoginSlide(index: number, patch: Partial<BackendSiteHomeSlide>) {
    setHome((current) => ({
      ...current,
      loginSlides: (current.loginSlides || []).map((slide, slideIndex) => slideIndex === index ? { ...slide, ...patch } : slide),
    }))
  }

  function updateAsset(index: number, patch: Partial<BackendSiteHomeAsset>) {
    setHome((current) => ({
      ...current,
      assets: current.assets.map((asset, assetIndex) => assetIndex === index ? { ...asset, ...patch } : asset),
    }))
  }

  function toggleFeaturedExpert(expert: BackendExpert) {
    setHome((current) => {
      const exists = current.featuredExperts.some((item) => item.id === expert.id)
      if (exists) {
        return { ...current, featuredExperts: current.featuredExperts.filter((item) => item.id !== expert.id) }
      }
      if (current.featuredExperts.length >= 4) {
        setError('首页最多选择 4 位专家')
        return current
      }
      setError('')
      return { ...current, featuredExperts: [...current.featuredExperts, expert] }
    })
  }

  async function save() {
    setSaving(true)
    setError('')
    try {
      const saved = await backend.saveAdminSiteHome({
        slides: sortItems(home.slides),
        loginSlides: sortItems(home.loginSlides || []),
        assets: sortItems(home.assets),
        featuredExperts: home.featuredExperts.slice(0, 4),
        blocks: sortItems(home.blocks || []).map((block) => ({ ...block, items: sortItems(block.items || []) })),
      })
      setHome({ slides: sortItems(saved.slides), loginSlides: sortItems(saved.loginSlides || []), assets: sortItems(saved.assets), featuredExperts: saved.featuredExperts || [], blocks: sortItems(saved.blocks || []).map((block) => ({ ...block, items: sortItems(block.items || []) })) })
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存失败')
    } finally {
      setSaving(false)
    }
  }

  const publishedSlideCount = home.slides.filter((slide) => slide.status === 'published').length
  const publishedLoginSlideCount = (home.loginSlides || []).filter((slide) => slide.status === 'published' && slide.imageUrl).length
  const selectedExpertIds = new Set(home.featuredExperts.map((expert) => expert.id))
  const publishedExperts = experts.filter((expert) => expert.status === 'published')

  function updateBlock(index: number, patch: Partial<BackendSitePageBlock>) {
    setHome((current) => ({
      ...current,
      blocks: (current.blocks || []).map((block, blockIndex) => blockIndex === index ? { ...block, ...patch } : block),
    }))
  }

  function updateBlockItem(blockIndex: number, itemIndex: number, patch: Partial<BackendSitePageBlockItem>) {
    setHome((current) => ({
      ...current,
      blocks: (current.blocks || []).map((block, currentBlockIndex) => currentBlockIndex === blockIndex
        ? {
          ...block,
          items: (block.items || []).map((item, currentItemIndex) => currentItemIndex === itemIndex ? { ...item, ...patch } : item),
        }
        : block),
    }))
  }

  function updateBlockItemMetadata(blockIndex: number, itemIndex: number, patch: Record<string, unknown>) {
    setHome((current) => ({
      ...current,
      blocks: (current.blocks || []).map((block, currentBlockIndex) => currentBlockIndex === blockIndex
        ? {
          ...block,
          items: (block.items || []).map((item, currentItemIndex) => currentItemIndex === itemIndex
            ? { ...item, metadata: { ...(item.metadata || {}), ...patch } }
            : item),
        }
        : block),
    }))
  }

  function addBlockItem(blockIndex: number) {
    setHome((current) => ({
      ...current,
      blocks: (current.blocks || []).map((block, currentBlockIndex) => currentBlockIndex === blockIndex
        ? {
          ...block,
          items: [
            ...(block.items || []),
            {
              itemKey: `item-${Date.now()}`,
              title: '新条目',
              subtitle: '',
              description: '',
              imageUrl: '',
              href: '',
              ctaLabel: '',
              status: 'published',
              sortOrder: ((block.items || []).length + 1) * 10,
              metadata: {},
            },
          ],
        }
        : block),
    }))
  }

  return (
    <AdminShell title="首页配置" description="维护首页轮播、登录页轮播、全站固定图片资产、首页专家精选、专家平台主视觉、数据服务主视觉和智能体产品主视觉。">
      <div className="space-y-4">
        <div className="flex items-center justify-between border border-line bg-white px-4 py-3">
          <div>
            <div className="text-sm font-extrabold text-ink">首页轮播：{publishedSlideCount}/5 · 登录页轮播：{publishedLoginSlideCount}/3</div>
            <div className="mt-1 text-xs font-bold text-soft">新闻、课程、活动、专家推荐请进入固定推荐位配置。</div>
          </div>
          <div className="flex items-center gap-2">
            <Link href="/admin/site/recommendations" className="inline-flex h-8 items-center rounded-[4px] border border-line px-3 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
              推荐位配置
            </Link>
            <button type="button" onClick={save} disabled={saving} className="h-8 rounded-[4px] bg-brand px-4 text-xs font-extrabold text-white disabled:bg-line-dark">
              {saving ? '保存中...' : '保存首页配置'}
            </button>
          </div>
        </div>
        {error && <div className="border border-red-100 bg-red-50 px-4 py-3 text-sm font-bold text-red-700">{error}</div>}

        <section className="border border-line bg-white">
          <div className="flex items-center justify-between border-b border-line px-4 py-3">
            <div>
              <div className="text-sm font-extrabold text-ink">登录页轮播图</div>
              <div className="mt-1 text-xs font-bold text-soft">后台上传真实照片，最多 3 张；只有“显示”且已上传图片的项目会进入登录页左侧轮播。</div>
            </div>
            <button
              type="button"
              onClick={() => setHome((current) => ({
                ...current,
                loginSlides: [...(current.loginSlides || []), {
                  id: `login-slide-${Date.now()}`,
                  title: '登录页轮播图',
                  imageUrl: '',
                  sortOrder: ((current.loginSlides || []).length + 1) * 10,
                  status: 'hidden',
                }],
              }))}
              disabled={(home.loginSlides || []).length >= 3}
              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 disabled:text-soft"
            >
              <Plus className="h-3.5 w-3.5" />
              添加图片
            </button>
          </div>
          <div className="divide-y divide-line">
            {(home.loginSlides || []).length === 0 && (
              <div className="px-4 py-8 text-center text-xs font-bold text-soft">暂未配置登录页轮播图，请添加 1-3 张真实照片。</div>
            )}
            {(home.loginSlides || []).map((slide, index) => (
              <div key={slide.id} className="grid gap-3 px-4 py-3 lg:grid-cols-[120px_1fr_90px_96px_150px] lg:items-center">
                <div className="h-20 rounded-[4px] border border-line bg-cover bg-center" style={{ backgroundImage: slide.imageUrl ? `url(${slide.imageUrl})` : undefined }}>
                  {!slide.imageUrl && <div className="grid h-full place-items-center text-[11px] font-bold text-soft">暂无图片</div>}
                </div>
                <input value={slide.title} onChange={(event) => updateLoginSlide(index, { title: event.target.value })} className="h-9 rounded-[4px] border border-line px-3 text-sm" placeholder="图片标题/替代文字" />
                <input value={slide.sortOrder} onChange={(event) => updateLoginSlide(index, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-9 rounded-[4px] border border-line px-3 text-sm" />
                <select value={slide.status} onChange={(event) => updateLoginSlide(index, { status: event.target.value as BackendSiteHomeSlide['status'] })} className="h-9 rounded-[4px] border border-line px-2 text-sm">
                  <option value="published">显示</option>
                  <option value="hidden">隐藏</option>
                </select>
                <div className="flex items-center gap-2">
                  <label className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
                    <Upload className="h-3.5 w-3.5" />
                    {slide.imageUrl ? '重新上传' : '上传'}
                    <input type="file" accept="image/jpeg,image/png,image/webp" className="sr-only" onChange={(event) => {
                      const file = event.target.files?.[0]
                      if (file) void uploadImage(file, (url) => updateLoginSlide(index, { imageUrl: url, status: 'published' }))
                      event.target.value = ''
                    }} />
                  </label>
                  <button type="button" onClick={() => setHome((current) => ({ ...current, loginSlides: (current.loginSlides || []).filter((_, slideIndex) => slideIndex !== index) }))} className="text-xs font-extrabold text-red-600">删除</button>
                </div>
              </div>
            ))}
          </div>
        </section>

        <section className="border border-line bg-white">
          <div className="flex items-center justify-between border-b border-line px-4 py-3">
            <div>
              <div className="text-sm font-extrabold text-ink">首页轮播</div>
              <div className="mt-1 text-xs font-bold text-soft">至少 1 张、最多 5 张发布图；隐藏图不会进入用户端轮播。</div>
            </div>
            <button
              type="button"
              onClick={() => setHome((current) => ({
                ...current,
                slides: [...current.slides, {
                  id: `home-slide-${Date.now()}`,
                  title: '暂无首页轮播图',
                  imageUrl: '',
                  sortOrder: (current.slides.length + 1) * 10,
                  status: 'hidden',
                }],
              }))}
              disabled={home.slides.length >= 5}
              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 disabled:text-soft"
            >
              <Plus className="h-3.5 w-3.5" />
              添加轮播
            </button>
          </div>
          <div className="divide-y divide-line">
            {home.slides.map((slide, index) => (
              <div key={slide.id} className="grid gap-3 px-4 py-3 lg:grid-cols-[96px_1fr_90px_96px_150px] lg:items-center">
                <div className="h-16 rounded-[4px] border border-line bg-cover bg-center" style={{ backgroundImage: slide.imageUrl ? `url(${slide.imageUrl})` : undefined }}>
                  {!slide.imageUrl && <div className="grid h-full place-items-center text-[11px] font-bold text-soft">暂无图片</div>}
                </div>
                <input value={slide.title} onChange={(event) => updateSlide(index, { title: event.target.value })} className="h-9 rounded-[4px] border border-line px-3 text-sm" />
                <input value={slide.sortOrder} onChange={(event) => updateSlide(index, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-9 rounded-[4px] border border-line px-3 text-sm" />
                <select value={slide.status} onChange={(event) => updateSlide(index, { status: event.target.value as BackendSiteHomeSlide['status'] })} className="h-9 rounded-[4px] border border-line px-2 text-sm">
                  <option value="published">显示</option>
                  <option value="hidden">隐藏</option>
                </select>
                <div className="flex items-center gap-2">
                  <label className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
                    <Upload className="h-3.5 w-3.5" />
                    上传
                    <input type="file" accept="image/jpeg,image/png,image/webp" className="sr-only" onChange={(event) => {
                      const file = event.target.files?.[0]
                      if (file) void uploadImage(file, (url) => updateSlide(index, { imageUrl: url }))
                      event.target.value = ''
                    }} />
                  </label>
                  <button type="button" onClick={() => setHome((current) => ({ ...current, slides: current.slides.filter((_, slideIndex) => slideIndex !== index) }))} className="text-xs font-extrabold text-red-600">删除</button>
                </div>
              </div>
            ))}
          </div>
        </section>

        <section className="border border-line bg-white">
          <div className="border-b border-line px-4 py-3">
            <div className="text-sm font-extrabold text-ink">全站固定图片资产</div>
            <div className="mt-1 text-xs font-bold text-soft">包含首页图片、专家平台主视觉、数据服务主视觉和智能体产品主视觉；上传或重新上传后前台立即同步。</div>
          </div>
          <div className="divide-y divide-line">
            {home.assets.map((asset, index) => (
              <div key={asset.key} className="grid gap-3 px-4 py-3 lg:grid-cols-[96px_220px_minmax(0,1fr)_90px_120px] lg:items-center">
                <div className="h-16 rounded-[4px] border border-line bg-cover bg-center" style={{ backgroundImage: asset.imageUrl ? `url(${asset.imageUrl})` : undefined }}>
                  {!asset.imageUrl && <div className="grid h-full place-items-center text-[11px] font-bold text-soft">暂无图片</div>}
                </div>
                <div>
                  <input
                    value={asset.title}
                    onChange={(event) => updateAsset(index, { title: event.target.value })}
                    placeholder="标题"
                    className="h-9 w-full rounded-[4px] border border-line px-3 text-sm font-extrabold text-ink"
                  />
                  <div className="mt-1 text-[11px] font-bold text-soft">{asset.key}</div>
                </div>
                <div className="grid gap-2">
                  <input value={asset.label} onChange={(event) => updateAsset(index, { label: event.target.value })} placeholder="图片替代文字" className="h-9 rounded-[4px] border border-line px-3 text-sm" />
                  <textarea
                    value={asset.description}
                    onChange={(event) => updateAsset(index, { description: event.target.value })}
                    placeholder="描述"
                    rows={2}
                    className="w-full rounded-[4px] border border-line px-3 py-2 text-sm"
                  />
                </div>
                <select value={asset.status} onChange={(event) => updateAsset(index, { status: event.target.value as BackendSiteHomeAsset['status'] })} className="h-9 rounded-[4px] border border-line px-2 text-sm">
                  <option value="published">显示</option>
                  <option value="hidden">隐藏</option>
                </select>
                <label className="inline-flex h-8 cursor-pointer items-center justify-center gap-1.5 rounded-[4px] border border-line px-3 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
                  <Upload className="h-3.5 w-3.5" />
                  {asset.imageUrl ? '重新上传' : '上传'}
                  <input type="file" accept="image/jpeg,image/png,image/webp" className="sr-only" onChange={(event) => {
                    const file = event.target.files?.[0]
                    if (file) void uploadImage(file, (url) => updateAsset(index, { imageUrl: url }))
                    event.target.value = ''
                  }} />
                </label>
              </div>
            ))}
          </div>
        </section>

        <section className="border border-line bg-white">
          <div className="border-b border-line px-4 py-3">
            <div className="text-sm font-extrabold text-ink">首页运营区块</div>
            <div className="mt-1 text-xs font-bold text-soft">维护合作单位、服务入口、智能体工作流和会员权益卡；条目支持排序、隐藏、跳转和 CTA。</div>
          </div>
          <div className="divide-y divide-line">
            {(home.blocks || []).length === 0 && (
              <div className="px-4 py-8 text-center text-xs font-bold text-soft">暂未初始化首页区块，请先运行最新迁移。</div>
            )}
            {(home.blocks || []).map((block, blockIndex) => (
              <div key={block.blockKey} className="space-y-3 px-4 py-4">
                <div className="grid gap-3 lg:grid-cols-[180px_1fr_1fr_90px_96px_auto] lg:items-center">
                  <div>
                    <div className="text-xs font-extrabold text-soft">{block.blockKey}</div>
                    <input value={block.layout} onChange={(event) => updateBlock(blockIndex, { layout: event.target.value })} className="mt-1 h-8 w-full rounded-[4px] border border-line px-2 text-xs" placeholder="布局标识" />
                  </div>
                  <input value={block.title} onChange={(event) => updateBlock(blockIndex, { title: event.target.value })} className="h-9 rounded-[4px] border border-line px-3 text-sm font-extrabold" placeholder="区块标题" />
                  <input value={block.subtitle} onChange={(event) => updateBlock(blockIndex, { subtitle: event.target.value })} className="h-9 rounded-[4px] border border-line px-3 text-sm" placeholder="副标题" />
                  <input value={block.sortOrder} onChange={(event) => updateBlock(blockIndex, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-9 rounded-[4px] border border-line px-2 text-sm" />
                  <select value={block.status} onChange={(event) => updateBlock(blockIndex, { status: event.target.value as BackendSitePageBlock['status'] })} className="h-9 rounded-[4px] border border-line px-2 text-sm">
                    <option value="published">显示</option>
                    <option value="hidden">隐藏</option>
                  </select>
                  <button type="button" onClick={() => addBlockItem(blockIndex)} 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>
                <textarea value={block.body} onChange={(event) => updateBlock(blockIndex, { body: event.target.value })} className="w-full rounded-[4px] border border-line px-3 py-2 text-sm" rows={2} placeholder="区块说明" />
                <div className="divide-y divide-line border border-line">
                  {(block.items || []).map((item, itemIndex) => (
	                    <div key={item.itemKey} className="grid gap-2 px-3 py-3 lg:grid-cols-[120px_160px_1fr_160px_120px_78px_90px_auto_auto] lg:items-center">
	                      <input value={item.itemKey} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { itemKey: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="条目键" />
	                      <input value={item.title} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { title: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-sm font-bold" placeholder="标题" />
	                      <input value={item.description} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { description: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-sm" placeholder="描述" />
                      <input value={item.href} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { href: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-sm" placeholder="链接" />
                      <input value={item.ctaLabel} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { ctaLabel: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-sm" placeholder="CTA" />
                      <input value={item.sortOrder} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { sortOrder: Number(event.target.value || 0) })} type="number" className="h-8 rounded-[4px] border border-line px-2 text-sm" />
                      <select value={item.status} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { status: event.target.value as BackendSitePageBlockItem['status'] })} className="h-8 rounded-[4px] border border-line px-2 text-sm">
                        <option value="published">显示</option>
                        <option value="hidden">隐藏</option>
                      </select>
                      <button type="button" onClick={() => setHome((current) => ({
                        ...current,
                        blocks: (current.blocks || []).map((currentBlock, currentBlockIndex) => currentBlockIndex === blockIndex
                          ? { ...currentBlock, items: (currentBlock.items || []).filter((_, currentItemIndex) => currentItemIndex !== itemIndex) }
                          : currentBlock),
                      }))} className="h-8 rounded-[4px] border border-red-100 px-2 text-xs font-extrabold text-red-600">删除</button>
                      <label className="inline-flex h-8 cursor-pointer items-center justify-center rounded-[4px] border border-line px-2 text-xs font-extrabold text-ink hover:border-brand hover:text-brand">
                        {item.imageUrl ? '换图' : '图片'}
                        <input type="file" accept="image/jpeg,image/png,image/webp" className="sr-only" onChange={(event) => {
                          const file = event.target.files?.[0]
                          if (file) void uploadImage(file, (url) => updateBlockItem(blockIndex, itemIndex, { imageUrl: url }))
	                          event.target.value = ''
	                        }} />
	                      </label>
	                      <div className="grid gap-2 lg:col-span-9 md:grid-cols-[150px_1fr_86px_86px_96px_96px]">
	                        <input value={item.subtitle || ''} onChange={(event) => updateBlockItem(blockIndex, itemIndex, { subtitle: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="副标题/价格/标签" />
	                        <input value={String(item.metadata?.visual || '')} onChange={(event) => updateBlockItemMetadata(blockIndex, itemIndex, { visual: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="视觉说明/替代文本" />
	                        <input value={String(item.metadata?.assetKey || '')} onChange={(event) => updateBlockItemMetadata(blockIndex, itemIndex, { assetKey: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="assetKey" />
	                        <input value={String(item.metadata?.tone || '')} onChange={(event) => updateBlockItemMetadata(blockIndex, itemIndex, { tone: event.target.value })} className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="tone" />
	                        <input value={String(item.metadata?.x || '')} onChange={(event) => updateBlockItemMetadata(blockIndex, itemIndex, { x: Number(event.target.value || 0) })} type="number" className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="x" />
	                        <input value={String(item.metadata?.y || '')} onChange={(event) => updateBlockItemMetadata(blockIndex, itemIndex, { y: Number(event.target.value || 0) })} type="number" className="h-8 rounded-[4px] border border-line px-2 text-xs" placeholder="y" />
	                      </div>
	                    </div>
	                  ))}
                </div>
              </div>
            ))}
          </div>
        </section>

        <section className="border border-line bg-white">
          <div className="border-b border-line px-4 py-3">
            <div className="text-sm font-extrabold text-ink">首页专家精选</div>
            <div className="mt-1 text-xs font-bold text-soft">从已发布专家列表中选择，最多 4 位；前台按选择顺序展示。</div>
          </div>
          <div className="grid gap-4 px-4 py-4 xl:grid-cols-[360px_1fr]">
            <div className="border border-line bg-bg/40">
              <div className="border-b border-line px-3 py-2 text-xs font-extrabold text-soft">已选 {home.featuredExperts.length}/4</div>
              <div className="divide-y divide-line">
                {home.featuredExperts.length === 0 && (
                  <div className="px-3 py-6 text-center text-xs font-bold text-soft">暂未选择首页专家</div>
                )}
                {home.featuredExperts.map((expert, index) => (
                  <div key={expert.id} className="grid grid-cols-[32px_1fr_auto] items-center gap-3 px-3 py-3">
                    <div className="text-xs font-extrabold text-brand">0{index + 1}</div>
                    <div className="min-w-0">
                      <div className="truncate text-sm font-extrabold text-ink">{expert.name}</div>
                      <div className="mt-1 truncate text-[11px] font-bold text-soft">{expert.title || '未填写职务'} · {expert.organization || '未填写机构'}</div>
                    </div>
                    <button type="button" onClick={() => toggleFeaturedExpert(expert)} className="grid h-8 w-8 place-items-center rounded-[4px] border border-line text-muted hover:border-red-200 hover:text-red-600" aria-label={`移除${expert.name}`}>
                      <X className="h-3.5 w-3.5" />
                    </button>
                  </div>
                ))}
              </div>
            </div>

            <div className="grid gap-3 md:grid-cols-2">
              {publishedExperts.map((expert) => {
                const selected = selectedExpertIds.has(expert.id)
                const disabled = !selected && home.featuredExperts.length >= 4
                return (
                  <div key={expert.id} className={`flex min-w-0 flex-col gap-3 border p-3 ${selected ? 'border-brand bg-brand-light/35' : 'border-line bg-white'}`}>
                    <div className="min-w-0">
                      <div className="flex min-w-0 items-start justify-between gap-3">
                        <div className="truncate text-sm font-extrabold text-ink">{expert.name}</div>
                        <button
                          type="button"
                          onClick={() => toggleFeaturedExpert(expert)}
                          disabled={disabled}
                          className={`inline-flex h-7 shrink-0 items-center gap-1 rounded-[4px] px-2.5 text-xs font-extrabold ${
                            selected
                              ? 'bg-brand text-white'
                              : 'border border-line bg-white text-muted hover:border-brand hover:text-brand disabled:bg-bg disabled:text-soft'
                          }`}
                        >
                          {selected ? <Check className="h-3.5 w-3.5" /> : <Plus className="h-3.5 w-3.5" />}
                          {selected ? '已选' : '选择'}
                        </button>
                      </div>
                      <div className="mt-1 truncate text-xs font-bold text-muted">{expert.title || '未填写职务'} · {expert.organization || '未填写机构'}</div>
                    </div>
                    <div className="flex flex-wrap gap-1.5">
                      {(expert.directions || expert.specialties || []).slice(0, 3).map((tag) => (
                        <span key={tag} className="rounded-[3px] bg-bg px-2 py-0.5 text-[11px] font-bold text-brand">{tag}</span>
                      ))}
                    </div>
                    <div className="text-xs font-bold text-soft">¥{yuan(expert.priceAmount).toLocaleString()} / 小时</div>
                  </div>
                )
              })}
            </div>
          </div>
        </section>

        {uploading && <div className="text-xs font-bold text-brand">正在上传：{uploading}</div>}
      </div>
    </AdminShell>
  )
}
