// ===== AI相談ログ ページ =====
function AIConsultsPage({ pendingSelectId, onConsumePending, bookings = [], onOpenBooking }) {
  const D = window.AdminData;
  const KEY = 'seitai_ai_logs_v1';
  const READ_KEY = 'seitai_ai_logs_read_v1';

  const [logs, setLogs] = React.useState([]);
  const [readSet, setReadSet] = React.useState(() => new Set(D.loadJSON(READ_KEY, [])));
  const [filter, setFilter] = React.useState('all'); // all | unread | urgent | line | booked | dropped
  const [selectedId, setSelectedId] = React.useState(null);
  const [search, setSearch] = React.useState('');

  // 外部（予約モーダルの「会話を見る」）からの選択指示
  React.useEffect(() => {
    if (pendingSelectId) {
      setFilter('all');
      setSearch('');
      setSelectedId(pendingSelectId);
      setReadSet(prev => { const n = new Set(prev); n.add(pendingSelectId); return n; });
      onConsumePending && onConsumePending();
    }
  }, [pendingSelectId]);

  // 読み込み + クロスタブ同期
  React.useEffect(() => {
    const load = () => setLogs(D.loadJSON(KEY, []));
    load();
    const onStorage = (e) => {
      if (e.key === KEY) load();
      if (e.key === READ_KEY) setReadSet(new Set(D.loadJSON(READ_KEY, [])));
    };
    window.addEventListener('storage', onStorage);
    // 同タブ更新も拾う
    const interval = setInterval(load, 3000);
    return () => { window.removeEventListener('storage', onStorage); clearInterval(interval); };
  }, []);

  React.useEffect(() => { D.saveJSON(READ_KEY, [...readSet]); }, [readSet]);

  const markRead = (id) => setReadSet(prev => { const n = new Set(prev); n.add(id); return n; });
  const markAllRead = () => setReadSet(new Set(logs.map(l => l.id)));
  const deleteLog = (id) => {
    if (!confirm('このログを削除しますか？')) return;
    const next = logs.filter(l => l.id !== id);
    D.saveJSON(KEY, next);
    setLogs(next);
    if (selectedId === id) setSelectedId(null);
  };
  const clearAll = () => {
    if (!confirm('全てのAI相談ログを削除します。よろしいですか？')) return;
    D.saveJSON(KEY, []);
    setLogs([]);
    setSelectedId(null);
  };

  // フィルタ＆ソート
  const filtered = React.useMemo(() => {
    let arr = logs.slice();
    if (filter === 'unread') arr = arr.filter(l => !readSet.has(l.id));
    if (filter === 'urgent') arr = arr.filter(l => (l.triggers || []).includes('urgent'));
    if (filter === 'line')   arr = arr.filter(l => l.lineCtaClicked);
    if (filter === 'booked') arr = arr.filter(l => l.reachedBooking);
    if (filter === 'dropped') arr = arr.filter(l => !l.reachedBooking && !l.lineCtaClicked);
    if (search.trim()) {
      const s = search.toLowerCase();
      arr = arr.filter(l =>
        (l.summary || '').toLowerCase().includes(s) ||
        (l.topics || []).some(t => t.toLowerCase().includes(s))
      );
    }
    arr.sort((a,b) => (b.updatedAt || b.startedAt || '').localeCompare(a.updatedAt || a.startedAt || ''));
    return arr;
  }, [logs, filter, readSet, search]);

  const selected = filtered.find(l => l.id === selectedId) || logs.find(l => l.id === selectedId);

  // 集計
  const stats = React.useMemo(() => {
    const total = logs.length;
    const unread = logs.filter(l => !readSet.has(l.id)).length;
    const urgent = logs.filter(l => (l.triggers || []).includes('urgent')).length;
    const lineClick = logs.filter(l => l.lineCtaClicked).length;
    const booked = logs.filter(l => l.reachedBooking).length;
    const cvr = total > 0 ? Math.round((booked / total) * 100) : 0;

    // トピックランキング
    const topicCount = {};
    logs.forEach(l => (l.topics || []).forEach(t => { topicCount[t] = (topicCount[t]||0) + 1; }));
    const topTopics = Object.entries(topicCount).sort((a,b) => b[1]-a[1]).slice(0, 5);

    return { total, unread, urgent, lineClick, booked, cvr, topTopics };
  }, [logs, readSet]);

  const fmtDateTime = (iso) => {
    if (!iso) return '―';
    const d = new Date(iso);
    return `${d.getMonth()+1}/${d.getDate()} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}`;
  };
  const fmtRelative = (iso) => {
    if (!iso) return '―';
    const t = new Date(iso);
    const diff = (new Date() - t) / 1000;
    if (diff < 60) return 'たった今';
    if (diff < 3600) return Math.floor(diff/60) + '分前';
    if (diff < 86400) return Math.floor(diff/3600) + '時間前';
    if (diff < 86400*7) return Math.floor(diff/86400) + '日前';
    return fmtDateTime(iso);
  };

  return (
    <div className="ai-consults-page">
      {/* KPI */}
      <div className="ai-stats">
        <div className="ai-stat-card">
          <div className="ai-stat-label">相談件数（全期間）</div>
          <div className="ai-stat-value">{stats.total}</div>
        </div>
        <div className="ai-stat-card">
          <div className="ai-stat-label">未読</div>
          <div className="ai-stat-value" style={{color: stats.unread > 0 ? 'var(--orange)' : 'var(--ink)'}}>{stats.unread}</div>
        </div>
        <div className="ai-stat-card">
          <div className="ai-stat-label">緊急/専門判断</div>
          <div className="ai-stat-value" style={{color: stats.urgent > 0 ? '#d6651e' : 'var(--ink)'}}>{stats.urgent}</div>
        </div>
        <div className="ai-stat-card">
          <div className="ai-stat-label">LINE誘導クリック</div>
          <div className="ai-stat-value" style={{color: '#06c755'}}>{stats.lineClick}</div>
        </div>
        <div className="ai-stat-card">
          <div className="ai-stat-label">予約到達</div>
          <div className="ai-stat-value">{stats.booked} <span style={{fontSize:13, color:'var(--ink-soft)', fontWeight:500}}>({stats.cvr}%)</span></div>
        </div>
      </div>

      {/* トピックランキング */}
      {stats.topTopics.length > 0 && (
        <div className="ai-topics-card">
          <div className="ai-topics-label">よく相談されるトピック TOP5</div>
          <div className="ai-topics-list">
            {stats.topTopics.map(([t, c], i) => (
              <div key={t} className="ai-topic-chip">
                <span className="ai-topic-rank">{i+1}</span>
                <span className="ai-topic-name">{t}</span>
                <span className="ai-topic-count">{c}件</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* フィルタバー */}
      <div className="filter-bar" style={{marginTop: 12}}>
        <div className="ai-filters">
          {[
            { v:'all', label:'すべて' },
            { v:'unread', label:`未読 (${stats.unread})` },
            { v:'urgent', label:'緊急/専門判断' },
            { v:'line', label:'LINEクリック' },
            { v:'booked', label:'予約到達' },
            { v:'dropped', label:'離脱' }
          ].map(f => (
            <button key={f.v}
              className={'ai-filter-btn' + (filter === f.v ? ' active' : '')}
              onClick={() => setFilter(f.v)}>
              {f.label}
            </button>
          ))}
        </div>
        <input type="text" className="ai-search" placeholder="症状やトピックで検索..."
          value={search} onChange={e => setSearch(e.target.value)} />
        <div style={{flex:1}}/>
        <button className="btn" onClick={markAllRead}><Icon name="check" size={14}/> 全て既読</button>
        {logs.length > 0 && (
          <button className="btn btn-ghost" onClick={clearAll} style={{color:'#c33'}}>全削除</button>
        )}
      </div>

      {/* リスト + 詳細 */}
      {logs.length === 0 ? (
        <div className="card" style={{marginTop: 12}}>
          <EmptyState icon="messages" title="AI相談ログはまだありません"
            sub="LP上でユーザーがAI院長と5往復以上会話すると、ここに表示されます。"/>
        </div>
      ) : (
        <div className="ai-split">
          {/* リスト */}
          <div className="ai-list">
            {filtered.length === 0 ? (
              <div className="ai-empty-row">該当する相談はありません</div>
            ) : filtered.map(l => {
              const unread = !readSet.has(l.id);
              const isUrgent = (l.triggers || []).includes('urgent');
              const isSelected = l.id === selectedId;
              return (
                <div key={l.id}
                  className={'ai-list-row' + (isSelected ? ' selected' : '') + (unread ? ' unread' : '')}
                  onClick={() => { setSelectedId(l.id); markRead(l.id); }}>
                  <div className="ai-list-row-head">
                    <span className="ai-list-time">{fmtRelative(l.startedAt)}</span>
                    <span className="ai-list-rounds">{l.rounds || 0}往復</span>
                    {unread && <span className="ai-list-dot"/>}
                  </div>
                  <div className="ai-list-summary">{l.summary || '（記録なし）'}</div>
                  <div className="ai-list-flags">
                    {(l.topics || []).slice(0, 3).map(t => <span key={t} className="ai-list-topic">{t}</span>)}
                    {isUrgent && <span className="ai-list-flag urgent">緊急</span>}
                    {l.lineCtaClicked && <span className="ai-list-flag line">LINE</span>}
                    {l.reachedBooking && <span className="ai-list-flag booked">予約</span>}
                    {!l.reachedBooking && !l.lineCtaClicked && <span className="ai-list-flag dropped">離脱</span>}
                  </div>
                </div>
              );
            })}
          </div>

          {/* 詳細 */}
          <div className="ai-detail">
            {!selected ? (
              <div className="ai-detail-empty">
                <Icon name="messages" size={48}/>
                <p>左のリストから相談を選択してください</p>
              </div>
            ) : (
              <div className="ai-detail-body">
                <div className="ai-detail-head">
                  <div>
                    <div className="ai-detail-meta">
                      {fmtDateTime(selected.startedAt)} · {selected.rounds || 0}往復
                      {selected.reachedBooking && <span className="ai-list-flag booked" style={{marginLeft: 8}}>予約到達</span>}
                      {selected.lineCtaClicked && <span className="ai-list-flag line" style={{marginLeft: 6}}>LINEクリック</span>}
                      {(selected.triggers || []).includes('urgent') && <span className="ai-list-flag urgent" style={{marginLeft: 6}}>緊急</span>}
                    </div>
                    <div className="ai-detail-topics">
                      {(selected.topics || []).map(t => <span key={t} className="ai-list-topic">{t}</span>)}
                      {(selected.topics || []).length === 0 && <span style={{color:'var(--ink-soft)', fontSize:12}}>トピック未抽出</span>}
                    </div>
                  </div>
                  <div style={{display:'flex', gap:8, flexShrink:0}}>
                    {(() => {
                      // 紐付く予約を検索
                      const linkedBooking = bookings.find(b => b.aiConsultId === selected.id);
                      if (!linkedBooking) return null;
                      return (
                        <button className="btn btn-primary" onClick={() => onOpenBooking && onOpenBooking(linkedBooking)} style={{whiteSpace:'nowrap'}}>
                          <Icon name="external" size={14}/> 予約詳細を開く
                        </button>
                      );
                    })()}
                    <button className="btn btn-ghost" onClick={() => deleteLog(selected.id)} style={{color:'#c33'}}>
                      <Icon name="trash" size={14}/> 削除
                    </button>
                  </div>
                </div>

                <div className="ai-detail-thread">
                  {(selected.messages || []).map((m, i) => (
                    <div key={i} className={'ai-bubble-row ' + m.role}>
                      <div className="ai-bubble-label">{m.role === 'user' ? 'ユーザー' : 'AI院長'}</div>
                      <div className="ai-bubble-text">{m.content}</div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* スタイル */}
      <style>{`
        .ai-stats { display:grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 16px; }
        .ai-stat-card { background: #fff; border:1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
        .ai-stat-label { font-size:11px; color: var(--ink-soft); font-weight:600; margin-bottom: 6px; }
        .ai-stat-value { font-size: 26px; font-weight: 800; color: var(--ink); line-height: 1; }

        .ai-topics-card { background: #fff; border:1px solid var(--border); border-radius: 12px; padding: 12px 16px; display:flex; align-items:center; gap: 16px; }
        .ai-topics-label { font-size: 11px; color: var(--ink-soft); font-weight: 700; letter-spacing: .05em; flex-shrink:0; }
        .ai-topics-list { display:flex; gap: 8px; flex-wrap: wrap; }
        .ai-topic-chip { display:inline-flex; align-items:center; gap:6px; background: var(--green-50); border:1px solid var(--green-100); padding: 4px 10px 4px 4px; border-radius: 999px; font-size: 12px; }
        .ai-topic-rank { display:inline-flex; align-items:center; justify-content:center; width: 18px; height:18px; background: var(--green-800); color: #fff; border-radius: 50%; font-size: 10px; font-weight: 800; }
        .ai-topic-name { font-weight: 700; color: var(--ink); }
        .ai-topic-count { color: var(--ink-soft); font-size: 11px; }

        .ai-filters { display:flex; gap: 6px; flex-wrap:wrap; }
        .ai-filter-btn { padding: 6px 12px; border-radius: 999px; border:1px solid var(--border); background:#fff; font-size: 12px; font-weight: 600; color: var(--ink-soft); cursor:pointer; }
        .ai-filter-btn.active { background: var(--green-800); color:#fff; border-color: var(--green-800); }
        .ai-search { padding: 7px 12px; border-radius: 8px; border:1px solid var(--border); font-size: 12.5px; min-width: 200px; }

        .ai-split { display:grid; grid-template-columns: 380px 1fr; gap: 12px; margin-top: 12px; min-height: 540px; }
        .ai-list { background:#fff; border:1px solid var(--border); border-radius: 12px; overflow: hidden; max-height: 720px; overflow-y: auto; }
        .ai-list-row { padding: 12px 14px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background .15s; }
        .ai-list-row:hover { background: #fbf9f4; }
        .ai-list-row.selected { background: var(--green-50); border-left: 3px solid var(--green-800); padding-left: 11px; }
        .ai-list-row.unread { background: #fffaf3; }
        .ai-list-row.unread.selected { background: var(--green-50); }
        .ai-list-row-head { display:flex; align-items:center; gap:8px; margin-bottom: 4px; font-size: 11px; }
        .ai-list-time { color: var(--ink-soft); font-weight: 600; }
        .ai-list-rounds { color: var(--ink-soft); }
        .ai-list-dot { width: 7px; height:7px; border-radius:50%; background: var(--orange); margin-left: auto; }
        .ai-list-summary { font-size: 12.5px; color: var(--ink); line-height: 1.5; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; margin-bottom: 6px; }
        .ai-list-flags { display:flex; gap:4px; flex-wrap:wrap; }
        .ai-list-topic { font-size: 10.5px; padding: 2px 7px; border-radius: 4px; background: var(--green-50); color: var(--green-800); font-weight: 600; }
        .ai-list-flag { font-size: 10px; padding: 2px 7px; border-radius: 4px; font-weight: 700; }
        .ai-list-flag.urgent { background: #fdf0e6; color: #d6651e; }
        .ai-list-flag.line { background: #e8f9ed; color: #06a045; }
        .ai-list-flag.booked { background: #e8f0e6; color: var(--green-800); }
        .ai-list-flag.dropped { background: #f0eee8; color: #888; }

        .ai-detail { background:#fff; border:1px solid var(--border); border-radius: 12px; min-height: 540px; }
        .ai-detail-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; height: 100%; color: var(--ink-soft); padding: 60px 20px; text-align:center; gap:12px; opacity:.6; }
        .ai-detail-empty p { margin:0; font-size: 13px; }
        .ai-detail-body { padding: 18px 20px; }
        .ai-detail-head { display:flex; align-items:flex-start; justify-content:space-between; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
        .ai-detail-meta { font-size: 12px; color: var(--ink-soft); margin-bottom: 6px; }
        .ai-detail-topics { display:flex; gap: 4px; flex-wrap: wrap; }
        .ai-detail-thread { display:flex; flex-direction:column; gap: 14px; max-height: 600px; overflow-y: auto; }
        .ai-bubble-row { padding: 10px 14px; border-radius: 10px; max-width: 90%; }
        .ai-bubble-row.user { background: #f3f4ed; align-self: flex-end; }
        .ai-bubble-row.assistant { background: var(--green-50); align-self: flex-start; }
        .ai-bubble-label { font-size: 10px; color: var(--ink-soft); font-weight: 700; letter-spacing: .05em; margin-bottom: 4px; }
        .ai-bubble-text { font-size: 13px; line-height: 1.7; color: var(--ink); white-space: pre-wrap; }
        .ai-empty-row { padding: 40px 20px; text-align:center; color: var(--ink-soft); font-size: 13px; }

        @media (max-width: 1100px) {
          .ai-stats { grid-template-columns: repeat(2, 1fr); }
          .ai-split { grid-template-columns: 1fr; }
        }
      `}</style>
    </div>
  );
}
window.AIConsultsPage = AIConsultsPage;
