// Profile — 全屏个人主页覆盖层
// 包含：个人信息设置 + 我的内容（问题/投票）
const sb = window.supabaseClient;

// ── 多语言文案 ────────────────────────────────────────────────────
const PROFILE_I18N = {
  zh: {
    fileTooLarge: '文件不能超过 2 MB',
    notImage: '请选择图片文件',
    uploadFail: '上传失败：',
    bucketNotFound: '存储桶未配置，请联系管理员',
    uploadPermission: '没有上传权限，请重新登录',
    saveFail: '保存失败：',
    rlsError: '没有操作权限，请重新登录后再试',
    avatar: '头像',
    avatarHint: '点击上传头像',
    avatarSaved: '头像保存成功',
    avatarDesc: '支持 JPG、PNG、WebP · 最大 2 MB',
    nickname: '昵称',
    email: '邮箱',
    verified: '已验证',
    telegram: 'Telegram',
    socialLabel: '社交平台主页',
    addLink: '添加平台链接',
    platformName: '平台名称',
    saving: '保存中…',
    saved: '已保存',
    profileSaved: '个人信息修改成功！',
    saveBtn: '保存修改',
    customPlatform: '自定义平台',
    xProfile: 'X (Twitter)',
    xPlaceholder: 'https://x.com/yourusername',
  },
  en: {
    fileTooLarge: 'File must be under 2 MB',
    notImage: 'Please select an image file',
    uploadFail: 'Upload failed: ',
    bucketNotFound: 'Storage bucket not configured, contact admin',
    uploadPermission: 'No upload permission, please sign in again',
    saveFail: 'Save failed: ',
    rlsError: 'No permission, please sign in again',
    avatar: 'Avatar',
    avatarHint: 'Click to upload avatar',
    avatarSaved: 'Avatar saved',
    avatarDesc: 'JPG, PNG, WebP · Max 2 MB',
    nickname: 'Nickname',
    email: 'Email',
    verified: 'Verified',
    telegram: 'Telegram',
    socialLabel: 'Social profiles',
    addLink: 'Add platform link',
    platformName: 'Platform name',
    saving: 'Saving…',
    saved: 'Saved',
    profileSaved: 'Profile updated successfully!',
    saveBtn: 'Save changes',
    customPlatform: 'Custom',
    xProfile: 'X (Twitter)',
    xPlaceholder: 'https://x.com/yourusername',
  },
};

function useProfileLang() {
  const [lang, setLang] = React.useState(() => window.__kiwvoLang || localStorage.getItem('kiwvo.lang') || 'zh');
  React.useEffect(() => {
    const on = (e) => setLang(e.detail);
    window.addEventListener('kiwvo:lang', on);
    return () => window.removeEventListener('kiwvo:lang', on);
  }, []);
  return PROFILE_I18N[lang] || PROFILE_I18N.zh;
}

// ── 预设社交平台 ─────────────────────────────────────────────────
const PRESET_PLATFORMS = [
  { key: 'x',       label: 'X (Twitter)', placeholder: 'https://x.com/yourname' },
  { key: 'binance', label: 'Binance Live', placeholder: 'https://www.binance.com/en/live/...' },
  { key: 'okx',     label: 'OKX Live',    placeholder: 'https://www.okx.com/...' },
  { key: 'gate',    label: 'Gate.io',     placeholder: 'https://www.gate.io/...' },
  { key: 'bybit',   label: 'Bybit',       placeholder: 'https://www.bybit.com/...' },
  { key: 'youtube', label: 'YouTube',     placeholder: 'https://youtube.com/@yourname' },
  { key: 'twitch',  label: 'Twitch',      placeholder: 'https://twitch.tv/yourname' },
  { key: 'telegram',label: 'Telegram',    placeholder: 'https://t.me/yourname' },
  { key: 'custom',  label: '自定义平台',   placeholder: '' },
];

