(function attachAxisAuthBootstrap(root) {
  'use strict';

  function localContext() {
    return Object.freeze({
      mode: 'local', userId: 'local-user', email: 'local@axis.invalid', displayName: 'Local workspace',
      workspaceId: 'local-workspace', workspaceName: 'Local Workspace', role: 'owner'
    });
  }

  function iconLock() {
    return <svg aria-hidden="true" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="10" width="16" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>;
  }

  function AuthFrame({ children }) {
    return (
      <main className="axis-auth-page">
        <section className="axis-auth-story" aria-label="Axis Performance">
          <div className="axis-auth-brand"><span className="axis-auth-mark">A</span><span><strong>Axis</strong><small>Performance</small></span></div>
          <div className="axis-auth-story-copy">
            <p className="axis-auth-eyebrow">Sports science workspace</p>
            <h1>让数据进入决策，而不是停在表格。</h1>
            <p>统一运动员档案、监控摘要与审核工作流，同时把原始测力台曲线和个人知识资料留在当前设备。</p>
          </div>
          <div className="axis-auth-boundary">{iconLock()}<span>云端同步：账号、权限、花名册与结构化摘要<br/>本地保留：原始曲线、源文件、知识库与 AI 私有记忆</span></div>
        </section>
        <section className="axis-auth-main">{children}</section>
      </main>
    );
  }

  function LoginPanel({ gateway, onAuthenticated }) {
    const [email, setEmail] = React.useState('');
    const [password, setPassword] = React.useState('');
    const [visible, setVisible] = React.useState(false);
    const [busy, setBusy] = React.useState(false);
    const [error, setError] = React.useState('');
    const emailRef = React.useRef(null);

    React.useEffect(() => { if (emailRef.current) emailRef.current.focus(); }, []);

    async function submit(event) {
      event.preventDefault();
      setError('');
      if (!email.trim() || !password) {
        setError('请输入邮箱与密码。');
        if (!email.trim() && emailRef.current) emailRef.current.focus();
        return;
      }
      setBusy(true);
      try {
        await onAuthenticated(await gateway.signIn({ email, password }));
      } catch (reason) {
        var message = String(reason && reason.message || '');
        setError(/工作区权限/.test(message) ? message : '无法登录。请检查邮箱、密码和网络连接。');
      } finally { setBusy(false); }
    }

    return (
      <div className="axis-auth-panel">
        <header><h2>登录工作区</h2><p>使用管理员分配的账号继续。公开注册在受控 MVP 阶段保持关闭。</p></header>
        <form className="axis-auth-form" onSubmit={submit} noValidate>
          <div className="axis-auth-field">
            <label htmlFor="axis-auth-email">邮箱</label>
            <input ref={emailRef} id="axis-auth-email" name="email" type="email" inputMode="email" autoComplete="email"
              value={email} onChange={event => setEmail(event.target.value)} aria-invalid={!!error && !email.trim()} />
          </div>
          <div className="axis-auth-field">
            <label htmlFor="axis-auth-password">密码</label>
            <div className="axis-auth-input-wrap">
              <input id="axis-auth-password" name="password" type={visible ? 'text' : 'password'} autoComplete="current-password"
                value={password} onChange={event => setPassword(event.target.value)} aria-invalid={!!error && !password}
                aria-describedby="axis-auth-error" data-password-visible={visible ? 'true' : undefined} />
              <button className="axis-auth-password-toggle" type="button" aria-pressed={visible} onClick={() => setVisible(value => !value)}>{visible ? '隐藏' : '显示'}</button>
            </div>
          </div>
          <p id="axis-auth-error" className="axis-auth-status" role="alert">{error}</p>
          <button className="axis-auth-submit" type="submit" disabled={busy}>{busy ? '正在验证…' : '登录'}</button>
        </form>
        <p className="axis-auth-help">忘记密码或尚未加入工作区？请联系工作区管理员。免费 MVP 暂不依赖不可靠的默认邮件重置通道。</p>
      </div>
    );
  }

  function StatePanel({ title, children, action }) {
    return <div className="axis-auth-panel axis-auth-state"><h2>{title}</h2>{children}{action}</div>;
  }

  function AuthApp({ config, gateway, onReady }) {
    const [state, setState] = React.useState({ kind: 'loading' });

    async function acceptContext(context) {
      var result = root.AxisLocalVaultOwnership.claim(context);
      if (result.state === 'conflict' || result.state === 'corrupt') { setState({ kind: 'vault', context, result }); return; }
      await onReady(context, gateway);
    }

    React.useEffect(() => {
      let live = true;
      gateway.currentContext().then(context => {
        if (!live) return;
        if (context) acceptContext(context); else setState({ kind: 'login' });
      }).catch(error => { if (live) setState({ kind: 'error', error }); });
      return () => { live = false; };
    }, []);

    if (state.kind === 'loading') return <AuthFrame><div className="axis-auth-panel axis-auth-state" role="status"><div className="axis-auth-spinner"/><h2>正在验证会话</h2><p>正在确认账号和工作区权限。</p></div></AuthFrame>;
    if (state.kind === 'error') return <AuthFrame><StatePanel title="云端登录暂不可用"><p>{String(state.error && state.error.message || state.error)}</p><button className="axis-auth-secondary" onClick={() => root.location.reload()}>重新加载</button></StatePanel></AuthFrame>;
    if (state.kind === 'vault') return <AuthFrame><StatePanel title="此设备属于另一个本地工作区"><p>为避免原始曲线、知识库或 AI 私有资料串到当前账号，Axis 已停止加载。请先使用原账号导出本地备份，或清除这台设备上的 Axis 本地数据。</p><button className="axis-auth-secondary axis-auth-danger" onClick={async () => {
      if (!root.confirm('这会永久删除当前浏览器中的 Axis 本地数据，包括原始测力台曲线和个人知识库。确认继续？')) return;
      try { await root.AxisLocalVaultOwnership.clearAndClaim(state.context); await onReady(state.context, gateway); }
      catch (error) { setState({ kind: 'error', error }); }
    }}>清除本地数据并切换账号</button></StatePanel></AuthFrame>;
    return <AuthFrame><LoginPanel gateway={gateway} onAuthenticated={acceptContext}/></AuthFrame>;
  }

  let authRoot = null;
  let booted = false;

  async function finish(context, gateway, onAuthenticated) {
    if (booted) return;
    booted = true;
    root.AxisAuthRuntime = Object.freeze({
      getContext: function () { return context; },
      can: function (capability) { return root.AxisPermissionModel.can(context.role, capability); },
      capabilities: function () { return root.AxisPermissionModel.capabilities(context.role); },
      listMembers: function () {
        if (!gateway || !gateway.listMembers) return Promise.resolve([]);
        return gateway.listMembers(context.workspaceId);
      },
      updateMemberRole: function (membershipId, role) {
        if (!gateway || !gateway.updateMemberRole) throw new Error('本地模式不提供成员角色管理。');
        return gateway.updateMemberRole({ membershipId: membershipId, workspaceId: context.workspaceId, role: role });
      },
      syncStructuredSnapshot: function (athletes) {
        if (!gateway || !gateway.syncStructuredSnapshot) throw new Error('云端结构化同步尚未启用。');
        if (!root.AxisPermissionModel.can(context.role, 'athletes.write')) throw new Error('当前角色没有上传运动员结构化数据的权限。');
        return gateway.syncStructuredSnapshot({ athletes: athletes, context: context });
      },
      signOut: async function () {
        if (gateway && gateway.signOut) await gateway.signOut();
        root.location.reload();
      }
    });
    if (authRoot) { authRoot.unmount(); authRoot = null; }
    await onAuthenticated(context);
  }

  async function start(request) {
    var config = root.AXIS_CLOUD_CONFIG || {};
    if (!request || typeof request.onAuthenticated !== 'function') throw new Error('Axis auth bootstrap requires onAuthenticated.');
    if (config.mode === 'local') {
      var context = localContext();
      root.AxisLocalVaultOwnership.claim(context);
      await finish(context, null, request.onAuthenticated);
      return;
    }
    if (config.mode === 'preview') {
      var previewGateway = Object.freeze({
        currentContext: async function () { return null; },
        signIn: async function () { throw new Error('Preview mode does not transmit credentials.'); },
        signOut: async function () {}
      });
      authRoot = ReactDOM.createRoot(document.getElementById('root'));
      authRoot.render(<AuthApp config={config} gateway={previewGateway} onReady={(context) => finish(context, previewGateway, request.onAuthenticated)}/>);
      return;
    }
    var mount = document.getElementById('root');
    if (!mount) throw new Error('Axis auth mount is missing.');
    if (!config.supabaseUrl || !config.supabasePublishableKey) {
      authRoot = ReactDOM.createRoot(mount);
      authRoot.render(<AuthFrame><StatePanel title="云端环境尚未配置"><p>此公网部署已锁定，未配置 Supabase URL 与 publishable key 前不会加载运动员数据。</p></StatePanel></AuthFrame>);
      return;
    }
    try {
      var gateway = await root.AxisSupabaseAuthGateway.create(config);
      authRoot = ReactDOM.createRoot(mount);
      authRoot.render(<AuthApp config={config} gateway={gateway} onReady={(context) => finish(context, gateway, request.onAuthenticated)}/>);
    } catch (error) {
      authRoot = ReactDOM.createRoot(mount);
      authRoot.render(<AuthFrame><StatePanel title="无法启动登录"><p>{String(error && error.message || error)}</p></StatePanel></AuthFrame>);
    }
  }

  root.AxisAuthBootstrap = Object.freeze({ start });
})(window);
