/* global React, Icon, Badge, PageHeader, SectionHead */

// Hidden internal reference. Not in the NAV array — reachable only via the
// `#help` hash route (see parseHelpRequest in index.html), the same way the
// check-in and respond pages are surfaced. Pure static documentation sourced
// from the live code.
//
// Role-aware (see the `isAdmin` prop): members see a usage-only view — the pages
// they can reach plus how to connect the MCP server — while admins see the full
// maintainer reference. Admin-only pages, internal hash routes, server-side wiring,
// and any config/secrets are never rendered on the member view.

const HELP_ROUTES = [
  {
    id: 'dashboard',
    label: 'Dashboard',
    access: 'Everyone',
    blurb: 'Landing page. Club-wide stats, upcoming events, and quick links. Where the brand mark and "Dashboard" nav item both land.',
  },
  {
    id: 'attendance',
    label: 'Attendance',
    access: 'Everyone (admins run sessions)',
    blurb: 'Live check-in with a rotating QR code, plus attendance history. Admins start a session from a calendar event; members scan to check in.',
  },
  {
    id: 'calendar',
    label: 'Calendar',
    access: 'Everyone',
    blurb: 'Read-only view of the shared Google Calendar. Members submit event requests here; admins create or approve events (which open in Google to save).',
  },
  {
    id: 'availability',
    label: 'Availability',
    access: 'Everyone',
    blurb: 'Weekly when2meet-style grid (Mon–Sun, 30-minute slots, Ithaca local time). Members paint the times they are generally free and save; the group heat map shows when a chosen set of members overlaps and ranks the best windows.',
  },
  {
    id: 'members',
    label: 'Members',
    access: 'Everyone',
    blurb: 'Roster with member classes (active / alumni / abroad) and project-team assignments. Alumni and abroad members are excluded from active counts.',
  },
  {
    id: 'drive',
    label: 'Drive',
    access: 'Admin only',
    blurb: 'Browser for the shared Google Drive folder. Hidden from members for now — admins still set each file/folder to "Everyone" or "Admins only" (stored in drive_file_visibility), which is what filtering resumes from when it reopens to members.',
  },
  {
    id: 'projecthub / project:<id>',
    label: 'Project Hub',
    access: 'Admins see a hub; members see their teams',
    blurb: 'Per-team resources. An admin gets one "Project Hub" tab with a project switcher; a member gets one tab per project they are assigned to, plus any board open to the whole club (the InvestCorp ESG example) — those open ones are read-only unless you are on the team.',
  },
  {
    id: 'slack',
    label: 'Slack',
    access: 'Admin only',
    blurb: 'Catalog of Slack automations (e.g. the day-of event reminder) and the one-time bot setup steps. Read-only reference.',
  },
  {
    id: 'notifications',
    label: 'Notify',
    access: 'Admin only',
    blurb: 'Send messages or response-request forms to members and track who has seen / responded. Surfaces in the nav bell and the banner.',
  },
];

const HELP_HIDDEN_ROUTES = [
  {
    id: '#checkin/<sessionId>?t=<token>',
    blurb: 'Attendance check-in page a member opens by scanning the rotating session QR code.',
  },
  {
    id: '#respond/<notificationId>',
    blurb: 'Response form a member is deep-linked to from a response-request notification.',
  },
  {
    id: '#help',
    blurb: 'This page. Hidden from the nav on purpose — share the URL with maintainers only.',
  },
];

const HELP_DRIVE_STEPS = [
  {
    title: 'Create a Google Cloud service account',
    body: 'In Google Cloud Console, create (or reuse) a project, enable the Google Drive API, then create a service account. Generate a JSON key for it and download the file. The key contains a client_email and a private_key.',
  },
  {
    title: 'Give the server the credentials',
    body: 'Provide the key to the server one of three ways (checked in this order): the GOOGLE_SERVICE_ACCOUNT_KEY_JSON env var (the JSON inline — best for Railway), the GOOGLE_SERVICE_ACCOUNT_KEY_FILE path, or a creds/google_creds.json file. Never put any of this in env.js — it must stay server-side.',
  },
  {
    title: 'Share the Drive folder with the service account',
    body: 'A service account is its own Google identity, so it sees nothing by default. Open the shared CGAI Drive folder, Share it with the service account’s client_email, and grant Viewer. The server only ever requests the drive.readonly scope.',
  },
  {
    title: 'Point the app at the folder',
    body: 'Set GOOGLE_DRIVE_FOLDER_URL (paste the folder’s share link) or GOOGLE_DRIVE_FOLDER_ID in .env. Optionally set GOOGLE_DRIVE_FOLDER_MAX_DEPTH to limit how many nested levels are walked (default 5).',
  },
  {
    title: 'Restart and verify',
    body: 'Restart the app and open the Drive tab. The server mints a short-lived access token from the key (signed JWT, RS256) and lists the folder. If you see an auth error, re-check the folder share and that the key JSON has client_email + private_key.',
  },
  {
    title: 'Set per-file visibility (optional)',
    body: 'In admin view each row has a visibility dropdown: "Everyone" or "Admins only". Choices are stored in the drive_file_visibility table and filter what members see — the underlying Drive sharing is unchanged.',
  },
];