// ── Supabase 服务 ────────────────────────────────────────────────
const ProfileDB = {
  async getProfile(userId) {
    const { data, error } = await sb
      .from('profiles')
      .select('*')
      .eq('id', userId)
      .single();
    if (error && error.code !== 'PGRST116') throw error;
    return data;
  },

  async saveProfile(userId, updates) {
    const { error } = await sb
      .from('profiles')
      .upsert({ id: userId, ...updates }, { onConflict: 'id' });
    if (error) {
      // 新列尚未迁移时，退回只保存基础字段
      if (error.message && (error.message.includes('schema cache') || error.message.includes('column'))) {
        const base = { nickname: updates.nickname, avatar_url: updates.avatar_url };
        const { error: err2 } = await sb
          .from('profiles')
          .upsert({ id: userId, ...base }, { onConflict: 'id' });
        if (err2) throw err2;
        // 提示用户需要执行迁移
        console.warn('[kiwvo] profiles 表缺少新列（telegram/social_links），已只保存基础信息。请在 Supabase Dashboard → SQL Editor 运行迁移脚本。');
        return;
      }
      throw error;
    }
  },

  async uploadAvatar(userId, file) {
    const ext = file.name.split('.').pop();
    const path = `${userId}/avatar.${ext}`;
    const { error } = await sb.storage
      .from('avatars')
      .upload(path, file, { upsert: true, contentType: file.type });
    if (error) throw error;
    const { data } = sb.storage.from('avatars').getPublicUrl(path);
    return data.publicUrl + '?t=' + Date.now();
  },

  async getMyQuestions(userId) {
    const { data, error } = await sb
      .from('questions')
      .select('id, title, tag, solved, created_at')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });
    if (error) throw error;
    return data || [];
  },

  async getMyVotes(userId) {
    const { data, error } = await sb
      .from('question_votes')
      .select('question_id, questions(id, title, tag)')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });
    if (error) throw error;
    return (data || []).filter(v => v.questions).map(v => v.questions);
  },

  async getMyFeatureVotes(userId) {
    const { data, error } = await sb
      .from('feature_votes')
      .select('feature_id, feature_requests(id, title)')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });
    if (error) throw error;
    return (data || []).filter(v => v.feature_requests).map(v => v.feature_requests);
  },
};

function timeAgoP(dateStr) {
  const now = Date.now();
  const d = new Date(dateStr).getTime();
  const diff = now - d;
  const mins = Math.floor(diff / 60000);
  if (mins < 1) return '刚刚';
  if (mins < 60) return `${mins} 分钟前`;
  const hours = Math.floor(mins / 60);
  if (hours < 24) return `${hours} 小时前`;
  const days = Math.floor(hours / 24);
  return `${days} 天前`;
}

// ── 头像上传区 ───────────────────────────────────────────────────
function AvatarUpload({ avatarUrl, onUploaded, uploading, setUploading, t }) {
  const inputRef = React.useRef(null);
  const [preview, setPreview] = React.useState(avatarUrl);
  const [error, setError] = React.useState('');
  const [toast, setToast] = React.useState('');

  React.useEffect(() => { setPreview(avatarUrl); }, [avatarUrl]);

  const handleFile = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (file.size > 2 * 1024 * 1024) { setError(t.fileTooLarge); return; }
    if (!file.type.startsWith('image/')) { setError(t.notImage); return; }
    setError('');
    const localUrl = URL.createObjectURL(file);
    setPreview(localUrl);
    setUploading(true);
    try {
      const url = await onUploaded(file);
      setPreview(url);
      setToast(t.avatarSaved);
      setTimeout(() => setToast(''), 2000);
    } catch (err) {
      const msg = (err.message || '').toLowerCase();
      const localMsg = msg.includes('bucket') ? t.bucketNotFound
        : msg.includes('permission') || msg.includes('policy') ? t.uploadPermission
        : t.uploadFail + err.message;
      setError(localMsg);
      setPreview(avatarUrl);
    } finally {
      setUploading(false);
    }
  };

  return (
    <div className="flex items-center gap-5">
      <div className="relative shrink-0">
        <div
          className="w-20 h-20 rounded-full overflow-hidden bg-emerald-900/30 border-2 border-emerald-400/20 flex items-center justify-center cursor-pointer hover:border-emerald-400/50 transition-colors"
          onClick={() => inputRef.current?.click()}
        >
          {preview ? (
            <img src={preview} alt="avatar" className="w-full h-full object-cover" />
          ) : (
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" className="text-emerald-400/50">
              <circle cx="12" cy="8" r="4" stroke="currentColor" strokeWidth="1.5"/>
              <path d="M4 20c0-4 3.6-7 8-7s8 3 8 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
            </svg>
          )}
          {uploading && (
            <div className="absolute inset-0 bg-black/60 rounded-full flex items-center justify-center">
              <svg className="animate-spin text-emerald-400" width="20" height="20" viewBox="0 0 24 24" fill="none">
                <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" opacity="0.25"/>
                <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
              </svg>
            </div>
          )}
        </div>
        <button
          type="button"
          onClick={() => inputRef.current?.click()}
          className="absolute -bottom-1 -right-1 w-6 h-6 rounded-full bg-emerald-500 hover:bg-emerald-400 text-[#052E21] flex items-center justify-center transition-colors shadow-lg"
        >
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none">
            <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
          </svg>
        </button>
        <input ref={inputRef} type="file" accept="image/*" className="hidden" onChange={handleFile} />
      </div>
      <div>
        <p className="text-[13px] text-white/70">{t.avatarHint}</p>
        <p className="text-[11.5px] text-white/35 mt-1">{t.avatarDesc}</p>
        {error && <p className="text-[11.5px] text-rose-400 mt-1">{error}</p>}
        {toast && <p className="text-[11.5px] text-emerald-400 mt-1">{toast}</p>}
      </div>
    </div>
  );
}

