// Arcaid Guild — screens

function GTopicList({ topics, state, go, onLike, onBookmark, empty }) {
  if (!topics.length) return <GEmpty icon="home" text={empty || "トピックがありません"} />;
  return (
    <div className="g-list">
      {topics.map((t) => (
        <GTopicCard key={t.id} topic={t} state={state}
          onOpen={(id) => go("topic", { id })} onLike={onLike} onBookmark={onBookmark} />
      ))}
    </div>
  );
}

// 5.1 Home
function GHome({ route, go, state, onLike, onBookmark }) {
  const cat = route.params.category || "new";
  const tabs = [{ key: "new", label: "新着" }, ...GUILD_CATEGORIES.map((c) => ({ key: c.key, label: c.label }))];
  let list = GUILD_TOPICS.filter((t) => cat === "new" || t.category === cat);
  list = [...list].sort((a, b) => (b.pinned ? 1 : 0) - (a.pinned ? 1 : 0) || b.createdAt - a.createdAt);
  return (
    <>
      <GHeader title="ホーム" />
      <div className="g-tabs">
        {tabs.map((t) => (
          <button key={t.key} type="button" className={"g-tab" + (cat === t.key ? " active" : "")}
            onClick={() => go("home", { category: t.key })}>{t.label}</button>
        ))}
      </div>
      <div className="g-scroll">
        <GTopicList topics={list} state={state} go={go} onLike={onLike} onBookmark={onBookmark} empty="このカテゴリーの投稿はまだありません" />
      </div>
    </>
  );
}