const HELP_CALENDAR_STEPS = [
  {
    title: 'Google Calendar is the source of truth',
    body: 'The app reads events from the shared Google Calendar (GOOGLE_CALENDAR_ID) and merges in locally-approved submissions. It never stores events itself — the in-app create/delete endpoints intentionally return 410. You add and edit events in Google Calendar, the app reflects them.',
  },
  {
    title: 'Admin: create an event',
    body: 'Calendar tab → "New session". Fill in title, date, time, location, and audience, then "Create in Google Calendar". That opens a pre-filled Google Calendar event template in a new tab — you save it there. Once Google has it, it shows up in the app on the next load.',
  },
  {
    title: 'Member: submit a request',
    body: 'Members (or admins in member view) use "Submit to communal calendar". The request is saved to calendar_event_submissions as pending — it does not touch Google yet.',
  },
  {
    title: 'Admin: approve or reject',
    body: 'Pending requests appear in the calendar sidebar under "Pending member submissions". Approve opens the same pre-filled Google template for you to save (then marks it approved); Reject discards it.',
  },
  {
    title: 'Configuration',
    body: 'GOOGLE_CALENDAR_ID selects the calendar; GOOGLE_CALENDAR_TIME_ZONE defaults to America/New_York. Set GOOGLE_API_KEY for private/faster reads via the Google API — without it, the server falls back to the calendar’s public iCal feed, so the calendar must be public for events to load.',
  },
];

// The two tools exposed by the MCP server (lib/mcp.js). Kept in sync with the
// registerTool descriptions there.
const HELP_MCP_TOOLS = [
  {
    name: 'list_subteams',
    body: 'Lists the subteams you can access — id, name, member count, and whether a Drive folder is linked. No arguments.',
  },
  {
    name: 'get_subteam',
    body: 'Full hub content for one subteam (by id or name): team name, the roster (name / role / class / email / LinkedIn), the hub page content (section notes, links, per-person to-do checklists), and the linked Drive file list. Content only — no ids, timestamps, or styling metadata. Optional includeDrive:false skips the Drive walk.',
  },
];

// Users only need to know what the server is and how to connect. The sign-in
// mechanics, access rules, and token configuration are maintainer concerns —
// tracked in tasks/mcp-subteam-server.md, not surfaced on the website.
const HELP_MCP_STEPS = [
  {
    title: 'What it is',
    body: 'A remote MCP (Model Context Protocol) server at POST /api/mcp that lets AI chat clients (Claude Code, Claude Desktop/web) query subteam hub data as structured JSON. Read-only.',
  },
  {
    title: 'Connect from Claude Code',
    body: 'Run: claude mcp add --transport http cgai https://ops.stuart-labs.com/api/mcp — then /mcp inside Claude Code → Authenticate. The client registers itself automatically and runs the Google/Cornell sign-in; the token is cached locally.',
  },
];

function HelpStep({ index, title, body }) {
  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: '32px 1fr',
      gap: 14,
      padding: '14px 18px',
      borderBottom: '1px solid var(--border-default)',
    }}>
      <div className="mono" style={{ fontSize: 12, color: 'var(--coral-700)', fontWeight: 700, paddingTop: 2 }}>
        {String(index + 1).padStart(2, '0')}
      </div>
      <div>
        <div style={{ fontWeight: 600, color: 'var(--steel-900)', marginBottom: 4 }}>{title}</div>
        <div className="muted" style={{ fontSize: 12.5, lineHeight: 1.55 }}>{body}</div>
      </div>
    </div>
  );
}