// ── 社交链接编辑器 ────────────────────────────────────────────────
function SocialLinksEditor({ links, onChange, t }) {
  const addLink = () => {
    onChange([...links, { platform: '', url: '', key: 'custom' }]);
  };

  const updateLink = (i, field, val) => {
    const next = links.map((l, idx) => idx === i ? { ...l, [field]: val } : l);
    onChange(next);
  };

  const removeLink = (i) => {
    onChange(links.filter((_, idx) => idx !== i));
  };

  const setPlatform = (i, key) => {
    const preset = PRESET_PLATFORMS.find(p => p.key === key);
    updateLink(i, 'platform', key === 'custom' ? '' : preset.label);
    updateLink(i, 'key', key);
  };

  // 「自定义平台」选项文案跟随语言
  const presetsLocalized = PRESET_PLATFORMS.map(p =>
    p.key === 'custom' ? { ...p, label: t.customPlatform } : p
  );

  return (
    <div className="space-y-2">
      {links.map((link, i) => {
        const isCustom = link.key === 'custom' || !PRESET_PLATFORMS.find(p => p.key === link.key && p.key !== 'custom');
        const preset = PRESET_PLATFORMS.find(p => p.key === link.key);
        return (
          <div key={i} className="flex items-center gap-2">
            {/* 平台选择 */}
            <select
              value={link.key || 'custom'}
              onChange={e => setPlatform(i, e.target.value)}
              className="w-36 h-9 rounded-lg bg-[#0A1512] border border-white/[0.08] text-[12.5px] text-white/80 px-2 outline-none focus:border-emerald-400/40 appearance-none cursor-pointer"
            >
              {presetsLocalized.map(p => (
                <option key={p.key} value={p.key} style={{background:'#0F1E1A'}}>{p.label}</option>
              ))}
            </select>
            {/* 自定义平台名 */}
            {isCustom && (
              <input
                value={link.platform}
                onChange={e => updateLink(i, 'platform', e.target.value)}
                placeholder={t.platformName}
                className="w-24 h-9 rounded-lg bg-[#0A1512] border border-white/[0.08] text-[12.5px] text-white placeholder:text-white/25 px-2.5 outline-none focus:border-emerald-400/40"
              />
            )}
            {/* URL */}
            <input
              value={link.url}
              onChange={e => updateLink(i, 'url', e.target.value)}
              placeholder={preset?.placeholder || 'https://'}
              className="flex-1 h-9 rounded-lg bg-[#0A1512] border border-white/[0.08] text-[12.5px] text-white/80 placeholder:text-white/20 px-2.5 outline-none focus:border-emerald-400/40 transition-colors"
            />
            {/* 删除按钮 — 更明显 */}
            <button
              type="button"
              onClick={() => removeLink(i)}
              className="shrink-0 w-9 h-9 rounded-lg bg-white/[0.06] border border-white/[0.12] text-white/70 hover:text-white hover:bg-rose-500/20 hover:border-rose-400/40 transition-all flex items-center justify-center"
            >
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
                <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"/>
              </svg>
            </button>
          </div>
        );
      })}
      <button
        type="button"
        onClick={addLink}
        className="flex items-center gap-1.5 h-9 px-3 rounded-lg border border-dashed border-white/[0.1] text-[12.5px] text-white/40 hover:text-emerald-300 hover:border-emerald-400/30 transition-all w-full justify-center"
      >
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
          <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
        </svg>
        {t.addLink}
      </button>
    </div>
  );
}

