import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import * as forumApi from '../api/forum.js';
import { uploadIcon } from '../api/upload.js';
import { me } from '../api/auth.js';
import { getToken } from '../api/client.js';
import { showSnackbar, normalizePagedList } from '../lib/utils.js';
import ForumIcon from '../components/ForumIcon.jsx';
import Avatar from '../components/Avatar.jsx';

const PAGE_SIZE = 20;
const DURATIONS = [
  { value: 1, label: '1 天' },
  { value: 7, label: '7 天' },
  { value: 30, label: '30 天' },
  { value: 'forever', label: '永久' },
];
const TABS = [
  { key: 'posts', label: '帖子管理', icon: 'forum' },
  { key: 'announcement', label: '公告编辑', icon: 'campaign' },
  { key: 'mutes', label: '用户禁言', icon: 'block' },
  { key: 'profile', label: '版块设置', icon: 'tune' },
];
// 图标底色色板（与后台 ForumManage 同源 12 色；留空 = 按名称哈希自动配色）
const COLOR_PALETTE = ['#6750a4', '#00639b', '#006a60', '#387002', '#7d5260', '#b3261e',
  '#8f4c38', '#5d4037', '#c0008f', '#386a20', '#005ac1', '#6d4fc8'];

/** 版主名提取：兼容数组 / 逗号字符串 */
function moderatorNamesOf(cat) {
  const m = cat && cat.moderators;
  if (Array.isArray(m)) {
    return m.map((x) => (typeof x === 'string' ? x : (x && x.username) || '')).filter(Boolean);
  }
  if (typeof m === 'string') return m.split(',').map((s) => s.trim()).filter(Boolean);
  return [];
}

/**
 * 单版块管理台（路由 /forum/manage/:id，版主/管理员）：
 * Tab 1 帖子管理（搜索 + 分页 + 置顶/加精切换/删除）
 * Tab 2 公告编辑（PUT /categories/:id/announcement）
 * Tab 3 用户禁言（列表 / 添加固定时长 1·7·30天·永久 / 解除；版主只读展示）
 * Tab 4 版块设置（名称/描述/图标/图标底色 → PUT /categories/:id/profile 部分更新）
 * 权限：非版主且非 admin → 无权限提示。
 */
