// スレッド詳細ページ（返信・いいね）
function ThreadPage({ nav, progress, threadPostId, boardId }) {
  const [post, setPost] = React.useState(null);
  const [replies, setReplies] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);

  // ニックネームモーダル
  const [nickModal, setNickModal] = React.useState(false);
  const [nickInput, setNickInput] = React.useState('');
  const [nickSaving, setNickSaving] = React.useState(false);
  const [nickError, setNickError] = React.useState('');
  const [displayName, setDisplayName] = React.useState(null);
  const [pendingAction, setPendingAction] = React.useState(null); // 'reply'

  // 返信フォーム
  const [replyBody, setReplyBody] = React.useState('');
  const [replyImageFile, setReplyImageFile] = React.useState(null);
  const [replyImagePreview, setReplyImagePreview] = React.useState(null);
  const [uploading, setUploading] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [formError, setFormError] = React.useState('');

  // 削除確認
  const [deleteConfirm, setDeleteConfirm] = React.useState(false);
  const [deleting, setDeleting] = React.useState(false);

  // ライトボックス
  const [lightboxUrl, setLightboxUrl] = React.useState(null);

  const repliesEndRef = React.useRef(null);

  React.useEffect(function() {
    if (!threadPostId) return;
    setLoading(true);
    fetch('/api/board/post/' + threadPostId)
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) { setError(data.error); return; }
        setPost(data.post);
        setReplies(data.replies);
      })
      .catch(function() { setError('読み込みに失敗しました'); })
      .finally(function() { setLoading(false); });

    fetch('/api/board/profile')
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.profile && data.profile.display_name) setDisplayName(data.profile.display_name);
      })
      .catch(function() {});
  }, [threadPostId]);

  function relativeTime(dateStr) {
    var d = new Date(dateStr);
    var now = new Date();
    var diff = Math.floor((now - d) / 1000);
    if (diff < 60) return 'たった今';
    if (diff < 3600) return Math.floor(diff / 60) + '分前';
    if (diff < 86400) return Math.floor(diff / 3600) + '時間前';
    var yesterday = new Date(now);
    yesterday.setDate(yesterday.getDate() - 1);
    if (
      d.getFullYear() === yesterday.getFullYear() &&
      d.getMonth() === yesterday.getMonth() &&
      d.getDate() === yesterday.getDate()
    ) return '昨日';
    return (d.getMonth() + 1) + '/' + d.getDate();
  }

  // いいねトグル（楽観的UI更新）
  function togglePostLike() {
    if (!post) return;
    var wasLiked = post.liked;
    var newCount = wasLiked ? Math.max(0, post.like_count - 1) : post.like_count + 1;
    setPost(function(p) { return { ...p, liked: !wasLiked, like_count: newCount }; });

    fetch('/api/board/like', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ postId: post.id }),
    })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) {
          // ロールバック
          setPost(function(p) { return { ...p, liked: wasLiked, like_count: wasLiked ? newCount + 1 : newCount - 1 }; });
        }
      })
      .catch(function() {
        setPost(function(p) { return { ...p, liked: wasLiked, like_count: wasLiked ? newCount + 1 : newCount - 1 }; });
      });
  }

  function toggleReplyLike(replyId) {
    var reply = replies.find(function(r) { return r.id === replyId; });
    if (!reply) return;
    var wasLiked = reply.liked;
    var newCount = wasLiked ? Math.max(0, reply.like_count - 1) : reply.like_count + 1;

    setReplies(function(prev) {
      return prev.map(function(r) {
        return r.id === replyId ? { ...r, liked: !wasLiked, like_count: newCount } : r;
      });
    });

    fetch('/api/board/like', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ replyId: replyId }),
    })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) {
          setReplies(function(prev) {
            return prev.map(function(r) {
              return r.id === replyId ? { ...r, liked: wasLiked, like_count: wasLiked ? newCount + 1 : newCount - 1 } : r;
            });
          });
        }
      })
      .catch(function() {
        setReplies(function(prev) {
          return prev.map(function(r) {
            return r.id === replyId ? { ...r, liked: wasLiked, like_count: wasLiked ? newCount + 1 : newCount - 1 } : r;
          });
        });
      });
  }

  function handleReplyImageChange(e) {
    var file = e.target.files && e.target.files[0];
    if (!file) return;
    setReplyImageFile(file);
    setReplyImagePreview(URL.createObjectURL(file));
  }

  function clearReplyImage() {
    setReplyImageFile(null);
    if (replyImagePreview) URL.revokeObjectURL(replyImagePreview);
    setReplyImagePreview(null);
  }

  function uploadImage(file) {
    var fd = new FormData();
    fd.append('image', file);
    setUploading(true);
    return fetch('/api/board/upload-image', { method: 'POST', body: fd })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) throw new Error(data.error);
        return data.url;
      })
      .finally(function() { setUploading(false); });
  }

  function handleReplySubmit() {
    if (!displayName) {
      setPendingAction('reply');
      setNickModal(true);
      return;
    }
    doSubmitReply();
  }

  function doSubmitReply() {
    var bodyText = replyBody.trim();
    if (!bodyText) { setFormError('本文を入力してください'); return; }
    setFormError('');
    setSubmitting(true);

    // 楽観的UI更新: 暫定返信をすぐに追加
    var tempId = 'temp-' + Date.now();
    var tempReply = {
      id: tempId,
      post_id: threadPostId,
      user_id: '__temp__',
      body: bodyText,
      image_url: replyImagePreview || null,
      like_count: 0,
      liked: false,
      is_own: true,
      display_name: displayName || '匿名',
      created_at: new Date().toISOString(),
      _sending: true,
    };
    setReplies(function(prev) { return [...prev, tempReply]; });
    setReplyBody('');

    var doPost = function(imageUrl) {
      fetch('/api/board/post/' + threadPostId + '/reply', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ body: bodyText, imageUrl: imageUrl || null }),
      })
        .then(function(r) { return r.json(); })
        .then(function(data) {
          if (data.error) {
            // 楽観的更新をロールバック
            setReplies(function(prev) { return prev.filter(function(r) { return r.id !== tempId; }); });
            setReplyBody(bodyText);
            setFormError(data.error);
            return;
          }
          // 暫定返信を実データに置き換え
          setReplies(function(prev) {
            return prev.map(function(r) { return r.id === tempId ? data.reply : r; });
          });
          setPost(function(p) { return p ? { ...p, reply_count: (p.reply_count || 0) + 1 } : p; });
          clearReplyImage();
          // 最新返信にスクロール
          setTimeout(function() {
            if (repliesEndRef.current) repliesEndRef.current.scrollIntoView({ behavior: 'smooth' });
          }, 100);
        })
        .catch(function() {
          setReplies(function(prev) { return prev.filter(function(r) { return r.id !== tempId; }); });
          setReplyBody(bodyText);
          setFormError('返信の投稿に失敗しました');
        })
        .finally(function() { setSubmitting(false); });
    };

    if (replyImageFile) {
      uploadImage(replyImageFile)
        .then(function(url) { doPost(url); })
        .catch(function(e) {
          setReplies(function(prev) { return prev.filter(function(r) { return r.id !== tempId; }); });
          setReplyBody(bodyText);
          setFormError(e.message || '画像のアップロードに失敗しました');
          setSubmitting(false);
        });
    } else {
      doPost(null);
    }
  }

  function saveNickname() {
    var name = nickInput.trim();
    if (name.length < 2 || name.length > 12) {
      setNickError('2〜12文字で入力してください');
      return;
    }
    setNickSaving(true);
    setNickError('');
    fetch('/api/board/profile', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ displayName: name }),
    })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) { setNickError(data.error); return; }
        setDisplayName(data.profile.display_name);
        setNickModal(false);
        setNickInput('');
        setNickError('');
        if (pendingAction === 'reply') {
          setPendingAction(null);
          doSubmitReply();
        }
      })
      .catch(function() { setNickError('保存に失敗しました'); })
      .finally(function() { setNickSaving(false); });
  }

  function handleDelete() {
    setDeleting(true);
    fetch('/api/board/post/' + threadPostId, { method: 'DELETE' })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.error) { alert(data.error); return; }
        nav.goBoard(boardId || (post && post.board_id));
      })
      .catch(function() { alert('削除に失敗しました'); })
      .finally(function() { setDeleting(false); setDeleteConfirm(false); });
  }

  // ── スタイル定数 ──
  var cardBase = {
    background: '#fff',
    border: '1px solid #e8e4dc',
    borderRadius: 12,
    padding: '14px 16px',
    marginBottom: 10,
  };

  var likeBtn = function(liked) {
    return {
      background: 'none',
      border: '1px solid ' + (liked ? '#e74c3c' : '#ddd'),
      borderRadius: 20,
      padding: '4px 12px',
      fontSize: 13,
      color: liked ? '#e74c3c' : '#999',
      cursor: 'pointer',
      display: 'inline-flex',
      alignItems: 'center',
      gap: 4,
      transition: 'all 0.15s',
    };
  };

  return (
    <main className="main-content" style={{ maxWidth: 680, margin: '0 auto', padding: '24px 16px 160px' }}>

      {/* ニックネームモーダル */}
      {nickModal && (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
          <div style={{ background: '#fff', borderRadius: 16, padding: 24, width: '100%', maxWidth: 360 }}>
            <h2 style={{ fontSize: 18, fontWeight: 700, color: '#13294B', marginBottom: 8 }}>ニックネームを設定</h2>
            <p style={{ fontSize: 13, color: '#666', marginBottom: 16, lineHeight: 1.6 }}>掲示板に表示される名前です。あとから変更できます。</p>
            <input
              type="text"
              placeholder="例: 株初心者たろう"
              value={nickInput}
              onChange={function(e) { setNickInput(e.target.value); }}
              maxLength={12}
              style={{ width: '100%', padding: '10px 12px', border: '1px solid #ddd', borderRadius: 8, fontSize: 15, boxSizing: 'border-box', marginBottom: 8 }}
            />
            <div style={{ fontSize: 11, color: '#999', marginBottom: 12 }}>{nickInput.length}/12文字</div>
            {nickError && <div style={{ color: '#c0392b', fontSize: 13, marginBottom: 10 }}>{nickError}</div>}
            <div style={{ display: 'flex', gap: 10 }}>
              <button
                onClick={function() { setNickModal(false); setNickInput(''); setNickError(''); setPendingAction(null); }}
                style={{ flex: 1, padding: '10px 0', background: '#f5f2eb', border: 'none', borderRadius: 8, fontWeight: 600, cursor: 'pointer', fontSize: 14 }}
              >キャンセル</button>
              <button
                onClick={saveNickname}
                disabled={nickSaving}
                style={{ flex: 2, padding: '10px 0', background: '#13294B', color: '#fff', border: 'none', borderRadius: 8, fontWeight: 700, cursor: 'pointer', fontSize: 14, opacity: nickSaving ? 0.7 : 1 }}
              >{nickSaving ? '保存中...' : '決定'}</button>
            </div>
          </div>
        </div>
      )}

      {/* ライトボックス */}
      {lightboxUrl && (
        <div
          style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.85)', zIndex: 300, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'zoom-out' }}
          onClick={function() { setLightboxUrl(null); }}
        >
          <img
            src={lightboxUrl}
            alt=""
            style={{ maxWidth: '95vw', maxHeight: '90vh', borderRadius: 8, objectFit: 'contain' }}
            onClick={function(e) { e.stopPropagation(); }}
          />
          <button
            onClick={function() { setLightboxUrl(null); }}
            style={{ position: 'absolute', top: 16, right: 16, background: 'rgba(255,255,255,0.2)', border: 'none', color: '#fff', fontSize: 24, borderRadius: '50%', width: 40, height: 40, cursor: 'pointer', lineHeight: '40px', textAlign: 'center' }}
          >×</button>
        </div>
      )}

      {/* 削除確認ダイアログ */}
      {deleteConfirm && (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
          <div style={{ background: '#fff', borderRadius: 16, padding: 24, width: '100%', maxWidth: 320 }}>
            <h2 style={{ fontSize: 17, fontWeight: 700, color: '#c0392b', marginBottom: 10 }}>投稿を削除しますか？</h2>
            <p style={{ fontSize: 13, color: '#666', marginBottom: 20, lineHeight: 1.6 }}>この操作は元に戻せません。返信もすべて削除されます。</p>
            <div style={{ display: 'flex', gap: 10 }}>
              <button onClick={function() { setDeleteConfirm(false); }} style={{ flex: 1, padding: '10px 0', background: '#f5f2eb', border: 'none', borderRadius: 8, fontWeight: 600, cursor: 'pointer', fontSize: 14 }}>キャンセル</button>
              <button onClick={handleDelete} disabled={deleting} style={{ flex: 1, padding: '10px 0', background: '#c0392b', color: '#fff', border: 'none', borderRadius: 8, fontWeight: 700, cursor: 'pointer', fontSize: 14, opacity: deleting ? 0.7 : 1 }}>
                {deleting ? '削除中...' : '削除する'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* ── ヘッダー ── */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
        <button
          onClick={function() { nav.goBoard(boardId || (post && post.board_id)); }}
          style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 22, color: '#13294B', padding: 0, lineHeight: 1 }}
        >‹</button>
        <h1 style={{ fontSize: 17, fontWeight: 700, color: '#13294B', margin: 0, flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          スレッド詳細
        </h1>
      </div>

      {loading && <div style={{ textAlign: 'center', padding: '40px 0', color: '#999' }}>読み込み中...</div>}
      {error && <div style={{ background: '#fff4f4', border: '1px solid #f5c6c6', borderRadius: 8, padding: 16, color: '#c0392b', fontSize: 14 }}>{error}</div>}

      {/* ── 元投稿 ── */}
      {post && (
        <div style={{ ...cardBase, marginBottom: 20 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
            <div style={{ fontSize: 12, color: '#999' }}>
              <span style={{ fontWeight: 600, color: '#555' }}>👤 {post.display_name}</span>
              <span style={{ marginLeft: 8 }}>{relativeTime(post.created_at)}</span>
            </div>
            {post.is_own && (
              <button
                onClick={function() { setDeleteConfirm(true); }}
                style={{ background: 'none', border: '1px solid #f5c6c6', borderRadius: 6, padding: '3px 10px', fontSize: 12, color: '#c0392b', cursor: 'pointer' }}
              >削除</button>
            )}
          </div>
          <h2 style={{ fontSize: 17, fontWeight: 700, color: '#13294B', marginBottom: 10, lineHeight: 1.4 }}>{post.title}</h2>
          <div style={{ fontSize: 14, color: '#333', lineHeight: 1.7, whiteSpace: 'pre-wrap', marginBottom: post.image_url ? 12 : 14 }}>{post.body}</div>
          {post.image_url && (
            <img
              src={post.image_url}
              alt=""
              style={{ maxWidth: '100%', borderRadius: 8, marginBottom: 14, display: 'block', cursor: 'zoom-in' }}
              onClick={function() { setLightboxUrl(post.image_url); }}
            />
          )}
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <button onClick={togglePostLike} style={likeBtn(post.liked)}>
              {post.liked ? '♥' : '♡'} {post.like_count > 0 ? post.like_count : ''}
            </button>
            <span style={{ fontSize: 12, color: '#bbb', marginLeft: 4 }}>💬 {post.reply_count || replies.length}</span>
          </div>
        </div>
      )}

      {/* ── 返信一覧 ── */}
      {!loading && post && (
        <div>
          <div style={{ fontSize: 13, fontWeight: 700, color: '#13294B', marginBottom: 10 }}>
            返信 {replies.length > 0 ? replies.length + '件' : ''}
          </div>
          {replies.length === 0 && (
            <div style={{ textAlign: 'center', padding: '20px 0', color: '#bbb', fontSize: 13 }}>まだ返信はありません</div>
          )}
          {replies.map(function(reply) {
            return (
              <div key={reply.id} style={{ ...cardBase, opacity: reply._sending ? 0.6 : 1 }}>
                <div style={{ fontSize: 12, color: '#999', marginBottom: 6 }}>
                  <span style={{ fontWeight: 600, color: '#555' }}>👤 {reply.display_name}</span>
                  <span style={{ marginLeft: 8 }}>{relativeTime(reply.created_at)}</span>
                  {reply._sending && <span style={{ marginLeft: 8, color: '#C9731A' }}>送信中...</span>}
                </div>
                <div style={{ fontSize: 14, color: '#333', lineHeight: 1.7, whiteSpace: 'pre-wrap', marginBottom: reply.image_url ? 10 : 8 }}>{reply.body}</div>
                {reply.image_url && !reply._sending && (
                  <img
                    src={reply.image_url}
                    alt=""
                    style={{ maxWidth: '100%', borderRadius: 8, marginBottom: 8, display: 'block', cursor: 'zoom-in' }}
                    onClick={function() { setLightboxUrl(reply.image_url); }}
                  />
                )}
                {!reply._sending && (
                  <button onClick={function() { toggleReplyLike(reply.id); }} style={likeBtn(reply.liked)}>
                    {reply.liked ? '♥' : '♡'} {reply.like_count > 0 ? reply.like_count : ''}
                  </button>
                )}
              </div>
            );
          })}
          <div ref={repliesEndRef} />
        </div>
      )}

      {/* ── 返信入力エリア（画面下部固定） ── */}
      <div style={{
        position: 'fixed',
        bottom: 56,
        left: 0,
        right: 0,
        background: '#fff',
        borderTop: '1px solid #e8e4dc',
        boxShadow: '0 -2px 10px rgba(0,0,0,0.06)',
        padding: '10px 16px',
        paddingBottom: 'max(10px, env(safe-area-inset-bottom))',
        zIndex: 50,
      }}>
        {formError && <div style={{ color: '#c0392b', fontSize: 12, marginBottom: 6 }}>{formError}</div>}
        {replyImagePreview && (
          <div style={{ position: 'relative', display: 'inline-block', marginBottom: 8 }}>
            <img src={replyImagePreview} alt="" style={{ height: 60, borderRadius: 6, objectFit: 'cover' }} />
            <button
              onClick={clearReplyImage}
              style={{ position: 'absolute', top: -6, right: -6, background: '#555', color: '#fff', border: 'none', borderRadius: '50%', width: 20, height: 20, fontSize: 12, cursor: 'pointer', lineHeight: '20px', textAlign: 'center', padding: 0 }}
            >×</button>
          </div>
        )}
        <div style={{ display: 'flex', gap: 8, alignItems: 'flex-end' }}>
          <label style={{ cursor: 'pointer', color: '#999', fontSize: 20, lineHeight: 1, flexShrink: 0, paddingBottom: 6 }}>
            📷
            <input type="file" accept="image/jpeg,image/png,image/webp,image/gif" onChange={handleReplyImageChange} style={{ display: 'none' }} />
          </label>
          <textarea
            placeholder="返信を入力..."
            value={replyBody}
            onChange={function(e) { setReplyBody(e.target.value); }}
            maxLength={1000}
            rows={2}
            style={{ flex: 1, padding: '8px 12px', border: '1px solid #ddd', borderRadius: 10, fontSize: 14, resize: 'none', boxSizing: 'border-box', lineHeight: 1.5 }}
          />
          <button
            onClick={handleReplySubmit}
            disabled={submitting || uploading || !replyBody.trim()}
            style={{
              padding: '8px 14px',
              background: (submitting || uploading || !replyBody.trim()) ? '#ccc' : '#13294B',
              color: '#fff',
              border: 'none',
              borderRadius: 10,
              fontWeight: 700,
              fontSize: 14,
              cursor: (submitting || uploading || !replyBody.trim()) ? 'default' : 'pointer',
              flexShrink: 0,
              height: 40,
            }}
          >送信</button>
        </div>
      </div>
    </main>
  );
}

window.ThreadPage = ThreadPage;
