// screens/account.jsx — My account: who you are signed in as, and the connection that
// acts in your name (your own Atlassian account, 0027).
//
// The Atlassian row used to live in the sidebar foot. It had to be reachable from every
// screen, because the grant is between Atlassian and the person and nobody can make it
// for them, and this app had no page for a person's own settings. It is still reachable
// from every screen, through the account menu at the foot of the sidebar, which opens
// this page; the sidebar goes back to being navigation. The vulnerability comment box
// also points here when a comment would otherwise reach Jira under the integration.

// Remembered across the Atlassian round trip. The callback always lands on
// /vulnerability_ledger (IntegrationsController.OAuthCallback), so a connection started
// here has to say where to come back to; app.jsx reads this in its initial view.
const ATL_RETURN_KEY = "vc_atl_return";

// Atlassian keeps a grant until the person removes it on their own profile. There is no
// revoke endpoint for 3LO, so Disconnect here can only forget this product's copy.
const ATL_MANAGE_URL = "https://id.atlassian.com/manage-profile/apps";

// Open My account from anywhere, including files that cannot reach App's nav(): the
// same path a Back button would take, so App's popstate handler does the routing.
function openMyAccount() {
  history.pushState(null, "", "/account");
  window.dispatchEvent(new PopStateEvent("popstate"));
}

function acctRole(auth) {
  if (auth.role) return auth.role;
  return auth.isAdmin ? "Super admin" : auth.isCompanyAdmin ? "Company admin" : "Analyst";
}

function AccountScreen({ auth, atl, onRefreshAtl, onToast, onSignOut }) {
  return (
    <div className="page acct">
      <div className="page-head">
        <div>
          <span className="eyebrow">Account</span>
          <h1 className="page-title">My account</h1>
          <p className="page-desc">Who you are signed in as, and the connection that acts in your name.</p>
        </div>
      </div>

      <div className="acct-grid">
        <section className="card acct-card" aria-labelledby="acct-profile">
          <div className="acct-card-head">
            <h2 id="acct-profile" className="acct-card-title">Profile</h2>
          </div>
          <div className="acct-id">
            <span className="acct-avatar" aria-hidden="true">{initials(auth.name)}</span>
            <div className="acct-id-txt">
              <strong>{auth.name}</strong>
              {auth.handle && auth.handle !== auth.name && <span className="mono">{auth.handle}</span>}
            </div>
          </div>
          <dl className="acct-dl">
            <div><dt>Organisation</dt><dd>{auth.companyName || auth.org || "—"}</dd></div>
            <div><dt>Role</dt><dd>{acctRole(auth)}</dd></div>
          </dl>
          <div className="acct-actions">
            <button className="btn btn-sm btn-danger-outline" type="button" onClick={onSignOut}>
              <Icon name="logout" size={14} />Sign out
            </button>
          </div>
        </section>

        {FEATURES.jira && <AtlassianConnectionCard atl={atl} onRefresh={onRefreshAtl} onToast={onToast} />}
      </div>
    </div>
  );
}