export default function ForumManageCategory() {
  const { id } = useParams();
  const navigate = useNavigate();
  const catId = parseInt(id, 10);

  const [user, setUser] = useState(null);
  const [managedIds, setManagedIds] = useState([]);
  const [permission, setPermission] = useState('checking'); // checking | ok | denied
  const [cat, setCat] = useState(null);   // 版块详情（含聚合/公告）
  const [catMissing, setCatMissing] = useState(false);

  const [tab, setTab] = useState('posts');

  // ── Tab1 帖子管理 ──
  const [qInput, setQInput] = useState(''); // 输入框（回车/点按钮才生效）
  const [q, setQ] = useState('');           // 已应用的关键词
  const [page, setPage] = useState(1);
  const [pageData, setPageData] = useState(null);
  const [postsBusy, setPostsBusy] = useState(false);
  const [acting, setActing] = useState(false);

  // ── Tab2 公告编辑 ──
  const [annText, setAnnText] = useState('');
  const [annSaving, setAnnSaving] = useState(false);

  // ── Tab3 用户禁言 ──
  const [mutes, setMutes] = useState([]);
  const [muteUsername, setMuteUsername] = useState('');
  const [muteDuration, setMuteDuration] = useState(7);
  const [muteBusy, setMuteBusy] = useState(false);

  // ── Tab4 版块设置 ──
  const [profile, setProfile] = useState({ name: '', description: '', icon: '', icon_color: '' });
  const [profileSaving, setProfileSaving] = useState(false);
  const [iconUploading, setIconUploading] = useState(false);
  const iconFileRef = useRef(null);

  const canManage = !!user && (user.role === 'admin' || managedIds.includes(catId));

  // 权限 + 版块信息加载
  useEffect(() => {
    if (!getToken()) { navigate('/login.html'); return; }
    let mounted = true;
    (async () => {
      try {
        const u = await me();
        const ids = await forumApi.listModerated();
        if (!mounted) return;
        setUser(u);
        setManagedIds(ids);
        if (u.role === 'admin' || ids.includes(catId)) {
          setPermission('ok');
          const c = await forumApi.getCategory(catId).catch(() => null);
          if (!mounted) return;
          if (c) {
            setCat(c);
            setAnnText(c.announcement || '');
            setProfile({
              name: c.name || '',
              description: c.description || '',
              icon: c.icon || '',
              icon_color: c.icon_color || '',
            });
          }
          else setCatMissing(true);
        } else {
          setPermission('denied');
        }
      } catch (e) {
        if (mounted) setPermission('denied');
      }
    })();
    return () => { mounted = false; };
  }, [catId, navigate]);

  const loadPosts = useCallback(async () => {
    if (!catId) return;
    setPostsBusy(true);
    try {
      const data = await forumApi.listPosts({ categoryId: catId, page, q: q || undefined });
      setPageData(normalizePagedList(data));
    } catch (e) {
      showSnackbar(e.message);
      setPageData({ items: [], total: 0, page, pageSize: PAGE_SIZE });
    } finally {
      setPostsBusy(false);
    }
  }, [catId, page, q]);

  const loadMutes = useCallback(async () => {
    if (!catId) return;
    try {
      const ms = await forumApi.listMutes(catId);
      setMutes(Array.isArray(ms) ? ms : []);
    } catch (e) {
      showSnackbar(e.message);
      setMutes([]);
    }
  }, [catId]);

  // 帖子列表加载（权限通过后）
  useEffect(() => {
    if (permission === 'ok') loadPosts();
  }, [permission, loadPosts]);

  // 切到禁言 Tab 时拉取
  useEffect(() => {
    if (permission === 'ok' && tab === 'mutes') loadMutes();
  }, [permission, tab, loadMutes]);

  const items = (pageData && pageData.items) || [];
  const totalPages = pageData ? Math.max(1, Math.ceil(pageData.total / (pageData.pageSize || PAGE_SIZE))) : 1;
  const moderatorNames = useMemo(() => (cat ? moderatorNamesOf(cat) : []), [cat]);

  const goPage = (p) => {
    if (p < 1 || p > totalPages || p === page) return;
    setPage(p);
  };
  const search = () => { setQ(qInput.trim()); setPage(1); };

  // ── 帖子操作 ──
  const togglePin = async (p) => {
    if (acting) return;
    setActing(true);
    try {
      await forumApi.setPinned(p.id, !p.is_pinned);
      showSnackbar(p.is_pinned ? '已取消置顶' : '已置顶');
      await loadPosts();
    } catch (e) {
      showSnackbar(e.message);
    }
    setActing(false);
  };
  const toggleEssence = async (p) => {
    if (acting) return;
    setActing(true);
    try {
      await forumApi.setEssence(p.id, !p.is_essence);
      showSnackbar(p.is_essence ? '已取消加精' : '已加精');
      await loadPosts();
    } catch (e) {
      showSnackbar(e.message);
    }
    setActing(false);
  };
  const confirmDeletePost = async (p) => {
    if (!window.confirm(`确定删除帖子「${p.title}」？回复将一并删除`)) return;
    if (acting) return;
    setActing(true);
    try {
      await forumApi.deletePost(p.id);
      showSnackbar('已删除');
      if (items.length === 1 && page > 1) setPage((cur) => cur - 1);
      else await loadPosts();
    } catch (e) {
      showSnackbar(e.message);
    }
    setActing(false);
  };

  // ── 公告 ──
  const saveAnnouncement = async () => {
    setAnnSaving(true);
    try {
      await forumApi.updateAnnouncement(catId, annText.trim());
      showSnackbar('公告已更新');
      const c = await forumApi.getCategory(catId).catch(() => null);
      if (c) setCat(c);
    } catch (e) {
      showSnackbar(e.message);
    }
    setAnnSaving(false);
  };

  // ── 版块设置 ──
  // 图标上传：前端先拦类型（png/jpg/jpeg/gif/webp，不含 svg）与 ≤1MB，成功后把返回 url 填入 icon 字段
  const handleIconFile = async (e) => {
    const f = e.target.files && e.target.files[0];
    e.target.value = ''; // 允许连续选择同一文件
    if (!f) return;
    const IMG_TYPES = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
    if (!IMG_TYPES.includes(f.type)) { showSnackbar('仅支持 png/jpg/jpeg/gif/webp 图片'); return; }
    if (f.size > 1024 * 1024) { showSnackbar('图片不能超过 1MB'); return; }
    setIconUploading(true);
    try {
      const data = await uploadIcon(f);
      if (data && data.url) {
        setProfile((p) => ({ ...p, icon: data.url })); // 实时预览自动生效
        showSnackbar('图标已上传，记得保存设置');
      } else {
        showSnackbar('上传失败，请重试');
      }
    } catch (err) {
      showSnackbar(err.message);
    }
    setIconUploading(false);
  };

  const saveProfile = async () => {
    const name = profile.name.trim();
    if (!name) { showSnackbar('名称不能为空'); return; }
    // 部分更新：只提交与当前值不同的字段（icon_color 留空 = 清除 → 按名称哈希配色）
    const fields = {};
    if (name !== (cat.name || '')) fields.name = name;
    if (profile.description.trim() !== (cat.description || '')) fields.description = profile.description.trim();
    if (profile.icon.trim() !== (cat.icon || '')) fields.icon = profile.icon.trim();
    if ((profile.icon_color || '') !== (cat.icon_color || '')) fields.icon_color = profile.icon_color.trim();
    if (Object.keys(fields).length === 0) { showSnackbar('没有改动'); return; }
    setProfileSaving(true);
    try {
      const res = await forumApi.updateCategoryProfile(catId, fields);
      showSnackbar((res && res.message) || '已保存');
      // 用后端返回的已更新字段合并进 cat，避免整页刷新
      if (res && res.category) {
        setCat((prev) => (prev ? { ...prev, ...res.category } : prev));
        setProfile((p) => ({
          ...p,
          name: res.category.name,
          description: res.category.description || '',
          icon: res.category.icon || '',
          icon_color: res.category.icon_color || '',
        }));
      }
    } catch (e) {
      showSnackbar(e.message);
    }
    setProfileSaving(false);
  };

  // ── 禁言 ──
  const addMute = async () => {
    const name = muteUsername.trim();
    if (!name) { showSnackbar('请输入用户名'); return; }
    setMuteBusy(true);
    try {
      await forumApi.createMute(catId, name, muteDuration);
      showSnackbar('已禁言');
      setMuteUsername('');
      loadMutes();
    } catch (e) {
      showSnackbar(e.message);
    }
    setMuteBusy(false);
  };
  const unmute = async (m) => {
    if (!window.confirm(`确定解除「${m.username || '用户#' + m.user_id}」的禁言？`)) return;
    try {
      await forumApi.deleteMute(catId, m.user_id);
      showSnackbar('已解除');
      loadMutes();
    } catch (e) {
      showSnackbar(e.message);
    }
  };

  // 加载中
  if (permission === 'checking') {
    return <div className="loading"><div className="spinner"></div></div>;
  }

  // 无权限
  if (permission === 'denied') {
    return (
      <div className="empty-state" style={{ maxWidth: 420, margin: '48px auto' }}>
        <div className="empty-icon">🔒</div>
        <p style={{ fontWeight: 500 }}>没有管理权限</p>
        <p className="text-muted" style={{ fontSize: 14, marginTop: 4 }}>你不是该版块的版主，无法进入管理台</p>
        <Link to="/forum.html" className="btn btn-tonal btn-sm" style={{ marginTop: 16 }}>返回论坛</Link>
      </div>
    );
  }

  // 版块不存在
  if (catMissing || !cat) {
    return (
      <div className="empty-state">
        <div className="empty-icon">⚠️</div>
        <p>版块不存在</p>
        <Link to="/forum/manage" className="btn btn-tonal btn-sm" style={{ marginTop: 12 }}>返回我的版块</Link>
      </div>
    );
  }

  return (
    <div className="forum-manage-cat">
      {/* 面包屑：论坛 / 管理 / 版块名 */}
      <nav className="breadcrumbs" aria-label="面包屑">
        <Link to="/forum.html">论坛</Link>
        <span className="sep">/</span>
        <Link to="/forum/manage">管理</Link>
        <span className="sep">/</span>
        <span>{cat.name}</span>
      </nav>

      {/* 版块信息 */}
      <div className="card category-head">
        <ForumIcon icon={cat.icon} name={cat.name} iconColor={cat.icon_color} size={48} />
        <div className="category-head-main">
          <h1>{cat.name} · 管理台</h1>
          <p className="category-head-desc">{cat.description || '暂无描述'}</p>
          <div className="category-head-stats">
            <span>{typeof cat.post_count === 'number' ? `${cat.post_count} 帖子` : ''}</span>
            {cat.today_count ? <span>今日 {cat.today_count}</span> : null}
            {moderatorNames.length > 0 ? <span>版主：{moderatorNames.join('、')}</span> : null}
          </div>
        </div>
        <div className="category-head-actions">
          <Link to={'/forum/c/' + catId} className="btn btn-text btn-sm">
            <span className="material-icons" style={{ fontSize: 16 }}>visibility</span> 查看版块
          </Link>
          <Link to="/forum/manage" className="btn btn-text btn-sm">全部版块</Link>
        </div>
      </div>

      {/* Tab 栏 */}
      <div className="manage-tabs" role="tablist" aria-label="管理功能">
        {TABS.map((t) => (
          <button
            key={t.key}
            type="button"
            role="tab"
            aria-selected={tab === t.key}
            className={'manage-tab' + (tab === t.key ? ' active' : '')}
            onClick={() => setTab(t.key)}
          >
            <span className="material-icons" aria-hidden="true">{t.icon}</span> {t.label}
            {t.key === 'mutes' && mutes.length > 0 ? <span className="manage-tab-count">{mutes.length}</span> : null}
          </button>
        ))}
      </div>

      {/* Tab 1：帖子管理 */}
      {tab === 'posts' && (
        <div className="card manage-card">
          <div className="manage-search">
            <input
              type="text"
              placeholder="搜索帖子标题…"
              value={qInput}
              onChange={(e) => setQInput(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') search(); }}
              aria-label="搜索帖子标题"
            />
            <button className="btn btn-tonal btn-sm" onClick={search}>搜索</button>
          </div>

          {postsBusy && <div className="loading" style={{ padding: 24 }}><div className="spinner"></div></div>}

          {!postsBusy && items.length === 0 && (
            <div className="empty-state" style={{ padding: '24px 0' }}>
              <div className="empty-icon">📝</div><p>暂无帖子</p>
            </div>
          )}

          {!postsBusy && items.map((p) => {
            // 站长保护：站长（username='admin'）的帖子仅站长本人可操作（列表带作者信息 → 前端隐藏操作）
            const isOwnerPost = (p.author_name || '') === 'admin';
            const canActOnPost = !isOwnerPost || (user && p.author_id === user.id);
            return (
              <div className="manage-post-row" key={p.id}>
                <div className="manage-post-main">
                  <div className="manage-post-title">
                    <span className="manage-post-title-text">{p.title}</span>
                    {p.is_pinned ? <span className="post-badge pin">📌</span> : null}
                    {p.is_essence ? <span className="post-badge essence">⭐</span> : null}
                  </div>
                  <div className="manage-post-meta">
                    <Avatar src={p.author_avatar} name={p.author_name} size={22} className="avatar-sm" to={p.author_id ? `/u/${p.author_id}` : undefined} />
                    <span>{p.author_name || '匿名'}</span>
                    <span>{p.created_at}</span>
                    <span>{p.reply_count || 0} 回复</span>
                    {p.sub_category ? <span className="chip chip-tonal">{p.sub_category}</span> : null}
                  </div>
                </div>
                {canActOnPost ? (
                  <div className="manage-post-actions">
                    <button
                      type="button"
                      className={'manage-action' + (p.is_pinned ? ' on' : '')}
                      title={p.is_pinned ? '取消置顶' : '置顶'}
                      aria-label={p.is_pinned ? '取消置顶' : '置顶'}
                      aria-pressed={!!p.is_pinned}
                      disabled={acting}
                      onClick={() => togglePin(p)}
                    >
                      <span className="material-icons" style={{ fontSize: 18 }}>push_pin</span>
                    </button>
                    <button
                      type="button"
                      className={'manage-action' + (p.is_essence ? ' on' : '')}
                      title={p.is_essence ? '取消加精' : '加精'}
                      aria-label={p.is_essence ? '取消加精' : '加精'}
                      aria-pressed={!!p.is_essence}
                      disabled={acting}
                      onClick={() => toggleEssence(p)}
                    >
                      <span className="material-icons" style={{ fontSize: 18 }}>star</span>
                    </button>
                    <button
                      type="button"
                      className="manage-action danger"
                      title="删除帖子"
                      aria-label="删除帖子"
                      disabled={acting}
                      onClick={() => confirmDeletePost(p)}
                    >
                      <span className="material-icons" style={{ fontSize: 18 }}>delete</span>
                    </button>
                  </div>
                ) : (
                  <span className="chip chip-static" title="站长帖子仅站长本人可操作">🔒 站长帖</span>
                )}
              </div>
            );
          })}

          {totalPages > 1 && (
            <div className="pagination">
              <button type="button" className="btn btn-tonal btn-sm" disabled={page <= 1} onClick={() => goPage(page - 1)}>
                <span className="material-icons" style={{ fontSize: 16 }}>chevron_left</span> 上一页
              </button>
              <span className="page-info">第 {page} / {totalPages} 页</span>
              <button type="button" className="btn btn-tonal btn-sm" disabled={page >= totalPages} onClick={() => goPage(page + 1)}>
                下一页 <span className="material-icons" style={{ fontSize: 16 }}>chevron_right</span>
              </button>
            </div>
          )}
        </div>
      )}

      {/* Tab 2：公告编辑 */}
      {tab === 'announcement' && (
        <div className="card manage-card" style={{ maxWidth: 640 }}>
          <h3 className="manage-card-title">板块公告</h3>
          <p className="text-muted" style={{ fontSize: 13, marginBottom: 12 }}>
            展示在版块顶部，留空可清除当前公告
          </p>
          <div className="form-group">
            <label htmlFor="annText">公告内容</label>
            <textarea
              id="annText"
              value={annText}
              onChange={(e) => setAnnText(e.target.value)}
              style={{ minHeight: 100 }}
            />
          </div>
          <button className="btn btn-filled" onClick={saveAnnouncement} disabled={annSaving}>
            {annSaving ? '保存中…' : '保存公告'}
          </button>
        </div>
      )}

      {/* Tab 3：用户禁言 */}
      {tab === 'mutes' && (
        <>
          <div className="card manage-card" style={{ maxWidth: 640 }}>
            <h3 className="manage-card-title">添加禁言</h3>
            <div className="mute-form">
              <input
                type="text"
                placeholder="输入要禁言的用户名"
                value={muteUsername}
                onChange={(e) => setMuteUsername(e.target.value)}
                onKeyDown={(e) => { if (e.key === 'Enter') addMute(); }}
                aria-label="被禁言用户名"
              />
              <select
                value={muteDuration}
                onChange={(e) => {
                  const v = e.target.value;
                  setMuteDuration(v === 'forever' ? v : parseInt(v, 10));
                }}
                aria-label="禁言时长"
              >
                {DURATIONS.map((d) => (
                  <option key={d.value} value={d.value}>{d.label}</option>
                ))}
              </select>
              <button className="btn btn-filled btn-sm" onClick={addMute} disabled={muteBusy || !muteUsername.trim()}>
                {muteBusy ? '提交中…' : '禁言'}
              </button>
            </div>
            <p className="text-muted" style={{ fontSize: 12 }}>被禁用户在本版块发帖 / 回复将被拒绝，到期自动解除</p>
          </div>

          <div className="card manage-card">
            <h3 className="manage-card-title">禁言列表 ({mutes.length})</h3>
            {mutes.length === 0 ? (
              <p className="text-muted" style={{ fontSize: 14 }}>暂无禁言</p>
            ) : (
              mutes.map((m) => {
                const permanent = m.permanent || m.muted_until == null || m.muted_until === '永久';
                return (
                  <div className="mute-row" key={m.user_id}>
                    <div className="mute-main">
                      <div className="mute-user">{m.username || '用户#' + m.user_id}</div>
                      <div className={'mute-expiry' + (permanent ? ' permanent' : '')}>
                        {permanent ? '永久禁言' : `到期：${m.muted_until}`}
                      </div>
                    </div>
                    <button
                      className="btn btn-text btn-sm"
                      style={{ color: 'var(--md-ref-error)' }}
                      onClick={() => unmute(m)}
                    >
                      解除
                    </button>
                  </div>
                );
              })
            )}
          </div>

          {moderatorNames.length > 0 && (
            <div className="card manage-card">
              <h3 className="manage-card-title">版主</h3>
              <p className="text-muted" style={{ fontSize: 13 }}>
                当前版主（仅管理员可更改）：{moderatorNames.join('、')}
              </p>
            </div>
          )}
        </>
      )}

      {/* Tab 4：版块设置 */}
      {tab === 'profile' && (
        <div className="card manage-card profile-form">
          <h3 className="manage-card-title">版块设置</h3>
          <p className="text-muted" style={{ fontSize: 13, marginBottom: 16 }}>
            修改版块的名称、描述与图标，保存后前台版块索引与版块页即时生效
          </p>

          {/* 实时预览 */}
          <div className="profile-preview">
            <ForumIcon icon={profile.icon} name={profile.name} iconColor={profile.icon_color} size={48} />
            <div className="profile-preview-hint">
              预览：{profile.name || '（未填写名称）'}
              {!profile.icon && !profile.icon_color ? ' · 图标与底色按名称自动生成' : ''}
            </div>
          </div>

          <div className="form-group">
            <label htmlFor="profileName">名称 *</label>
            <input
              id="profileName"
              type="text"
              value={profile.name}
              onChange={(e) => setProfile((p) => ({ ...p, name: e.target.value }))}
              placeholder="版块名称（≤50 字）"
              maxLength={50}
            />
          </div>

          <div className="form-group">
            <label htmlFor="profileDesc">描述</label>
            <textarea
              id="profileDesc"
              value={profile.description}
              onChange={(e) => setProfile((p) => ({ ...p, description: e.target.value }))}
              placeholder="版块简介，展示在版块头与卡片上"
              style={{ minHeight: 80 }}
              maxLength={500}
            />
          </div>

          <div className="form-group">
            <label htmlFor="profileIcon">图标</label>
            <div className="icon-input-row">
              <input
                id="profileIcon"
                type="text"
                value={profile.icon}
                onChange={(e) => setProfile((p) => ({ ...p, icon: e.target.value }))}
                placeholder="支持上传 ≤1MB 图片，或输入 emoji / 图片 URL"
                maxLength={100}
              />
              <button
                type="button"
                className="btn btn-tonal btn-sm icon-upload-btn"
                onClick={() => iconFileRef.current && iconFileRef.current.click()}
                disabled={iconUploading}
                aria-label="上传版块图标图片"
              >
                <span className="material-icons" style={{ fontSize: 16 }}>upload</span>
                {iconUploading ? '上传中…' : '上传图片'}
              </button>
            </div>
            <input
              ref={iconFileRef}
              type="file"
              accept="image/png,image/jpeg,image/gif,image/webp"
              aria-label="选择版块图标图片（png/jpg/jpeg/gif/webp，≤1MB）"
              style={{ display: 'none' }}
              onChange={handleIconFile}
            />
            <div className="text-muted" style={{ fontSize: 12, marginTop: 4 }}>
              支持上传 ≤1MB 图片（png/jpg/jpeg/gif/webp），或输入单个 emoji / 图片链接；留空取名称首字
            </div>
          </div>

          <div className="form-group">
            <label>图标底色</label>
            <div className="profile-palette" role="group" aria-label="选择图标底色">
              <button
                type="button"
                className={'profile-swatch clear' + (!profile.icon_color ? ' selected' : '')}
                aria-pressed={!profile.icon_color}
                aria-label="自动配色（留空，按名称哈希）"
                title="自动配色（留空）"
                onClick={() => setProfile((p) => ({ ...p, icon_color: '' }))}
              >
                A
              </button>
              {COLOR_PALETTE.map((col) => (
                <button
                  type="button"
                  key={col}
                  className={'profile-swatch' + (profile.icon_color === col ? ' selected' : '')}
                  style={{ background: col }}
                  aria-pressed={profile.icon_color === col}
                  aria-label={'底色 ' + col}
                  title={col}
                  onClick={() => setProfile((p) => ({ ...p, icon_color: p.icon_color === col ? '' : col }))}
                />
              ))}
            </div>
            <div className="text-muted" style={{ fontSize: 12, marginTop: 4 }}>
              留空时按版块名称哈希自动配色，深浅色主题自适应
            </div>
          </div>

          <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
            <button className="btn btn-filled" onClick={saveProfile} disabled={profileSaving}>
              {profileSaving ? '保存中…' : '保存设置'}
            </button>
            <button
              className="btn btn-text"
              onClick={() => setProfile({
                name: cat.name || '',
                description: cat.description || '',
                icon: cat.icon || '',
                icon_color: cat.icon_color || '',
              })}
              disabled={profileSaving}
            >
              撤销修改
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