function HelpPage({ onExit, isAdmin }) {
  // Members get a usage-oriented view: only the pages they can actually reach, and the
  // MCP connect steps — but no admin-only pages, internal hash routes, server-side
  // wiring, or secrets. Admins get the full maintainer reference. Features hidden from
  // members are never described on the member view.
  const routes = isAdmin ? HELP_ROUTES : HELP_ROUTES.filter((route) => !/admin only/i.test(route.access));
  // MCP steps are user-facing only ("what it is" + "how to connect"); same for everyone.
  const mcpSteps = HELP_MCP_STEPS;

  return (
    <main className="app-main">
      <PageHeader
        eyebrow={isAdmin ? 'Internal · Reference' : 'Reference'}
        title="How this dashboard works"
        sub={isAdmin
          ? 'A hidden reference for maintainers: the page directory, how the Google integrations are wired, and the MCP server that exposes subteam data to AI chats.'
          : 'A quick reference: what each page does, and how to query your subteam data from an AI chat.'}
        actions={
          <button className="btn btn-ghost btn-sm" type="button" onClick={onExit}>
            <Icon name="arrow" size={13}/> Back to app
          </button>
        }
      />

      <SectionHead title="Page directory" meta={`${routes.length} routes`}/>
      <div className="card" style={{ padding: 0, overflow: 'hidden', marginBottom: 24 }}>
        <div className="table-scroll">
        <table className="tbl">
          <thead>
            <tr>
              <th style={{ width: 150 }}>Page</th>
              <th style={{ width: 170 }}>Route · access</th>
              <th>What it does</th>
            </tr>
          </thead>
          <tbody>
            {routes.map((route) => (
              <tr key={route.id}>
                <td><div style={{ fontWeight: 600, color: 'var(--steel-900)' }}>{route.label}</div></td>
                <td>
                  <div className="mono" style={{ fontSize: 11.5, color: 'var(--ink-500)' }}>{route.id}</div>
                  <div className="muted" style={{ fontSize: 11, marginTop: 3 }}>{route.access}</div>
                </td>
                <td><span className="muted" style={{ fontSize: 12.5, lineHeight: 1.5 }}>{route.blurb}</span></td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </div>

      {isAdmin && (
        <>
          <SectionHead title="Hidden routes" meta="Hash links, not in the nav"/>
          <div className="card" style={{ display: 'grid', gap: 12, marginBottom: 32 }}>
            {HELP_HIDDEN_ROUTES.map((route) => (
              <div key={route.id} className="row" style={{ gap: 12, alignItems: 'baseline' }}>
                <span className="mono" style={{ fontSize: 12, color: 'var(--coral-700)', minWidth: 230 }}>{route.id}</span>
                <span className="muted" style={{ fontSize: 12.5, lineHeight: 1.5 }}>{route.blurb}</span>
              </div>
            ))}
          </div>
        </>
      )}

      <SectionHead title="MCP server for AI chats" meta="Remote · OAuth 2.1"/>
      <div className="card" style={{ display: 'grid', gap: 14, marginBottom: 20 }}>
        <div className="muted" style={{ fontSize: 12.5, lineHeight: 1.6 }}>
          Query subteam hub data from an AI chat client through a remote MCP endpoint. Add it once per client;
          sign-in is your Cornell Google account, and you only ever see the subteams you can access in the app.
        </div>
        <div>
          <div style={{ fontWeight: 600, color: 'var(--steel-900)', marginBottom: 6 }}>Tools</div>
          {HELP_MCP_TOOLS.map((tool) => (
            <div key={tool.name} className="row" style={{ gap: 12, alignItems: 'baseline', marginBottom: 6 }}>
              <span className="mono" style={{ fontSize: 12, color: 'var(--coral-700)', minWidth: 120 }}>{tool.name}</span>
              <span className="muted" style={{ fontSize: 12.5, lineHeight: 1.5 }}>{tool.body}</span>
            </div>
          ))}
        </div>
        {isAdmin && (
          <div>
            <div style={{ fontWeight: 600, color: 'var(--steel-900)', marginBottom: 6 }}>Endpoints</div>
            <div className="mono" style={{ fontSize: 11.5, color: 'var(--ink-500)', lineHeight: 1.7 }}>
              POST /api/mcp · /oauth/authorize · /oauth/token · /oauth/register · /oauth/revoke<br/>
              /.well-known/oauth-authorization-server · /.well-known/oauth-protected-resource
            </div>
          </div>
        )}
      </div>
      <div className="card" style={{ padding: 0, overflow: 'hidden', marginBottom: isAdmin ? 32 : 8 }}>
        {mcpSteps.map((step, index) => (
          <HelpStep key={step.title} index={index} title={step.title} body={step.body}/>
        ))}
      </div>

      {isAdmin && (
        <>
          <div className="help-split">
            <div>
              <SectionHead title="Implementing Google Drive" meta="Server-side, one-time"/>
              <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
                {HELP_DRIVE_STEPS.map((step, index) => (
                  <HelpStep key={step.title} index={index} title={step.title} body={step.body}/>
                ))}
              </div>
            </div>

            <div>
              <SectionHead title="Adding events to the calendar" meta="Google is the source of truth"/>
              <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
                {HELP_CALENDAR_STEPS.map((step, index) => (
                  <HelpStep key={step.title} index={index} title={step.title} body={step.body}/>
                ))}
              </div>
            </div>
          </div>

          <div className="card" style={{ marginTop: 24, display: 'grid', gap: 6 }}>
            <div style={{ fontWeight: 600, color: 'var(--steel-900)' }}>Where config lives</div>
            <div className="muted" style={{ fontSize: 12.5, lineHeight: 1.6 }}>
              All secrets and config are read from <span className="mono">.env</span> on the server. The browser only
              gets non-secret values via <span className="mono">env.js</span>, regenerated with{' '}
              <span className="mono">npm run write-env</span> (whitelist in <span className="mono">scripts/write-env.js</span>).
              Never hand-edit <span className="mono">env.js</span>, and never put a secret in it.
            </div>
          </div>
        </>
      )}
    </main>
  );
}

window.HelpPage = HelpPage;