// Your Atlassian account, in every state /oauth/me can report. Each state says what it
// means for the comments you write, because that is the only thing this connection
// changes: status, owners, due dates and evidence always go out as the integration.
function AtlassianConnectionCard({ atl, onRefresh, onToast }) {
  const [busy, setBusy] = useState(false);
  const [confirming, setConfirming] = useState(false);

  async function connect() {
    setBusy(true);
    try { sessionStorage.setItem(ATL_RETURN_KEY, "account"); } catch (_) {}
    try {
      await window.VCApi.jiraOAuthConnect();            // navigates away on success
    } catch (e) {
      try { sessionStorage.removeItem(ATL_RETURN_KEY); } catch (_) {}
      onToast((e && e.message) || "Could not start the Atlassian connection.");
      setBusy(false);
    }
  }
  async function disconnect() {
    setBusy(true);
    try {
      const r = await window.VCApi.jiraOAuthDisconnect();
      onToast((r && r.detail) || "Atlassian disconnected here.");
      await onRefresh();
    } catch (e) {
      onToast((e && e.message) || "Could not disconnect.");
    } finally { setBusy(false); setConfirming(false); }
  }

  let tone = "off", badge = "Not connected", body = null, actions = null;
  if (atl === null) {
    tone = "wait"; badge = "Checking…";
    body = <p className="acct-note">Reading your Atlassian connection…</p>;
  } else if (!atl.available) {
    tone = "off"; badge = "Not available";
    body = (
      <p className="acct-note">
        {atl.reason === "company"
          ? "Jira is connected per company, and this account does not belong to one."
          : "This deployment has no Atlassian app configured, so comments always reach Jira as the integration account."}
      </p>
    );
  } else if (atl.connected) {
    tone = "on"; badge = "Connected";
    body = (
      <>
        <p className="acct-note">
          {atl.inUse
            ? "Comments you write here appear in Jira under your own name."
            : "Your company currently posts comments as the integration account, so this connection is not being used. It will be as soon as an admin turns on “Post comments as the person who wrote them”."}
        </p>
        <dl className="acct-dl">
          {atl.siteUrl && <div><dt>Jira site</dt><dd className="mono">{String(atl.siteUrl).replace(/^https?:\/\//, "")}</dd></div>}
          {atl.connectedAt && <div><dt>Connected</dt><dd className="mono">{String(atl.connectedAt).slice(0, 10)}</dd></div>}
        </dl>
      </>
    );
    actions = confirming ? (
      <>
        <span className="acct-confirm">This product forgets your tokens. Atlassian keeps the grant until you remove it there.</span>
        <button className="btn btn-sm" type="button" disabled={busy} onClick={() => setConfirming(false)}>Cancel</button>
        <button className="btn btn-sm btn-danger-outline" type="button" disabled={busy} onClick={disconnect}>
          {busy ? <span className="btn-spin" /> : null}Disconnect
        </button>
      </>
    ) : (
      <button className="btn btn-sm btn-danger-outline" type="button" onClick={() => setConfirming(true)}>Disconnect</button>
    );
  } else {
    // A lapsed grant says why: the button looks identical to a first connection, and
    // "nothing happened" is the worst thing it could say.
    tone = atl.inUse ? "warn" : "off";
    badge = atl.lastError ? "Needs reconnecting" : "Not connected";
    body = (
      <p className="acct-note">
        {atl.lastError
          ? atl.lastError
          : atl.inUse
            ? "Your company posts Jira comments under the author's name. Until you connect, comments you write here reach Jira as the integration account."
            : "Your company posts comments as the integration account, so you do not need this yet. You can connect now and it will be used as soon as an admin turns on “Post comments as the person who wrote them”."}
      </p>
    );
    actions = (
      <button className={"btn btn-sm" + (atl.inUse ? " btn-accent" : "")} type="button" disabled={busy} onClick={connect}>
        {busy ? <span className="btn-spin" /> : <Icon name="link" size={14} />}Connect Atlassian
      </button>
    );
  }

  return (
    <section className="card acct-card" aria-labelledby="acct-atl">
      <div className="acct-card-head">
        <h2 id="acct-atl" className="acct-card-title">Atlassian account</h2>
        <span className={"acct-badge is-" + tone}>{badge}</span>
      </div>
      <p className="acct-lead">
        Lets comments you write here appear in Jira under your name instead of the
        integration account's. Only you can connect it: the grant is between you and
        Atlassian, so an admin cannot do it for you.
      </p>
      {body}
      <div className="acct-actions">
        {actions}
        {atl && atl.available && (
          <a className="acct-link" href={ATL_MANAGE_URL} target="_blank" rel="noopener noreferrer">
            Manage at Atlassian<Icon name="ext" size={12} />
          </a>
        )}
      </div>
    </section>
  );
}

Object.assign(window, { AccountScreen, openMyAccount, ATL_RETURN_KEY });
