// cast-guide — トップページの cast 一覧 SPA
// React 18 + Babel standalone (urban-guide と同じ運用形態)

const { useState, useEffect, useMemo } = React;

function CastApp() {
  const [shops, setShops] = useState([]);
  const [casts, setCasts] = useState([]);
  const [activeShop, setActiveShop] = useState('all');   // 'all' or shop_id
  const [workingOnly, setWorkingOnly] = useState(false);
  const [loading, setLoading] = useState(true);
  const [selected, setSelected] = useState(null);        // 詳細モーダル対象 cast

  useEffect(() => {
    Promise.all([
      fetch('/api/shops').then((r) => r.json()),
      fetch('/api/casts?limit=500').then((r) => r.json()),
    ])
      .then(([shp, cst]) => {
        setShops(Array.isArray(shp) ? shp : []);
        setCasts(Array.isArray(cst) ? cst : []);
      })
      .catch((e) => console.error('load failed', e))
      .finally(() => setLoading(false));
  }, []);

  // shop ID → cast 数
  const countsByShop = useMemo(() => {
    const m = { all: casts.length };
    for (const c of casts) m[c.shop_id] = (m[c.shop_id] || 0) + 1;
    return m;
  }, [casts]);

  const filtered = useMemo(() => {
    let list = casts;
    if (activeShop !== 'all') list = list.filter((c) => c.shop_id === activeShop);
    if (workingOnly) list = list.filter((c) => c.working_now);
    return list;
  }, [casts, activeShop, workingOnly]);

  if (loading) {
    return (
      <div className="cg-shell">
        <div className="cg-loading">読み込み中…</div>
      </div>
    );
  }

  return (
    <div className="cg-shell">
      <div className="cg-hd">
        <div>
          <div className="cg-sub">SECTION 01 / CASTS</div>
          <div className="cg-title">おすすめキャスト</div>
        </div>
        <div className="cg-sub">{filtered.length} 名</div>
      </div>

      <div className="cg-controls">
        <div className="chips" style={{ padding: 0 }}>
          <button
            type="button"
            className={`chip ${workingOnly ? 'is-on' : ''}`}
            onClick={() => setWorkingOnly((v) => !v)}
          >
            <span className="chip-led" aria-hidden="true"></span>
            <span>出勤中のみ</span>
          </button>
        </div>
        <div className="cg-tabs">
          <button
            className={`cg-tab ${activeShop === 'all' ? 'is-on' : ''}`}
            onClick={() => setActiveShop('all')}
          >
            すべて<span className="cg-tab-count">{countsByShop.all || 0}</span>
          </button>
          {shops.map((s) => (
            <button
              key={s.id}
              className={`cg-tab ${activeShop === s.id ? 'is-on' : ''}`}
              onClick={() => setActiveShop(s.id)}
              title={s.tag_ja}
            >
              {s.name}<span className="cg-tab-count">{countsByShop[s.id] || 0}</span>
            </button>
          ))}
        </div>
      </div>

      {filtered.length === 0 ? (
        <div className="cg-empty">該当キャストがありません。</div>
      ) : (
        <div className="cg-grid">
          {filtered.map((c) => (
            <CastCard
              key={c.id}
              cast={c}
              showShop={activeShop === 'all' && shops.length > 1}
              onClick={() => setSelected(c)}
            />
          ))}
        </div>
      )}

      {selected && (
        <CastModal cast={selected} onClose={() => setSelected(null)} />
      )}
    </div>
  );
}

function CastCard({ cast, showShop, onClick }) {
  const photoStyle = cast.photo_url
    ? { backgroundImage: `url('${cast.photo_url}')` }
    : {};
  return (
    <div className="cg-card" onClick={onClick} role="button" tabIndex={0}
         onKeyDown={(e) => { if (e.key === 'Enter') onClick && onClick(); }}>
      <div className="cg-card-img" style={photoStyle}>
        {cast.working_now && <div className="cg-badge-working">出勤中</div>}
      </div>
      <div className="cg-card-body">
        <div className="cg-card-name">
          {cast.name}{cast.age != null && <small>({cast.age})</small>}
        </div>
        {cast.prof_text && <div className="cg-card-prof">{cast.prof_text}</div>}
        {cast.start_time && cast.end_time && (
          <div className="cg-card-time-row">⏰ {cast.start_time}〜{cast.end_time}</div>
        )}
        {showShop && cast.shop_name && (
          <div className="cg-card-shop">📍 {cast.shop_name}</div>
        )}
      </div>
    </div>
  );
}