// 5.3 Topic detail
function GTopic({ route, go, state, onLike, onBookmark, onLikeComment }) {
  const t = GUILD_TOPICS.find((x) => x.id === route.params.id);
  const formRef = React.useRef(null);
  const taRef = React.useRef(null);
  const [draft, setDraft] = React.useState("");
  if (!t) return <GEmpty text="トピックが見つかりません" />;
  const comments = GUILD_COMMENTS[t.id] || [];
  const st = state[t.id] || {};
  const reply = (n) => {
    setDraft((d) => (">>" + n + " " + d).trimStart());
    if (formRef.current) formRef.current.scrollIntoView({ block: "center" });
    if (taRef.current) setTimeout(() => taRef.current.focus(), 250);
  };
  const tags = guildExtractTags(t.body);
  return (
    <>
      <GHeader onBack={() => go(-1)} title="トピック" />
      <div className="g-scroll">
        <article className="g-detail">
          {t.pinned && <div className="g-pin"><GIcon name="pin" size={13} /> 固定</div>}
          <div className="g-card-top"><GCatChip category={t.category} /><span className="g-time">{guildRelTime(t.createdAt)}</span></div>
          <h2 className="g-detail-title">{t.title}</h2>
          <div className="g-detail-author" onClick={() => go("profile", { handle: t.author })}>
            <GAvatar handle={t.author} size={38} />
            <div>
              <div className="g-author-name">{GUILD_USERS[t.author].name}</div>
              <div className="g-handle">@{t.author}</div>
            </div>
          </div>
          <p className="g-detail-body">{t.body.replace(/#[^\s#　]+/g, "").trim()}</p>
          {t.images.map((c, i) => <div key={i} className="g-detail-img" style={{ background: c }} />)}
          {tags.length > 0 && <div className="g-tagrow">{tags.map((tg) => <GTag key={tg} label={tg} onClick={() => go("search", { tag: tg })} />)}</div>}
          <div className="g-detail-meta"><span><GIcon name="eye" size={15} /> {t.views}回</span></div>
          <div className="g-detail-actions">
            <GMetric icon="heart" count={t.likes + (st.liked ? 1 : 0)} active={st.liked} onClick={() => onLike(t.id)} activeColor="#e0506a" />
            <GMetric icon="bookmark" count={t.bookmarks + (st.bookmarked ? 1 : 0)} active={st.bookmarked} onClick={() => onBookmark(t.id)} activeColor="#149a48" />
          </div>
        </article>

        <div className="g-comments">
          <div className="g-comments-head">コメント <span>{comments.length}</span></div>
          {comments.map((c) => {
            const cst = (state["c_" + t.id + "_" + c.id]) || {};
            return (
              <div className="g-comment" key={c.id} id={"c-" + c.id}>
                <div className="g-comment-no">{c.id}</div>
                <div className="g-comment-main">
                  <div className="g-comment-head">
                    <GAvatar handle={c.author} size={26} />
                    <span className="g-author-name">{GUILD_USERS[c.author].name}</span>
                    <span className="g-time">{guildRelTime(c.createdAt)}</span>
                  </div>
                  <p className="g-comment-body">{c.body.split(/(>>\d+)/g).map((p, i) => /^>>\d+$/.test(p) ? <a key={i} className="g-anchor">{p}</a> : p)}</p>
                  <div className="g-comment-actions">
                    <GMetric icon="heart" count={c.likes + (cst.liked ? 1 : 0)} active={cst.liked} onClick={() => onLikeComment(t.id, c.id)} activeColor="#e0506a" />
                    <button type="button" className="g-replybtn" onClick={() => reply(c.id)}><GIcon name="reply" size={16} /> 返信</button>
                  </div>
                </div>
              </div>
            );
          })}

          <div className="g-commentform" ref={formRef}>
            <div className="g-form-label">コメント <span className="g-req">必須</span></div>
            <textarea ref={taRef} className="g-textarea" value={draft} onChange={(e) => setDraft(e.target.value)} placeholder="コメントを入力…（返信は >>番号 で引用されます）" />
            <div className="g-form-row">
              <button type="button" className="g-imgadd"><GIcon name="image" size={18} /> 画像</button>
              <button type="button" className="g-postbtn" onClick={() => { setDraft(""); }}>投稿する <GIcon name="send" size={16} /></button>
            </div>
            <div className="g-form-note">画像は最大5枚・各10MB（JPEG / PNG / GIF）</div>
          </div>
        </div>
      </div>
    </>
  );
}

// 5.4 Create topic
function GCreate({ go }) {
  const [cat, setCat] = React.useState("main");
  const [title, setTitle] = React.useState("");
  const [body, setBody] = React.useState("");
  const tags = guildExtractTags(body);
  const valid = title.trim() && body.trim();
  return (
    <>
      <GHeader onBack={() => go(-1)} title="新規トピック" />
      <div className="g-scroll g-pad">
        <div className="g-form-label">タイトル <span className="g-req">必須</span></div>
        <input className="g-input" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="質問や話題のタイトル" />

        <div className="g-form-label">カテゴリー <span className="g-req">必須</span></div>
        <div className="g-segment">
          {GUILD_CATEGORIES.map((c) => (
            <button key={c.key} type="button" className={"g-seg" + (cat === c.key ? " active" : "")} onClick={() => setCat(c.key)}
              style={cat === c.key ? { background: c.color, borderColor: c.color } : undefined}>{c.label}</button>
          ))}
        </div>

        <div className="g-form-label">本文 <span className="g-req">必須</span></div>
        <textarea className="g-textarea tall" value={body} onChange={(e) => setBody(e.target.value)} placeholder="本文を入力… #タグ を書くと自動でタグが付きます" />
        {tags.length > 0 && <div className="g-tagrow">{tags.map((tg) => <span key={tg} className="g-tag static">#{tg}</span>)}</div>}

        <div className="g-form-label">画像（任意）</div>
        <div className="g-uploader"><GIcon name="image" size={22} /><span>画像を追加 — 最大5枚・各10MB</span></div>

        <button type="button" className={"g-submit" + (valid ? "" : " disabled")} disabled={!valid}
          onClick={() => go("home", {})}>トピックを投稿する</button>
      </div>
    </>
  );
}

// 5.5 Search
function GSearch({ route, go, state, onLike, onBookmark }) {
  const [q, setQ] = React.useState("");
  const tag = route.params.tag || "";
  const ql = q.trim().toLowerCase();
  let results = GUILD_TOPICS;
  if (tag) results = results.filter((t) => guildExtractTags(t.body).includes(tag));
  else if (ql) results = results.filter((t) => (t.title + t.body).toLowerCase().includes(ql));
  const featured = [...GUILD_TOPICS].sort((a, b) => b.likes - a.likes).slice(0, 3);
  const searching = ql || tag;
  return (
    <>
      <GHeader title="検索" />
      <div className="g-searchbar">
        <GIcon name="search" size={18} />
        <input value={q} onChange={(e) => { setQ(e.target.value); if (tag) go("search", {}); }} placeholder="キーワードで検索" />
      </div>
      <div className="g-scroll g-pad">
        {!searching && (
          <>
            <div className="g-sec-label">最近のタグ</div>
            <div className="g-tagrow wrap">{GUILD_TAGS.map((t) => <GTag key={t} label={t} active={tag === t} onClick={() => go("search", { tag: t })} />)}</div>
            <div className="g-sec-label">注目のトピック</div>
            <GTopicList topics={featured} state={state} go={go} onLike={onLike} onBookmark={onBookmark} />
          </>
        )}
        {searching && (
          <>
            {tag && <div className="g-sec-label">#{tag} のトピック</div>}
            <GTopicList topics={results} state={state} go={go} onLike={onLike} onBookmark={onBookmark} empty="該当するトピックがありません" />
          </>
        )}
      </div>
    </>
  );
}

// 5.6 / 5.7 Columns
function GColumns({ go }) {
  return (
    <>
      <GHeader title="限定コラム" />
      <div className="g-scroll g-pad">
        <div className="g-members-note"><GIcon name="check" size={15} /> 会員限定コンテンツ</div>
        <div className="g-list">
          {GUILD_COLUMNS.map((c) => (
            <article key={c.id} className="g-colcard" onClick={() => go("column", { id: c.id })}>
              <div className="g-colthumb" style={{ background: c.hero }} />
              <div className="g-colbody">
                <h3>{c.title}</h3>
                <p>{c.excerpt}</p>
                <span className="g-time">{guildDateStr(c.date)}</span>
              </div>
            </article>
          ))}
        </div>
      </div>
    </>
  );
}

function GColumn({ route, go, state, onLikeCol, onBookmarkCol }) {
  const c = GUILD_COLUMNS.find((x) => x.id === route.params.id);
  if (!c) return <GEmpty text="コラムが見つかりません" />;
  const st = state["col_" + c.id] || {};
  return (
    <>
      <GHeader onBack={() => go(-1)} title="限定コラム" />
      <div className="g-scroll">
        <div className="g-colhero" style={{ background: c.hero }} />
        <div className="g-pad">
          <h2 className="g-detail-title">{c.title}</h2>
          <div className="g-detail-meta"><span>{guildDateStr(c.date)}</span></div>
          <div className="g-colcontent">
            {c.body.map((b, i) => {
              if (b.type === "h") return <h3 key={i}>{b.text}</h3>;
              if (b.type === "img") return <div key={i} className="g-detail-img" style={{ background: b.color }} />;
              return <p key={i}>{b.text}</p>;
            })}
          </div>
          <div className="g-detail-actions">
            <GMetric icon="heart" count={c.likes + (st.liked ? 1 : 0)} active={st.liked} onClick={() => onLikeCol(c.id)} activeColor="#e0506a" />
            <GMetric icon="bookmark" count={c.bookmarks + (st.bookmarked ? 1 : 0)} active={st.bookmarked} onClick={() => onBookmarkCol(c.id)} activeColor="#149a48" />
          </div>
        </div>
      </div>
    </>
  );
}

// 5.8 Notifications
function GNotifications({ go }) {
  return (
    <>
      <GHeader title="通知" />
      <div className="g-scroll">
        {!GUILD_NOTIFICATIONS.length && <GEmpty icon="bell" text="通知はまだありません" />}
        {GUILD_NOTIFICATIONS.map((n) => {
          const t = GUILD_TOPICS.find((x) => x.id === n.topic);
          return (
            <button type="button" key={n.id} className="g-notif" onClick={() => go("topic", { id: n.topic })}>
              <GAvatar handle={n.actor} size={38} />
              <div className="g-notif-main">
                <div className="g-notif-text">
                  <b>{GUILD_USERS[n.actor].name}</b>さんが{n.type === "comment" ? "コメントしました" : "いいねしました"}
                </div>
                <div className="g-notif-topic">{t ? t.title : ""}</div>
                {n.excerpt && <div className="g-notif-ex">{n.excerpt}</div>}
                <div className="g-time">{guildRelTime(n.createdAt)}</div>
              </div>
              <span className={"g-notif-ic " + n.type}><GIcon name={n.type === "comment" ? "comment" : "heart"} size={15} /></span>
            </button>
          );
        })}
      </div>
    </>
  );
}

// 5.9 Bookmarks
function GBookmarks({ go, state, onLike, onBookmark }) {
  const list = GUILD_TOPICS.filter((t) => (state[t.id] || {}).bookmarked);
  return (
    <>
      <GHeader onBack={() => go("more")} title="ブックマーク" />
      <div className="g-scroll">
        {list.length ? (
          <GTopicList topics={list} state={state} go={go} onLike={onLike} onBookmark={onBookmark} />
        ) : <GEmpty icon="bookmark" text="ブックマークがありません" />}
      </div>
    </>
  );
}

// 5.10 Profile
function GProfile({ route, go, state, follow, onFollow, onLike, onBookmark }) {
  const handle = route.params.handle || GUILD_ME;
  const u = GUILD_USERS[handle];
  const [tab, setTab] = React.useState("topics");
  if (!u) return <GEmpty text="ユーザーが見つかりません" />;
  const isMe = handle === GUILD_ME;
  const isFollowing = follow[handle];
  const topics = GUILD_TOPICS.filter((t) => t.author === handle);
  const myComments = [];
  Object.keys(GUILD_COMMENTS).forEach((tid) => (GUILD_COMMENTS[tid] || []).forEach((c) => { if (c.author === handle) myComments.push({ ...c, tid }); }));
  return (
    <>
      <GHeader onBack={() => go(-1)} title="プロフィール" />
      <div className="g-scroll">
        <div className="g-profile">
          <div className="g-profile-top">
            <GAvatar handle={handle} size={72} />
            {!isMe && (
              <button type="button" className={"g-followbtn" + (isFollowing ? " on" : "")} onClick={() => onFollow(handle)}>
                {isFollowing ? "フォロー中" : "フォローする"}
              </button>
            )}
          </div>
          <div className="g-profile-name">{u.name}{u.official && <span className="g-off">公式</span>}</div>
          <div className="g-handle">@{u.handle}</div>
          {u.bio && <p className="g-profile-bio">{u.bio}</p>}
          <div className="g-profile-cars">{u.cars.map((c) => <span key={c} className="g-carchip"><GIcon name="car" size={14} /> {c}</span>)}</div>
          {u.website && <a className="g-weblink"><GIcon name="link" size={14} /> {u.website}</a>}
          <div className="g-follows">
            <span><b>{u.following}</b> フォロー中</span>
            <span><b>{u.followers}</b> フォロワー</span>
          </div>
        </div>
        <div className="g-tabs sub">
          <button type="button" className={"g-tab" + (tab === "topics" ? " active" : "")} onClick={() => setTab("topics")}>トピック</button>
          <button type="button" className={"g-tab" + (tab === "comments" ? " active" : "")} onClick={() => setTab("comments")}>コメント</button>
        </div>
        {tab === "topics" ? (
          <GTopicList topics={topics} state={state} go={go} onLike={onLike} onBookmark={onBookmark} empty="トピックがありません" />
        ) : (
          <div className="g-pad">
            {myComments.length ? myComments.map((c, i) => {
              const t = GUILD_TOPICS.find((x) => x.id === c.tid);
              return (
                <button type="button" key={i} className="g-commentitem" onClick={() => go("topic", { id: c.tid })}>
                  <div className="g-commentitem-topic">{t ? t.title : ""}</div>
                  <div className="g-comment-body">{c.body}</div>
                  <div className="g-time">{guildRelTime(c.createdAt)}</div>
                </button>
              );
            }) : <GEmpty icon="comment" text="コメントがありません" />}
            {myComments.length > 0 && <div className="g-pagination">{myComments.length}件中 1〜{myComments.length}件 ・ <b>1</b></div>}
          </div>
        )}
      </div>
    </>
  );
}

// 5.11 Contact
function GContact({ go }) {
  const [q, setQ] = React.useState("");
  const [sent, setSent] = React.useState([]);
  return (
    <>
      <GHeader onBack={() => go("more")} title="お問い合わせ" />
      <div className="g-scroll g-pad">
        {sent.length === 0 ? <GEmpty icon="comment" text="まだお問い合わせがありません" /> : (
          <div className="g-list">
            {sent.map((s, i) => (
              <div key={i} className="g-inquiry"><div className="g-inquiry-status">受付中</div><p>{s}</p><span className="g-time">たった今</span></div>
            ))}
          </div>
        )}
        <div className="g-form-label" style={{ marginTop: 24 }}>質問をする</div>
        <textarea className="g-textarea tall" value={q} onChange={(e) => setQ(e.target.value)} placeholder="運営への質問を入力してください" />
        <button type="button" className={"g-submit" + (q.trim() ? "" : " disabled")} disabled={!q.trim()}
          onClick={() => { setSent([q, ...sent]); setQ(""); }}>送信する</button>
      </div>
    </>
  );
}

// 5.12 More
function GMore({ go, follow }) {
  const me = GUILD_USERS[GUILD_ME];
  const items = [
    { key: "profile", icon: "more", label: "プロフィール", params: { handle: GUILD_ME } },
    { key: "notifications", icon: "bell", label: "通知" },
    { key: "bookmarks", icon: "bookmark", label: "ブックマーク" },
    { key: "columns", icon: "column", label: "限定コラム" },
    { key: "contact", icon: "comment", label: "お問い合わせ" },
  ];
  return (
    <>
      <GHeader title="その他" />
      <div className="g-scroll g-pad">
        <button type="button" className="g-mecard" onClick={() => go("profile", { handle: GUILD_ME })}>
          <GAvatar handle={GUILD_ME} size={52} />
          <div className="g-mecard-main">
            <div className="g-author-name">{me.name}</div>
            <div className="g-handle">@{me.handle}</div>
            <div className="g-follows sm"><span><b>{me.following}</b> フォロー中</span><span><b>{me.followers}</b> フォロワー</span></div>
          </div>
          <GIcon name="chevron" size={18} />
        </button>
        <div className="g-menu">
          {items.map((it) => (
            <button type="button" key={it.key} className="g-menuitem" onClick={() => go(it.key, it.params || {})}>
              <GIcon name={it.icon} size={20} /><span>{it.label}</span><GIcon name="chevron" size={16} />
            </button>
          ))}
        </div>
        <div className="g-menu muted">
          <button type="button" className="g-menuitem"><span>利用規約</span><GIcon name="chevron" size={16} /></button>
          <button type="button" className="g-menuitem"><span>プライバシーポリシー</span><GIcon name="chevron" size={16} /></button>
          <button type="button" className="g-menuitem danger"><span>ログアウト</span><GIcon name="chevron" size={16} /></button>
        </div>
      </div>
    </>
  );
}

Object.assign(window, {
  GHome, GTopic, GCreate, GSearch, GColumns, GColumn, GNotifications, GBookmarks, GProfile, GContact, GMore,
});