// ── 个人信息 Tab ──────────────────────────────────────────────────
function InfoTab({ user, profile, onSaved }) {
  const t = useProfileLang();
  const [nickname, setNickname] = React.useState(profile?.nickname || '');
  const [telegram, setTelegram] = React.useState(profile?.telegram || '');
  // 从 social_links 中提取 X 链接
  const initLinks = profile?.social_links || [];
  const xEntry = initLinks.find(l => l.key === 'x');
  const [xUrl, setXUrl] = React.useState(xEntry?.url || '');
  const [links, setLinks] = React.useState(initLinks.filter(l => l.key !== 'x'));
  const [avatarUrl, setAvatarUrl] = React.useState(profile?.avatar_url || '');
  const [uploading, setUploading] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState(false);
  const [error, setError] = React.useState('');
  const [toastMsg, setToastMsg] = React.useState('');

  const handleUpload = async (file) => {
    const url = await ProfileDB.uploadAvatar(user.id, file);
    setAvatarUrl(url);
    return url;
  };

  const handleSave = async (e) => {
    e.preventDefault();
    if (saving || uploading) return;
    setSaving(true);
    setError('');
    try {
      // 过滤掉 url 为空的行（无论是否填写了平台名）
      const cleanLinks = links.filter(l => l.url.trim());
      // 将 X 链接合并
      const allLinks = xUrl.trim()
        ? [{ key: 'x', platform: 'X (Twitter)', url: xUrl.trim() }, ...cleanLinks]
        : cleanLinks;
      await ProfileDB.saveProfile(user.id, {
        nickname: nickname.trim() || user.email.split('@')[0],
        telegram: telegram.trim(),
        avatar_url: avatarUrl,
        social_links: allLinks,
      });
      setSaved(true);
      setToastMsg(t.profileSaved);
      const updated = { nickname: nickname.trim() || user.email.split('@')[0], telegram: telegram.trim(), avatar_url: avatarUrl, social_links: allLinks };
      onSaved(updated);
      window.dispatchEvent(new CustomEvent('kiwvo:profile-updated', { detail: updated }));
      setTimeout(() => { setSaved(false); setToastMsg(''); }, 3000);
    } catch (err) {
      const msg = (err.message || '').toLowerCase();
      const localMsg = msg.includes('security policy') || msg.includes('permission') ? t.rlsError
        : t.saveFail + err.message;
      setError(localMsg);
    } finally {
      setSaving(false);
    }
  };

  return (
    <>
    <form onSubmit={handleSave} className="space-y-6 max-w-[560px]">
      {/* 头像 */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-3">{t.avatar}</label>
        <AvatarUpload
          avatarUrl={avatarUrl}
          onUploaded={handleUpload}
          uploading={uploading}
          setUploading={setUploading}
          t={t}
        />
      </div>

      {/* 昵称 */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-1.5">{t.nickname}</label>
        <input
          value={nickname}
          onChange={e => setNickname(e.target.value)}
          maxLength={32}
          placeholder={user.email.split('@')[0]}
          className="w-full h-10 rounded-lg bg-[#0A1512] border border-white/[0.08] focus:border-emerald-400/40 focus:shadow-[0_0_0_3px_rgba(16,185,129,0.1)] text-[14px] text-white placeholder:text-white/25 px-3 outline-none transition-all"
        />
        <p className="text-[11px] text-white/30 mt-1">{nickname.length} / 32</p>
      </div>

      {/* 邮箱 (只读) */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-1.5">{t.email}</label>
        <div className="flex items-center h-10 rounded-lg bg-white/[0.02] border border-white/[0.05] px-3 text-[14px] text-white/50">
          {user.email}
          <span className="ml-auto text-[10.5px] font-mono text-white/25 bg-white/[0.04] px-2 py-0.5 rounded">{t.verified}</span>
        </div>
      </div>

      {/* TG */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-1.5">{t.telegram}</label>
        <div className="flex items-center gap-2 h-10 rounded-lg bg-[#0A1512] border border-white/[0.08] focus-within:border-emerald-400/40 focus-within:shadow-[0_0_0_3px_rgba(16,185,129,0.1)] px-3 transition-all">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" className="text-white/30 shrink-0">
            <path d="M21.5 3.5L2.6 11.2c-1 .4-1 1.4 0 1.7l4.7 1.5 1.8 5.7c.2.7.6.9 1.2.5l2.7-2.1 4.6 3.4c.9.5 1.5.2 1.7-.8l3.1-14.7c.3-1.4-.5-2-1.9-1.4z"/>
          </svg>
          <input
            value={telegram}
            onChange={e => setTelegram(e.target.value)}
            placeholder="@yourusername"
            className="flex-1 bg-transparent outline-none text-[14px] text-white placeholder:text-white/25"
          />
        </div>
      </div>

      {/* X (Twitter) */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-1.5">{t.xProfile}</label>
        <div className="flex items-center gap-2 h-10 rounded-lg bg-[#0A1512] border border-white/[0.08] focus-within:border-emerald-400/40 focus-within:shadow-[0_0_0_3px_rgba(16,185,129,0.1)] px-3 transition-all">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" className="text-white/30 shrink-0">
            <path d="M18.244 2H21l-6.55 7.49L22 22h-6.79l-4.74-6.2L4.96 22H2.2l7.02-8.02L2 2h6.96l4.28 5.66L18.244 2zm-1.18 18h1.86L7.06 4H5.1l11.964 16z"/>
          </svg>
          <input
            value={xUrl}
            onChange={e => setXUrl(e.target.value)}
            placeholder={t.xPlaceholder}
            className="flex-1 bg-transparent outline-none text-[14px] text-white placeholder:text-white/25"
          />
        </div>
      </div>

      {/* 社交平台链接 */}
      <div>
        <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-2">{t.socialLabel}</label>
        <SocialLinksEditor links={links} onChange={setLinks} t={t} />
      </div>

      {error && (
        <div className="flex items-start gap-2 p-3 rounded-lg bg-rose-500/10 border border-rose-400/30 text-[12.5px] text-rose-300">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" className="shrink-0 mt-0.5">
            <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="1.6"/>
            <path d="M12 8v4M12 16h.01" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
          </svg>
          <span className="break-all">{error}</span>
        </div>
      )}

      <button
        type="submit"
        disabled={saving || uploading}
        className={`h-10 px-6 rounded-lg text-[13px] font-semibold transition-all inline-flex items-center gap-2 ${
          saved
            ? 'bg-emerald-500/20 text-emerald-300 border border-emerald-400/30'
            : saving || uploading
            ? 'bg-white/[0.04] text-white/30 cursor-not-allowed'
            : 'bg-emerald-500 hover:bg-emerald-400 text-[#052E21] shadow-[0_4px_20px_-4px_rgba(16,185,129,0.5)]'
        }`}
      >
        {saving ? (
          <>
            <svg className="animate-spin" width="14" height="14" viewBox="0 0 24 24" fill="none">
              <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" opacity="0.25"/>
              <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
            </svg>
            {t.saving}
          </>
        ) : saved ? (
          <>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
              <path d="M5 12.5l4.5 4.5L19 7.5" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            {t.saved}
          </>
        ) : t.saveBtn}
      </button>

    </form>

    {toastMsg && ReactDOM.createPortal(
      <div className="fixed top-6 left-1/2 -translate-x-1/2 z-[400] animate-[fadeIn_0.2s_ease]">
        <div className="flex items-center gap-2 px-5 py-3 rounded-xl bg-emerald-500/15 border border-emerald-400/30 shadow-[0_8px_32px_-8px_rgba(16,185,129,0.3)]">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
            <path d="M5 12.5l4.5 4.5L19 7.5" stroke="#6EE7B7" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
          <span className="text-[13px] text-emerald-200 font-medium">{toastMsg}</span>
        </div>
      </div>,
      document.body
    )}
    </>
  );
}

// ── 我的内容 Tab ──────────────────────────────────────────────────
function ContentTab({ user }) {
  const [tab, setTab] = React.useState('questions');
  const [questions, setQuestions] = React.useState([]);
  const [qVotes, setQVotes] = React.useState([]);
  const [fVotes, setFVotes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    setLoading(true);
    Promise.all([
      ProfileDB.getMyQuestions(user.id),
      ProfileDB.getMyVotes(user.id),
      ProfileDB.getMyFeatureVotes(user.id),
    ]).then(([q, qv, fv]) => {
      setQuestions(q);
      setQVotes(qv);
      setFVotes(fv);
    }).catch(console.error).finally(() => setLoading(false));
  }, [user.id]);

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <svg className="animate-spin text-emerald-400/60" width="24" height="24" viewBox="0 0 24 24" fill="none">
          <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" opacity="0.25"/>
          <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
        </svg>
      </div>
    );
  }

  const subtabs = [
    { id: 'questions', label: '我的提问', count: questions.length },
    { id: 'qvotes',    label: '顶过的问题', count: qVotes.length },
    { id: 'fvotes',    label: '投票的功能', count: fVotes.length },
  ];

  const EmptyState = ({ text }) => (
    <div className="flex flex-col items-center py-16 text-center">
      <div className="w-12 h-12 rounded-full bg-white/[0.03] border border-white/[0.06] flex items-center justify-center mb-3">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" className="text-white/20">
          <rect x="3" y="3" width="18" height="18" rx="3" stroke="currentColor" strokeWidth="1.4"/>
          <path d="M8 12h8M12 8v8" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
        </svg>
      </div>
      <p className="text-[13px] text-white/35">{text}</p>
    </div>
  );

  return (
    <div>
      <div className="flex items-center gap-0.5 p-1 rounded-lg bg-white/[0.03] border border-white/[0.05] inline-flex mb-5">
        {subtabs.map(t => (
          <button
            key={t.id}
            onClick={() => setTab(t.id)}
            className={`h-7 px-3 rounded-md text-[12.5px] font-medium transition-colors ${
              tab === t.id ? 'bg-[#0A1512] text-white shadow-[inset_0_0_0_1px_rgba(16,185,129,0.2)]' : 'text-white/40 hover:text-white/70'
            }`}
          >
            {t.label}
            <span className={`ml-1.5 text-[10.5px] font-mono ${tab === t.id ? 'text-emerald-300/80' : 'text-white/25'}`}>{t.count}</span>
          </button>
        ))}
      </div>

      {tab === 'questions' && (
        questions.length === 0 ? <EmptyState text="还没有发布过问题" /> : (
          <div className="space-y-2">
            {questions.map(q => (
              <div key={q.id} className="flex items-center gap-3 p-3.5 rounded-xl bg-[#0F1E1A] border border-white/[0.04]">
                <span className={`shrink-0 text-[10px] font-mono px-1.5 py-0.5 rounded ${q.solved ? 'bg-emerald-400/10 text-emerald-300' : 'bg-white/[0.05] text-white/40'}`}>
                  {q.solved ? '已解决' : q.tag}
                </span>
                <span className="flex-1 text-[13.5px] text-white/85 truncate">{q.title}</span>
                <span className="shrink-0 text-[11px] text-white/30 font-mono">{timeAgoP(q.created_at)}</span>
              </div>
            ))}
          </div>
        )
      )}

      {tab === 'qvotes' && (
        qVotes.length === 0 ? <EmptyState text="还没有为任何问题投票" /> : (
          <div className="space-y-2">
            {qVotes.map(q => (
              <div key={q.id} className="flex items-center gap-3 p-3.5 rounded-xl bg-[#0F1E1A] border border-white/[0.04]">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="#6EE7B7" className="shrink-0">
                  <path d="M12 5l7 8h-4v6h-6v-6H5l7-8z"/>
                </svg>
                <span className="shrink-0 text-[10px] font-mono px-1.5 py-0.5 rounded bg-white/[0.05] text-white/40">{q.tag}</span>
                <span className="flex-1 text-[13.5px] text-white/85 truncate">{q.title}</span>
              </div>
            ))}
          </div>
        )
      )}

      {tab === 'fvotes' && (
        fVotes.length === 0 ? <EmptyState text="还没有为任何功能投票" /> : (
          <div className="space-y-2">
            {fVotes.map(f => (
              <div key={f.id} className="flex items-center gap-3 p-3.5 rounded-xl bg-[#0F1E1A] border border-white/[0.04]">
                <svg width="13" height="13" viewBox="0 0 24 24" fill="#6EE7B7" className="shrink-0">
                  <path d="M12 5l7 8h-4v6h-6v-6H5l7-8z"/>
                </svg>
                <span className="flex-1 text-[13.5px] text-white/85 truncate">{f.title}</span>
              </div>
            ))}
          </div>
        )
      )}
    </div>
  );
}

// ── 只读 Profile 查看 ─────────────────────────────────────────────
function ReadOnlyProfile({ profile, displayName }) {
  const avatarUrl = profile?.avatar_url || '';
  const telegram = profile?.telegram || '';
  const socialLinks = profile?.social_links || [];
  const hue = (displayName.charCodeAt(0) || 65) % 60 + 140;

  return (
    <div className="space-y-6 max-w-[560px]">
      <div className="flex items-center gap-5">
        <div className="w-[72px] h-[72px] rounded-full overflow-hidden flex items-center justify-center text-[24px] font-semibold text-emerald-100 shrink-0 border-2 border-emerald-400/20"
          style={{ background: avatarUrl ? 'transparent' : `oklch(0.32 0.08 ${hue})` }}>
          {avatarUrl ? <img src={avatarUrl} alt="" className="w-full h-full object-cover" /> : displayName.charAt(0).toUpperCase()}
        </div>
        <div>
          <div className="text-[18px] text-white font-semibold">{displayName}</div>
        </div>
      </div>
      {telegram && (
        <div>
          <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-1.5">Telegram</label>
          <div className="text-[14px] text-white/70">{telegram}</div>
        </div>
      )}
      {socialLinks.length > 0 && (
        <div>
          <label className="block text-[11px] text-white/40 font-mono tracking-[0.14em] uppercase mb-2">Social</label>
          <div className="space-y-2">
            {socialLinks.filter(l => l.url).map((l, i) => (
              <a key={i} href={l.url} target="_blank" rel="noreferrer" className="block text-[13px] text-emerald-300 hover:text-emerald-200 truncate transition-colors">
                {l.platform || l.url}
              </a>
            ))}
          </div>
        </div>
      )}
      {!telegram && socialLinks.length === 0 && (
        <p className="text-[13px] text-white/30">该用户暂未填写个人信息</p>
      )}
    </div>
  );
}

// ── 主组件 ────────────────────────────────────────────────────────
function ProfileModal({ user, targetUserId, onClose }) {
  const viewId = targetUserId || user.id;
  const isOwn = !targetUserId || targetUserId === user.id;
  const [tab, setTab] = React.useState('info');
  const [profile, setProfile] = React.useState(null);
  const [profileLoading, setProfileLoading] = React.useState(true);

  React.useEffect(() => {
    if (!viewId) { setProfileLoading(false); return; }
    ProfileDB.getProfile(viewId)
      .then(p => setProfile(p))
      .catch(console.error)
      .finally(() => setProfileLoading(false));
  }, [viewId]);

  // ESC 关闭
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);

  // 阻止滚动
  React.useEffect(() => {
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = ''; };
  }, []);

  const email = isOwn ? (user.email || '') : (profile?.email || '');
  const displayName = profile?.nickname || (email ? email.split('@')[0] : '用户');
  const hue = (displayName.charCodeAt(0) || 65) % 60 + 140;

  const tabs = [
    { id: 'info',    label: '个人信息', icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <circle cx="12" cy="8" r="4" stroke="currentColor" strokeWidth="1.6"/>
        <path d="M4 20c0-4 3.6-7 8-7s8 3 8 7" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
      </svg>
    )},
    { id: 'content', label: '我的内容', icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <rect x="3" y="3" width="18" height="18" rx="2" stroke="currentColor" strokeWidth="1.6"/>
        <path d="M7 8h10M7 12h7M7 16h5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
      </svg>
    )},
  ];

  return (
    <div
      className="fixed inset-0 z-[200] flex items-stretch"
      style={{ background: 'rgba(5,18,15,0.7)', backdropFilter: 'blur(8px)' }}
      onClick={onClose}
    >
      {/* 侧边抽屉 */}
      <div
        className="ml-auto w-full max-w-[720px] h-full bg-[#0A1512] border-l border-white/[0.06] flex flex-col animate-[slideInRight_0.22s_cubic-bezier(0.22,1,0.36,1)]"
        onClick={e => e.stopPropagation()}
      >
        {/* 头部 */}
        <div className="flex items-center justify-between px-8 h-[68px] border-b border-white/[0.06] shrink-0">
          <div className="flex items-center gap-3">
            <div
              className="w-9 h-9 rounded-full overflow-hidden flex items-center justify-center text-[14px] font-semibold text-emerald-100 shrink-0"
              style={{ background: profile?.avatar_url ? 'transparent' : `oklch(0.32 0.08 ${hue})` }}
            >
              {profile?.avatar_url
                ? <img src={profile.avatar_url} alt="" className="w-full h-full object-cover" />
                : displayName.charAt(0).toUpperCase()
              }
            </div>
            <div>
              <div className="text-[15px] text-white font-semibold leading-tight">{displayName}</div>
              <div className="text-[11.5px] text-white/40 font-mono">{email}</div>
            </div>
          </div>
          <button
            onClick={onClose}
            className="w-9 h-9 rounded-lg border border-white/[0.07] text-white/40 hover:text-white hover:border-white/20 flex items-center justify-center transition-all"
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
              <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
            </svg>
          </button>
        </div>

        {/* Tab 导航 */}
        <div className="flex items-center gap-0.5 px-8 h-12 border-b border-white/[0.05] shrink-0">
          {tabs.map(t => (
            <button
              key={t.id}
              onClick={() => setTab(t.id)}
              className={`flex items-center gap-2 h-8 px-3.5 rounded-lg text-[13px] font-medium transition-colors ${
                tab === t.id
                  ? 'bg-emerald-400/10 text-emerald-300 border border-emerald-400/20'
                  : 'text-white/45 hover:text-white/80 hover:bg-white/[0.03]'
              }`}
            >
              {t.icon}
              {t.label}
            </button>
          ))}
        </div>

        {/* 内容区 */}
        <div className="flex-1 overflow-y-auto px-8 py-8 no-scrollbar">
          {profileLoading ? (
            <div className="flex items-center justify-center py-20">
              <svg className="animate-spin text-emerald-400/60" width="24" height="24" viewBox="0 0 24 24" fill="none">
                <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="2.5" opacity="0.25"/>
                <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/>
              </svg>
            </div>
          ) : tab === 'info' ? (
            isOwn ? (
              <InfoTab
                user={user}
                profile={profile}
                onSaved={(updates) => setProfile(prev => ({ ...prev, ...updates }))}
              />
            ) : (
              <ReadOnlyProfile profile={profile} displayName={displayName} />
            )
          ) : (
            <ContentTab user={isOwn ? user : { id: viewId }} />
          )}
        </div>
      </div>
    </div>
  );
}

window.ProfileModal = ProfileModal;
