import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import * as forumApi from '../api/forum.js';
import { me } from '../api/auth.js';
import { getToken } from '../api/client.js';
import { uploadFile } from '../api/upload.js';
import { required as captchaRequired, applyCaptchaResult } from '../api/captcha.js';
import { showCaptcha } from '../components/CaptchaModal.jsx';
import { showSnackbar, useDialog } from '../lib/utils.js';

/** 板块的子分类列表 */
function subCatsOf(cat) {
  if (!cat || !cat.sub_categories) return [];
  return cat.sub_categories.split(',').filter(Boolean).map((t) => t.trim());
}

/** 论坛首页：分类导航（侧栏 + 子分类 chips 筛选）+ 帖子列表 + 发帖弹窗（含验证码） */
export default function Forum() {
  const navigate = useNavigate();
  const [categories, setCategories] = useState([]);
  const [currentCatId, setCurrentCatId] = useState(null); // null=全部最新
  const [filterSub, setFilterSub] = useState('');
  const [posts, setPosts] = useState(null); // null=加载中
  const [loadError, setLoadError] = useState('');
  const [user, setUser] = useState(null);

  // 发帖弹窗状态
  const [showNewPost, setShowNewPost] = useState(false);
  const [npCategory, setNpCategory] = useState('');
  const [npSub, setNpSub] = useState('');
  const [npTitle, setNpTitle] = useState('');
  const [npContent, setNpContent] = useState('');
  const [npStatus, setNpStatus] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const fileRef = useRef(null);

  const load = useCallback(async (catId, sub) => {
    setPosts(null);
    setLoadError('');
    try {
      const ps = catId ? await forumApi.listPosts(catId) : await forumApi.listPosts();
      const filtered = sub ? (ps || []).filter((p) => p.sub_category === sub) : (ps || []);
      setPosts(filtered);
    } catch (e) {
      setLoadError(e.message || '加载失败');
      setPosts([]);
    }
  }, []);

  useEffect(() => {
    forumApi.listCategories().then((cs) => setCategories(cs || [])).catch(() => {});
    if (getToken()) me().then(setUser).catch(() => setUser(null));
    else setUser(null);
    load(null, '');
  }, [load]);

  const selectCategory = (catId) => {
    setCurrentCatId(catId);
    setFilterSub('');
    load(catId, '');
  };

  const showAllPosts = () => {
    setCurrentCatId(null);
    setFilterSub('');
    load(null, '');
  };

  // 发帖按钮：未登录显示"登录发帖"并跳登录页（照 forum.js）
  const handleNewPostBtn = () => {
    if (user) {
      setNpCategory(categories.length ? String(categories[0].id) : '');
      setNpSub('');
      setNpTitle('');
      setNpContent('');
      setNpStatus('');
      setShowNewPost(true);
    } else {
      navigate('/login.html');
    }
  };

  const handleCategoryChange = (e) => {
    setNpCategory(e.target.value);
    setNpSub(''); // 切换板块后重置子分类
  };

  const doUpload = async (file) => {
    try {
      const data = await uploadFile(file);
      setNpContent((c) => c + '\n' + data.tag + '\n');
      setNpStatus('已插入: ' + data.tag);
    } catch (e) {
      showSnackbar(e.message);
    }
  };

  const handleFileSelect = (e) => {
    const f = e.target.files && e.target.files[0];
    if (f) doUpload(f);
    e.target.value = '';
  };

  const submitPost = async () => {
    if (!npTitle.trim() || !npContent.trim()) { showSnackbar('标题和内容不能为空'); return; }
    setSubmitting(true);
    try {
      const base = {
        category_id: parseInt(npCategory, 10),
        title: npTitle.trim(),
        content: npContent.trim(),
        sub_category: npSub,
        use_markdown: 1,
      };
      // 验证码：captcha_forum 开启时走 showCaptcha 拿 proof / 第三方 token
      const cap = await captchaRequired('forum');
      if (cap && cap.required) {
        const result = await showCaptcha('forum');
        if (result === null) { setSubmitting(false); return; } // 取消
        applyCaptchaResult(base, result);
      }
      await forumApi.createPost(base);
      showSnackbar('发布成功');
      setShowNewPost(false);
      if (currentCatId) selectCategory(currentCatId);
      else showAllPosts();
    } catch (e) {
      showSnackbar(e.message);
    }
    setSubmitting(false);
  };

  const currentCat = categories.find((c) => c.id === currentCatId);
  const subCats = subCatsOf(currentCat);

  // 发帖弹窗焦点管理（B3）：Esc 关闭、聚焦首个输入、关闭后焦点还给触发按钮
  const { dialogRef: npDialogRef, onKeyDown: npDialogKey } = useDialog(showNewPost, () => setShowNewPost(false));

  return (
    <div className="forum-layout">
      <h1 className="sr-only">论坛</h1>
      <aside className="forum-sidebar">
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <span style={{ fontWeight: 600, fontSize: 16 }}>板块</span>
          <button className="btn btn-filled btn-sm" onClick={handleNewPostBtn}>
            {user ? '发帖' : '登录发帖'}
          </button>
        </div>
        <div className="forum-cat-list">
          {categories.map((c) => (
            <button
              type="button"
              key={c.id}
              className={'forum-cat-item' + (c.id === currentCatId ? ' active' : '')}
              onClick={() => selectCategory(c.id)}
            >
              <span className="material-icons" style={{ fontSize: 18 }}>forum</span> {c.name}
              {c.announcement ? (
                <span className="material-icons" style={{ fontSize: 14, color: 'var(--md-ref-primary)' }}>campaign</span>
              ) : null}
            </button>
          ))}
        </div>
        <hr style={{ border: 'none', borderTop: '1px solid var(--md-ref-outline-variant)', margin: '12px 0' }} />
        <button
          type="button"
          className={'forum-cat-item' + (currentCatId === null ? ' active' : '')}
          onClick={showAllPosts}
          style={{ fontWeight: 500 }}
        >
          <span className="material-icons" style={{ fontSize: 18 }}>dynamic_feed</span> 全部最新
        </button>
      </aside>

      <div className="forum-content">
        {currentCat && (
          <div style={{ marginBottom: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
              <h3 style={{ fontWeight: 600, fontSize: 20, margin: 0 }}>{currentCat.name}</h3>
              <span className="chip chip-static">板块</span>
            </div>
            <p className="text-muted" style={{ fontSize: 14 }}>{currentCat.description || ''}</p>
            {currentCat.announcement && (
              <div className="announcement-bar">
                <span className="material-icons ann-icon">campaign</span>
                <span className="ann-content">{currentCat.announcement}</span>
              </div>
            )}
            {subCats.length > 0 && (
              <div className="chips" style={{ marginBottom: 12, marginTop: 12 }}>
                <button type="button" className={'chip' + (!filterSub ? ' active' : '')} onClick={() => { setFilterSub(''); load(currentCatId, ''); }}>全部</button>
                {subCats.map((s) => (
                  <button type="button" key={s} className={'chip' + (filterSub === s ? ' active' : '')} onClick={() => { setFilterSub(s); load(currentCatId, s); }}>{s}</button>
                ))}
              </div>
            )}
          </div>
        )}

        {posts === null && !loadError && <div className="loading"><div className="spinner"></div></div>}
        {loadError && <div className="empty-state"><div className="empty-icon">⚠️</div><p>加载失败</p></div>}
        {posts !== null && !loadError && posts.length === 0 && (
          <div className="empty-state"><div className="empty-icon">📝</div><p>暂无帖子</p></div>
        )}
        {posts && posts.length > 0 && (
          <div className="forum-post-list">
            {posts.map((p) => {
              const catName = categories.find((c) => c.id === p.category_id)?.name || '';
              return (
                <Link key={p.id} to={`/forum/${p.id}`} className="card forum-post-card" style={{ textDecoration: 'none', display: 'block' }}>
                  <div className="post-title">{p.title}</div>
                  <div className="post-meta" style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <span>{p.author_name || '匿名'}</span>
                    <span>{p.created_at}</span>
                    <span>{p.reply_count || 0} 回复</span>
                    <span style={{ color: 'var(--md-ref-outline)', margin: '0 4px' }}>|</span>
                    <span className="chip chip-static">{catName}</span>
                    {p.sub_category ? (
                      <span className="chip chip-tonal">{p.sub_category}</span>
                    ) : null}
                  </div>
                </Link>
              );
            })}
          </div>
        )}
      </div>

      {/* 发帖弹窗 */}
      {showNewPost && (
        <div
          ref={npDialogRef}
          className="dialog-overlay active"
          role="dialog"
          aria-modal="true"
          aria-label="发布新帖"
          style={{ display: 'flex', zIndex: 9999 }}
          onMouseDown={(e) => { if (e.target === e.currentTarget) setShowNewPost(false); }}
          onKeyDown={npDialogKey}
        >
          <div className="dialog">
            <h3>发布新帖</h3>
            <div className="form-group">
              <label>板块</label>
              <select value={npCategory} onChange={handleCategoryChange}>
                {categories.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </div>
            <div className="form-group">
              <label>帖子分类（可选）</label>
              <select value={npSub} onChange={(e) => setNpSub(e.target.value)}>
                <option value="">无</option>
                {subCatsOf(categories.find((c) => c.id === parseInt(npCategory, 10))).map((s) => (
                  <option key={s} value={s}>{s}</option>
                ))}
              </select>
            </div>
            <div className="form-group">
              <label>标题 *</label>
              <input type="text" value={npTitle} onChange={(e) => setNpTitle(e.target.value)} />
            </div>
            <div className="form-group">
              <label>内容 *</label>
              <textarea value={npContent} onChange={(e) => setNpContent(e.target.value)} style={{ minHeight: 150, fontFamily: 'monospace' }} />
            </div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 12 }}>
              <button className="btn btn-tonal btn-sm" onClick={() => fileRef.current && fileRef.current.click()}>
                <span className="material-icons">upload</span> 上传附件
              </button>
              <input ref={fileRef} type="file" style={{ display: 'none' }} onChange={handleFileSelect} />
              <span className="text-muted" style={{ fontSize: 13 }}>{npStatus}</span>
            </div>
            <div className="actions">
              <button className="btn btn-text" onClick={() => setShowNewPost(false)}>取消</button>
              <button className="btn btn-filled" onClick={submitPost} disabled={submitting}>发布</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
