import type { ReactNode } from "react";
import { getIntegrationConfig, getProfile } from "@/lib/integrations";
import { SOCIAL_NETWORKS } from "@/lib/integrations/social";
import type { SocialLink } from "@/lib/integrations/types";
import {
  saveIntegrationsAction,
  refreshIntegrationsAction,
  testIntegrationAction,
} from "../../actions";
import ConsolePicker from "./ConsolePicker";
import GamePicker from "./GamePicker";

// Expandable "how do I get this?" help, shown under credential fields. Uses a
// native <details> so it works with zero JS and stays readable on mobile.
function CredHelp({ title, children }: { title: string; children: ReactNode }) {
  return (
    <details className="rb-cred-help">
      <summary>ⓘ {title}</summary>
      <div className="rb-cred-help-body">{children}</div>
    </details>
  );
}

// A "Test connection" submit button. Submits the whole form to the test action
// (so it validates the live, unsaved field values) tagged with which platform.
function TestButton({ platform }: { platform: string }) {
  return (
    <button
      type="submit"
      className="rb-btn rb-btn-ghost"
      formAction={testIntegrationAction.bind(null, platform)}
      formNoValidate
    >
      Test connection
    </button>
  );
}

function socialToText(links: SocialLink[]): string {
  return links
    .map((l) => [l.network, l.url, l.label].filter(Boolean).join(" | "))
    .join("\n");
}

function fmtAge(iso: string): string {
  const t = new Date(iso).getTime();
  if (Number.isNaN(t)) return "—";
  const mins = Math.round((Date.now() - t) / 60000);
  if (mins < 1) return "just now";
  if (mins < 60) return `${mins} min ago`;
  const hrs = Math.round(mins / 60);
  return hrs < 24 ? `${hrs}h ago` : `${Math.round(hrs / 24)}d ago`;
}

type Banners = {
  saved?: string;
  refreshed?: string;
  steam?: string;
  steamErr?: string;
  test?: string;
  testErr?: string;
  testGames?: string;
  testNotice?: string;
};

function Banner(p: Banners) {
  if (p.saved) return <p className="rb-admin-ok">Integrations saved. Caches cleared.</p>;
  if (p.refreshed)
    return <p className="rb-admin-ok">Platform caches cleared — data refetches on next view.</p>;
  if (p.steam)
    return (
      <p className="rb-admin-ok">
        Steam linked — SteamID <code>{p.steam}</code> saved. Add your API key below to pull
        game data.
      </p>
    );
  if (p.steamErr) return <p className="rb-admin-error">{p.steamErr}</p>;
  if (p.test && p.testErr)
    return (
      <p className="rb-admin-error">
        {p.test.toUpperCase()} test failed: {p.testErr}
      </p>
    );
  if (p.test)
    return (
      <p className={p.testNotice ? "rb-admin-warn" : "rb-admin-ok"}>
        {p.test.toUpperCase()} connection OK — fetched {p.testGames ?? 0} game(s).
        {p.testNotice ? ` ${p.testNotice}` : ""}
      </p>
    );
  return null;
}

