/* Knowledge Hub — four sub-views.
 *
 * Sub-route is the second segment of the hash route, defaulting to
 * "recent" if absent. The container itself owns the segmented control
 * and dispatches to the relevant view component.
 */
(function () {
  const { useState, useEffect, useMemo } = React;
  const {
    SegmentedControl,
    Input,
    Button,
    Pill,
    Card,
    Icons,
    Avatar,
    EmptyState,
    LoadingSpinner,
    EntryRow,
    EditEntry,
    CaptureMember,
    showToast,
    tokens,
    entries,
    members,
    coach,
    time,
    search,
  } = window.CC;

  // Sub-route helpers --------------------------------------------------
  const SUB_VIEWS = ["members", "recent", "attention", "search"];
  function parseSub(route) {
    // route shape: "/hub" | "/hub/{view}" | "/hub/member/{id}"
    const parts = route.split("/").filter(Boolean);
    if (parts[0] !== "hub") return null;
    if (parts[1] === "member" && parts[2]) {
      return { kind: "memberDetail", memberId: parts[2] };
    }
    if (SUB_VIEWS.includes(parts[1])) return { kind: parts[1] };
    return { kind: "recent" };
  }

  // Subscriptions -----------------------------------------------------
  function useEntries() {
    const [list, setList] = useState(entries.all());
    useEffect(() => entries.subscribe(setList), []);
    return list;
  }
  function useMembers() {
    const [list, setList] = useState(members.all());
    useEffect(() => members.subscribe(setList), []);
    return list;
  }

  // Sub-view router ---------------------------------------------------
  function KnowledgeHub({ route }) {
    const sub = parseSub(route) || { kind: "recent" };
    const [editing, setEditing] = useState(null);
    const [logForMember, setLogForMember] = useState(null);

    function go(view) {
      window.location.hash = `/hub/${view}`;
    }

    if (sub.kind === "memberDetail") {
      return (
        <>
          <MemberDetail
            memberId={sub.memberId}
            onBack={() => go("members")}
            onEdit={setEditing}
            onLog={(m) => setLogForMember(m)}
          />
          {editing && (
            <EditEntry entry={editing} onClose={() => setEditing(null)} />
          )}
          <CaptureMember
            open={Boolean(logForMember)}
            prefilledMember={logForMember}
            onClose={() => setLogForMember(null)}
            onSaved={() => showToast("Saved.")}
          />
        </>
      );
    }

    return (
      <div className="cc-hub">
        <header className="cc-hub__head">
          <h1 className="cc-hub__title">Knowledge Hub</h1>
          <SegmentedControl
            value={sub.kind}
            onChange={go}
            options={[
              { label: "Members", value: "members" },
              { label: "Recent", value: "recent" },
              { label: "Attention", value: "attention" },
              { label: "Search", value: "search" },
            ]}
          />
        </header>
        <div className="cc-hub__body">
          {sub.kind === "members" && (
            <MembersView
              onOpenMember={(m) => (window.location.hash = `/hub/member/${m.row_id}`)}
            />
          )}
          {sub.kind === "recent" && (
            <RecentView
              onEdit={setEditing}
              onOpenMember={(m) =>
                (window.location.hash = `/hub/member/${m.row_id}`)
              }
            />
          )}
          {sub.kind === "attention" && (
            <AttentionView
              onEdit={setEditing}
              onOpenMember={(m) =>
                (window.location.hash = `/hub/member/${m.row_id}`)
              }
            />
          )}
          {sub.kind === "search" && (
            <SearchView
              onOpenMember={(m) =>
                (window.location.hash = `/hub/member/${m.row_id}`)
              }
              onEdit={setEditing}
            />
          )}
        </div>
        {editing && (
          <EditEntry entry={editing} onClose={() => setEditing(null)} />
        )}
      </div>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Members view
  // ────────────────────────────────────────────────────────────
  function MembersView({ onOpenMember }) {
    const list = useMembers();
    const allEntries = useEntries();
    const [filter, setFilter] = useState("all");
    const [showLost, setShowLost] = useState(false);
    const [q, setQ] = useState("");
    const [sortBy, setSortBy] = useState("name");

    const statuses = useMemo(() => {
      const set = new Set(list.map((m) => m.status));
      return Array.from(set);
    }, [list]);

    const lastEntryFor = useMemo(() => {
      const map = new Map();
      for (const e of allEntries) {
        if (e.deleted) continue;
        for (const id of e.members || []) {
          if (!map.has(id)) map.set(id, e);
        }
      }
      return map;
    }, [allEntries]);

    let view = list;
    if (!showLost) view = view.filter((m) => m.status !== "Lost");
    if (filter !== "all") view = view.filter((m) => m.status === filter);
    if (q.trim())
      view = view.filter((m) =>
        m.name.toLowerCase().includes(q.trim().toLowerCase())
      );
    if (sortBy === "recent") {
      view = [...view].sort((a, b) => {
        const ea = lastEntryFor.get(a.row_id)?.created_at || 0;
        const eb = lastEntryFor.get(b.row_id)?.created_at || 0;
        return eb - ea;
      });
    } else {
      view = [...view].sort((a, b) => a.name.localeCompare(b.name));
    }

    const lostCount = list.filter((m) => m.status === "Lost").length;

    return (
      <div>
        <Input
          icon={Icons.search(16)}
          value={q}
          onChange={setQ}
          placeholder="Search members"
        />

        <div className="cc-members__chips">
          <FilterChip
            on={filter === "all"}
            onClick={() => setFilter("all")}
            label="All"
          />
          {statuses
            .filter((s) => s !== "Lost")
            .map((s) => (
              <FilterChip
                key={s}
                on={filter === s}
                onClick={() => setFilter(s)}
                tone={tokens.statusForLabel(s)}
                label={s}
              />
            ))}
          <span style={{ flex: 1 }} />
          <button
            type="button"
            onClick={() => setSortBy(sortBy === "name" ? "recent" : "name")}
            className="cc-members__sort"
          >
            sort: {sortBy === "name" ? "alphabetical" : "recent"}
          </button>
        </div>

        {view.length === 0 ? (
          <EmptyState
            icon={Icons.member(40)}
            title="No members match"
            subtitle="Try a different filter or search."
          />
        ) : (
          <ul className="cc-members__list">
            {view.map((m) => (
              <MemberRow
                key={m.row_id}
                member={m}
                lastEntry={lastEntryFor.get(m.row_id)}
                onClick={() => onOpenMember(m)}
              />
            ))}
          </ul>
        )}

        {lostCount > 0 && (
          <button
            type="button"
            className="cc-members__show-lost"
            onClick={() => setShowLost((v) => !v)}
          >
            {showLost ? "Hide" : "Show"} lost members ({lostCount})
          </button>
        )}
      </div>
    );
  }

  function FilterChip({ on, onClick, tone, label }) {
    const colour = tone ? tokens.colors.status[tone] : tokens.colors.text;
    return (
      <button
        type="button"
        onClick={onClick}
        className={`cc-filter-chip ${on ? "is-on" : ""}`}
        style={{
          "--chip-colour": colour,
        }}
      >
        {label}
      </button>
    );
  }

  function MemberRow({ member, lastEntry, onClick }) {
    return (
      <li>
        <button type="button" className="cc-member-row" onClick={onClick}>
          <span className="cc-member-row__name">{member.name}</span>
          <Pill size="sm" tone={tokens.statusForLabel(member.status)}>
            {member.status}
          </Pill>
          <span className="cc-member-row__coach">{member.coach}</span>
          <span className="cc-member-row__last">
            {lastEntry ? lastEntry.body : "No entries yet"}
          </span>
          <span className="cc-member-row__chev">{Icons.chevronRight(14)}</span>
        </button>
      </li>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Member detail
  // ────────────────────────────────────────────────────────────
  function MemberDetail({ memberId, onBack, onEdit, onLog }) {
    const all = useMembers();
    const allEntries = useEntries();
    const member = all.find((m) => m.row_id === memberId);
    if (!member) {
      return (
        <div className="cc-hub" style={{ padding: 32 }}>
          <EmptyState
            title="Member not found"
            subtitle="Looks like that member is no longer in the sheet."
            action={{ label: "Back to members", onClick: onBack }}
          />
        </div>
      );
    }
    const memberEntries = allEntries.filter(
      (e) => !e.deleted && (e.members || []).includes(memberId)
    );

    return (
      <div className="cc-hub">
        <header className="cc-member-detail__head">
          <button
            type="button"
            className="cc-member-detail__back"
            onClick={onBack}
          >
            ← Members
          </button>
          <h1 className="cc-member-detail__name">{member.name}</h1>
          <div className="cc-member-detail__meta">
            <Pill tone={tokens.statusForLabel(member.status)}>
              {member.status}
            </Pill>
            <span>· {member.coach}</span>
            {member.start_date && (
              <span>· joined {time.shortDateYear(new Date(member.start_date))}</span>
            )}
          </div>
        </header>

        <section className="cc-member-detail__profile">
          <ProfileField label="Programme" value={member.programme} />
          <ProfileField
            label="Days in"
            value={member.days_in != null ? `${member.days_in}` : "—"}
          />
          <ProfileField
            label="Last contact"
            value={
              member.last_contact
                ? time.shortDate(new Date(member.last_contact))
                : "—"
            }
          />
        </section>

        <section className="cc-member-detail__entries">
          <h2 className="cc-section-h2">Entries</h2>
          {memberEntries.length === 0 ? (
            <EmptyState
              icon={Icons.note(40)}
              title={`No entries about ${member.name.split(" ")[0]} yet`}
              subtitle="Log the first one with the button below."
            />
          ) : (
            <div className="cc-member-detail__list">
              {memberEntries.map((e) => (
                <EntryRow
                  key={e.id}
                  entry={e}
                  density="stack"
                  onEdit={onEdit}
                />
              ))}
            </div>
          )}
        </section>

        <button
          type="button"
          className="cc-member-detail__fab"
          onClick={() => onLog(member)}
        >
          {Icons.plus(20)} Log update
        </button>
      </div>
    );
  }

  function ProfileField({ label, value }) {
    return (
      <div className="cc-profile-field">
        <span className="cc-profile-field__label">{label}</span>
        <span className="cc-profile-field__value">{value || "—"}</span>
      </div>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Recent view
  // ────────────────────────────────────────────────────────────
  function RecentView({ onEdit, onOpenMember }) {
    const all = useEntries();
    const visible = all.filter((e) => !e.deleted);
    const [filter, setFilter] = useState("all");
    const [horizon, setHorizon] = useState(14); // days

    const cutoff = Date.now() - horizon * 86400000;
    const filtered = visible.filter((e) => {
      if (e.created_at < cutoff) return false;
      if (filter === "all") return true;
      return e.type === filter;
    });

    if (visible.length === 0) {
      return (
        <EmptyState
          icon={Icons.note(40)}
          title="Nothing logged yet today"
          subtitle="The capture buttons live on the home tab."
        />
      );
    }

    // Group by day key
    const groups = [];
    let lastKey = null;
    for (const e of filtered) {
      const head = time.dayHeader(e.created_at);
      if (head !== lastKey) {
        groups.push({ head, entries: [] });
        lastKey = head;
      }
      groups[groups.length - 1].entries.push(e);
    }

    return (
      <div>
        <div className="cc-members__chips">
          <FilterChip on={filter === "all"} onClick={() => setFilter("all")} label="All" />
          <FilterChip on={filter === "member"} onClick={() => setFilter("member")} label="Member" />
          <FilterChip on={filter === "class"} onClick={() => setFilter("class")} label="Class" />
          <FilterChip on={filter === "note"} onClick={() => setFilter("note")} label="Notes" />
        </div>

        {groups.length === 0 && (
          <EmptyState title="Nothing in this view" />
        )}

        {groups.map((g) => (
          <div key={g.head} className="cc-recent__group">
            <div className="cc-recent__day">{g.head}</div>
            {g.entries.map((e) => (
              <EntryRow
                key={e.id}
                entry={e}
                density="row"
                onEdit={onEdit}
                onOpenMember={onOpenMember}
              />
            ))}
          </div>
        ))}

        {filtered.length > 0 && horizon < 365 && (
          <div style={{ textAlign: "center", padding: 24 }}>
            <Button
              variant="ghost"
              onClick={() => setHorizon(horizon === 14 ? 30 : 365)}
            >
              Load older →
            </Button>
          </div>
        )}
      </div>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Attention view
  // ────────────────────────────────────────────────────────────
  function AttentionView({ onEdit, onOpenMember }) {
    const all = useEntries();
    const visible = all.filter((e) => !e.deleted);
    const me = coach.get() || "simon";

    const mentions = visible.filter(
      (e) =>
        Array.isArray(e.mentions) &&
        e.mentions.includes(me) &&
        !entries.isMentionRead(e, me)
    );
    const followups = visible.filter((e) => e.needs_followup);
    const pinned = visible.filter((e) => e.pinned);
    const decisions = visible.filter((e) => e.tag === "decision");

    const empty =
      mentions.length + followups.length + pinned.length + decisions.length === 0;

    if (empty) {
      return (
        <EmptyState
          icon={Icons.check(40)}
          title="Nothing needs your attention"
          subtitle="Lovely."
        />
      );
    }

    return (
      <div className="cc-attention">
        {mentions.length > 0 && (
          <Section title={`@${me}`} count={mentions.length}>
            {mentions.map((e) => (
              <Card key={e.id} variant="elevated" padding={16}>
                <EntryRow
                  entry={e}
                  density="card"
                  onEdit={onEdit}
                  onOpenMember={onOpenMember}
                  forceExpanded
                />
                <button
                  type="button"
                  className="cc-attention__mark"
                  onClick={() => entries.markMentionRead(e.id, me)}
                >
                  Mark as read
                </button>
              </Card>
            ))}
          </Section>
        )}

        {followups.length > 0 && (
          <Section title="Follow-ups needed" count={followups.length}>
            {followups.map((e) => (
              <Card key={e.id} variant="elevated" padding={16}>
                <EntryRow
                  entry={e}
                  density="card"
                  onEdit={onEdit}
                  onOpenMember={onOpenMember}
                />
              </Card>
            ))}
          </Section>
        )}

        {pinned.length > 0 && (
          <Section title="Pinned" count={pinned.length}>
            {pinned.map((e) => (
              <Card key={e.id} variant="elevated" padding={16}>
                <EntryRow
                  entry={e}
                  density="card"
                  onEdit={onEdit}
                  onOpenMember={onOpenMember}
                />
              </Card>
            ))}
          </Section>
        )}

        {decisions.length > 0 && (
          <Section title="Decisions" count={decisions.length}>
            {decisions.map((e) => (
              <Card key={e.id} variant="elevated" padding={16}>
                <EntryRow
                  entry={e}
                  density="card"
                  onEdit={onEdit}
                  onOpenMember={onOpenMember}
                />
              </Card>
            ))}
          </Section>
        )}
      </div>
    );
  }

  function Section({ title, count, children }) {
    return (
      <section className="cc-attention__section">
        <h2 className="cc-section-h2">
          {title}{" "}
          <span className="cc-section-h2__count">{count}</span>
        </h2>
        <div className="cc-attention__list">{children}</div>
      </section>
    );
  }

  // ────────────────────────────────────────────────────────────
  // Search view
  // ────────────────────────────────────────────────────────────
  function SearchView({ onOpenMember, onEdit }) {
    const [q, setQ] = useState("");
    const [results, setResults] = useState({ members: [], entries: [], events: [], meetings: [] });
    const [pending, setPending] = useState(false);

    useEffect(() => {
      search.init();
    }, []);

    useEffect(() => {
      if (!q || q.length < 2) {
        setResults({ members: [], entries: [], events: [], meetings: [] });
        return;
      }
      let cancelled = false;
      setPending(true);
      search.query(q).then((r) => {
        if (!cancelled) {
          setResults(r);
          setPending(false);
        }
      });
      return () => {
        cancelled = true;
      };
    }, [q]);

    const empty =
      q.length >= 2 &&
      !pending &&
      results.members.length === 0 &&
      results.entries.length === 0;

    return (
      <div className="cc-search">
        <Input
          icon={Icons.search(16)}
          value={q}
          onChange={setQ}
          placeholder="Search everything"
          autoFocus
        />
        {pending && <div style={{ padding: 24, textAlign: "center" }}><LoadingSpinner /></div>}
        {empty && (
          <EmptyState title={`Nothing matches "${q}"`} subtitle="Try shorter terms." />
        )}
        {results.members.length > 0 && (
          <Section title="Members" count={results.members.length}>
            <ul className="cc-members__list">
              {results.members.map((m) => (
                <MemberRow
                  key={m.row_id}
                  member={m}
                  onClick={() => onOpenMember(m)}
                />
              ))}
            </ul>
          </Section>
        )}
        {results.entries.length > 0 && (
          <Section title="Entries" count={results.entries.length}>
            {results.entries.map((e) => (
              <EntryRow
                key={e.id}
                entry={e}
                density="card"
                onEdit={onEdit}
                onOpenMember={onOpenMember}
              />
            ))}
          </Section>
        )}
      </div>
    );
  }

  window.CC = window.CC || {};
  window.CC.KnowledgeHub = KnowledgeHub;
})();