function CastModal({ cast, onClose }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [onClose]);

  const photoStyle = cast.photo_url
    ? { backgroundImage: `url('${cast.photo_url}')` }
    : {};
  const cells = [];
  if (cast.height) cells.push({ k: '身長', v: `${cast.height}cm` });
  if (cast.cup)    cells.push({ k: 'カップ', v: `${cast.cup}カップ` });
  if (cast.style)  cells.push({ k: 'スタイル', v: cast.style });
  if (cast.age != null) cells.push({ k: '年齢', v: `${cast.age}歳` });
  const shopHandle = cast.shop_url || '';

  return (
    <div className="cm-bd" onClick={onClose}>
      <div className="cm" onClick={(e) => e.stopPropagation()}>
        <div className="cm-grip"></div>
        <div className="cm-cover" style={photoStyle}>
          {cast.working_now && <div className="cm-working-badge">● 出勤中</div>}
          <button className="cm-x" onClick={onClose} aria-label="閉じる">×</button>
          {cast.start_time && cast.end_time && (
            <div className="cm-time-overlay">
              本日 {cast.start_time}〜{cast.end_time}
            </div>
          )}
        </div>
        <div className="cm-body">
          <div className="cm-name">
            {cast.name}{cast.age != null && <small>({cast.age})</small>}
          </div>
          {cast.shop_name && (
            <div className="cm-shop">📍 {cast.shop_name}{cast.shop_tag ? ` · ${cast.shop_tag}` : ''}</div>
          )}

          <div className="cm-pills">
            {cast.working_now && <span className="cm-pill is-accent">出勤中</span>}
            {cast.cup && <span className="cm-pill">{cast.cup}カップ</span>}
            {cast.height && <span className="cm-pill">身長 {cast.height}cm</span>}
            {cast.style && <span className="cm-pill">{cast.style}</span>}
          </div>

          {cast.prof_text && <div className="cm-prof">{cast.prof_text}</div>}

          {cells.length > 0 && (
            <div className="cm-info">
              {cells.map((c) => (
                <div className="cm-cell" key={c.k}>
                  <div className="cm-cell-l">{c.k}</div>
                  <div className="cm-cell-v">{c.v}</div>
                </div>
              ))}
            </div>
          )}

          {cast.detail && Array.isArray(cast.detail.profile) && cast.detail.profile.length > 0 && (
            <div className="cm-section">
              <div className="cm-section-h">プロフィール詳細</div>
              <dl className="cm-dl">
                {cast.detail.profile.map((row, i) => (
                  <div className="cm-dl-row" key={i}>
                    <dt>{row.label}</dt>
                    <dd>{row.value}</dd>
                  </div>
                ))}
              </dl>
            </div>
          )}

          {cast.detail && Array.isArray(cast.detail.options) && cast.detail.options.length > 0 && (
            <div className="cm-section">
              <div className="cm-section-h">可能オプション</div>
              <ul className="cm-opt">
                {cast.detail.options.map((t, i) => (
                  <li key={i}>{t}</li>
                ))}
              </ul>
            </div>
          )}

          {cast.detail && cast.detail.shop_comment && (
            <div className="cm-section">
              <div className="cm-section-h">お店からのコメント</div>
              <div className="cm-blurb">{cast.detail.shop_comment}</div>
            </div>
          )}

          <div className="cm-actions">
            {cast.cast_page_url && (
              <a className="cm-btn cm-btn-primary"
                 href={cast.cast_page_url} target="_blank" rel="noopener noreferrer">
                公式ページ ↗
              </a>
            )}
            {shopHandle && (
              <a className="cm-btn cm-btn-secondary"
                 href={shopHandle} target="_blank" rel="noopener noreferrer">
                店舗トップ ↗
              </a>
            )}
            <button className="cm-btn cm-btn-secondary" onClick={onClose}>閉じる</button>
          </div>
        </div>
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<CastApp />);