export default async function IntegrationsPage({
  searchParams,
}: {
  searchParams: Promise<Banners>;
}) {
  const banners = await searchParams;
  const cfg = getIntegrationConfig();
  // Loads (cached) platform data so we can show freshness + any fetch errors.
  const profile = await getProfile();
  const networkIds = SOCIAL_NETWORKS.map((n) => n.id).join(", ");

  return (
    <div className="rb-admin-page">
      <h1 className="rb-admin-h1">Integrations</h1>
      <Banner {...banners} />
      <p className="rb-admin-muted">
        Build your gamer bio: a profile, social links, console list, favorite
        games, and live data pulled from gaming platforms. Everything here powers
        the public <a href="/bio" target="_blank">bio page</a>.
      </p>

      {/* ---- platform status ---- */}
      {profile.platforms.length > 0 && (
        <div className="rb-admin-card">
          <h2 className="rb-admin-h2">Platform status</h2>
          <table className="rb-admin-table">
            <thead>
              <tr>
                <th>Platform</th>
                <th>Games</th>
                <th>Achievements</th>
                <th>Fetched</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              {profile.platforms.map((p) => (
                <tr key={p.platform}>
                  <td>{p.platform.toUpperCase()}</td>
                  <td>{p.games.length}</td>
                  <td>{p.achievements.length}</td>
                  <td>{fmtAge(p.fetchedAt)}</td>
                  <td>
                    {p.error ? (
                      <span className="rb-admin-error" style={{ margin: 0 }}>
                        {p.error}
                      </span>
                    ) : (
                      "OK"
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          <form action={refreshIntegrationsAction} className="rb-form-actions">
            <button className="rb-btn" type="submit">
              Refresh now
            </button>
          </form>
        </div>
      )}

      <form className="rb-admin-card" action={saveIntegrationsAction}>
        {/* ---- profile ---- */}
        <h2 className="rb-admin-h2">Profile</h2>
        <div className="rb-field-row">
          <label className="rb-field">
            <span>Display name</span>
            <input name="displayName" defaultValue={cfg.displayName} />
          </label>
          <label className="rb-field">
            <span>Avatar image URL</span>
            <input name="avatarUrl" defaultValue={cfg.avatarUrl} placeholder="https://…" />
          </label>
        </div>
        <label className="rb-field">
          <span>
            Bio <em className="rb-admin-muted">(Markdown)</em>
          </span>
          <textarea name="bio" rows={4} className="rb-mono" defaultValue={cfg.bio} />
        </label>

        {/* ---- social links ---- */}
        <h2 className="rb-admin-h2">Social links</h2>
        <label className="rb-field">
          <span>
            One per line: <code>network|url|label</code>
            <em className="rb-admin-muted"> — networks: {networkIds}</em>
          </span>
          <textarea
            name="social"
            rows={4}
            className="rb-mono"
            placeholder={"github|https://github.com/me\nmastodon|https://mastodon.social/@me"}
            defaultValue={socialToText(cfg.social)}
          />
        </label>

        {/* ---- consoles + favorites ---- */}
        <h2 className="rb-admin-h2">Collection</h2>
        <div className="rb-field">
          <span>
            Consoles owned{" "}
            <em className="rb-admin-muted">— search and click to add</em>
          </span>
          <ConsolePicker name="consoles" initial={cfg.consoles} />
        </div>
        <div className="rb-field">
          <span>
            Favorite games{" "}
            <em className="rb-admin-muted">— search (Steam catalog) and click to add</em>
          </span>
          <GamePicker name="favorites" initial={cfg.favorites} />
        </div>

        {/* ---- platforms ---- */}
        <h2 className="rb-admin-h2">Steam</h2>
        <label className="rb-check">
          <input type="checkbox" name="steamEnabled" defaultChecked={cfg.steam.enabled} />
          <span>Enable Steam integration</span>
        </label>
        <p className="rb-admin-muted">
          One-click:{" "}
          <a className="rb-btn rb-btn-ghost rb-btn-inline" href="/admin/integrations/steam/link">
            Sign in with Steam
          </a>{" "}
          to fill your SteamID automatically{cfg.steam.steamId ? ` (current: ${cfg.steam.steamId})` : ""}.
          You still add an API key below for game data.
        </p>
        <div className="rb-field-row">
          <label className="rb-field">
            <span>
              API key{" "}
              <em className="rb-admin-muted">
                ({cfg.steam.apiKey ? "stored — blank keeps it" : "required for game data"})
              </em>
            </span>
            <input
              name="steamApiKey"
              type="password"
              autoComplete="off"
              placeholder={cfg.steam.apiKey ? "•••••••• stored" : ""}
            />
            <CredHelp title="How to get a Steam API key">
              <ol>
                <li>
                  Go to{" "}
                  <a href="https://steamcommunity.com/dev/apikey" target="_blank" rel="noreferrer">
                    steamcommunity.com/dev/apikey
                  </a>{" "}
                  (sign in if asked).
                </li>
                <li>Enter any domain name (e.g. <code>localhost</code>) and agree to the terms.</li>
                <li>Copy the generated key and paste it here.</li>
              </ol>
              <p>Your Steam profile must be set to <strong>Public</strong> for game data to load.</p>
            </CredHelp>
          </label>
          <label className="rb-field">
            <span>SteamID (64-bit)</span>
            <input name="steamId" defaultValue={cfg.steam.steamId} placeholder="7656119…" />
            <CredHelp title="How to find your SteamID">
              <ol>
                <li>Use the “Sign in with Steam” button above — easiest, fills it for you.</li>
                <li>
                  Or open{" "}
                  <a href="https://steamid.io" target="_blank" rel="noreferrer">
                    steamid.io
                  </a>
                  , paste your profile URL, and copy the <code>steamID64</code> value.
                </li>
              </ol>
            </CredHelp>
          </label>
        </div>
        <div className="rb-form-actions rb-form-actions-sub">
          <TestButton platform="steam" />
        </div>

        <h2 className="rb-admin-h2">PlayStation (PSN)</h2>
        <label className="rb-check">
          <input type="checkbox" name="psnEnabled" defaultChecked={cfg.psn.enabled} />
          <span>Enable PSN integration</span>
        </label>
        <label className="rb-field">
          <span>
            NPSSO token{" "}
            <em className="rb-admin-muted">
              ({cfg.psn.npsso ? "stored — blank keeps it" : "required"})
            </em>
          </span>
          <input
            name="psnNpsso"
            type="password"
            autoComplete="off"
            placeholder={cfg.psn.npsso ? "•••••••• stored" : "64-char token"}
          />
          <CredHelp title="How to get your NPSSO token">
            <ol>
              <li>
                Sign in at{" "}
                <a href="https://www.playstation.com" target="_blank" rel="noreferrer">
                  playstation.com
                </a>{" "}
                in your browser.
              </li>
              <li>
                In the same browser, open{" "}
                <a
                  href="https://ca.account.sony.com/api/v1/ssocookie"
                  target="_blank"
                  rel="noreferrer"
                >
                  ca.account.sony.com/api/v1/ssocookie
                </a>
                .
              </li>
              <li>
                Copy the 64-character value of <code>npsso</code> from the JSON shown and paste it
                here.
              </li>
            </ol>
            <p>The token expires periodically — re-paste a fresh one if PSN starts erroring.</p>
          </CredHelp>
        </label>
        <div className="rb-form-actions rb-form-actions-sub">
          <TestButton platform="psn" />
        </div>

        <h2 className="rb-admin-h2">Xbox</h2>
        <label className="rb-check">
          <input type="checkbox" name="xboxEnabled" defaultChecked={cfg.xbox.enabled} />
          <span>Enable Xbox integration</span>
        </label>
        <div className="rb-field-row">
          <label className="rb-field">
            <span>
              OpenXBL API key{" "}
              <em className="rb-admin-muted">
                ({cfg.xbox.apiKey ? "stored — blank keeps it" : "required"})
              </em>
            </span>
            <input
              name="xboxApiKey"
              type="password"
              autoComplete="off"
              placeholder={cfg.xbox.apiKey ? "•••••••• stored" : ""}
            />
            <CredHelp title="How to get an OpenXBL API key">
              <ol>
                <li>
                  Go to{" "}
                  <a href="https://xbl.io" target="_blank" rel="noreferrer">
                    xbl.io
                  </a>{" "}
                  and sign in with your Microsoft / Xbox account.
                </li>
                <li>Open the console / API keys page and generate a key.</li>
                <li>Copy the key and paste it here.</li>
              </ol>
              <p>Xbox has no official public API; OpenXBL is a third-party proxy.</p>
            </CredHelp>
          </label>
          <label className="rb-field">
            <span>
              XUID <em className="rb-admin-muted">(optional)</em>
            </span>
            <input name="xboxXuid" defaultValue={cfg.xbox.xuid} />
            <CredHelp title="Do I need a XUID?">
              <p>
                No — leave blank and OpenXBL uses the account tied to your API key. Only set this to
                read a <em>different</em> profile.
              </p>
            </CredHelp>
          </label>
        </div>
        <div className="rb-form-actions rb-form-actions-sub">
          <TestButton platform="xbox" />
        </div>

        <h2 className="rb-admin-h2">RetroAchievements</h2>
        <label className="rb-check">
          <input type="checkbox" name="retroEnabled" defaultChecked={cfg.retro.enabled} />
          <span>Enable RetroAchievements integration</span>
        </label>
        <div className="rb-field-row">
          <label className="rb-field">
            <span>Username</span>
            <input
              name="retroUsername"
              defaultValue={cfg.retro.username}
              placeholder="your RA username"
            />
          </label>
          <label className="rb-field">
            <span>
              Web API key{" "}
              <em className="rb-admin-muted">
                ({cfg.retro.apiKey ? "stored — blank keeps it" : "required"})
              </em>
            </span>
            <input
              name="retroApiKey"
              type="password"
              autoComplete="off"
              placeholder={cfg.retro.apiKey ? "•••••••• stored" : ""}
            />
            <CredHelp title="How to get a RetroAchievements API key">
              <ol>
                <li>
                  Sign in at{" "}
                  <a href="https://retroachievements.org" target="_blank" rel="noreferrer">
                    retroachievements.org
                  </a>
                  .
                </li>
                <li>
                  Open{" "}
                  <a
                    href="https://retroachievements.org/settings"
                    target="_blank"
                    rel="noreferrer"
                  >
                    Settings → Keys
                  </a>{" "}
                  and copy your <strong>Web API Key</strong>.
                </li>
                <li>Paste it here along with your username above.</li>
              </ol>
            </CredHelp>
          </label>
        </div>
        <div className="rb-form-actions rb-form-actions-sub">
          <TestButton platform="retro" />
        </div>

        {/* ---- cache ---- */}
        <h2 className="rb-admin-h2">Caching</h2>
        <label className="rb-field">
          <span>
            Refresh interval <em className="rb-admin-muted">(minutes)</em>
          </span>
          <input
            name="cacheTtlMinutes"
            type="number"
            min={1}
            defaultValue={cfg.cacheTtlMinutes}
          />
        </label>

        <div className="rb-form-actions">
          <button className="rb-btn rb-btn-primary" type="submit">
            Save integrations
          </button>
        </div>
      </form>
    </div>
  );
}
