// app.jsx — root of the Yenda v3 SPA.
//   1. Boots Firebase Auth + waits for first state tick.
//   2. If not signed in → SignIn screen.
//   3. If signed in → bootstrapSession (server validates user has shifts on file).
//   4. Routes by role:
//        admin / teamLead → v3 team-lead dashboard
//        annotator        → /me view (My Dashboard + Shifts & Payments)

const { useState: aUseState, useEffect: aUseEffect } = React;

// Catches render-time errors anywhere below it and shows a visible card
// instead of going blank. Class component because hooks don't expose a
// getDerivedStateFromError equivalent. Wrap each tab so a buggy tab
// doesn't take down the whole shell.
class TabErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }
  static getDerivedStateFromError(error) { return { error }; }
  componentDidCatch(error, info) {
    // eslint-disable-next-line no-console
    console.error('Tab render error:', error, info);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.tabKey !== this.props.tabKey && this.state.error) {
      this.setState({ error: null });
    }
  }
  render() {
    if (!this.state.error) return this.props.children;
    return (
      <div className="page">
        <div className="card">
          <div className="card-bd" style={{ color: '#b91c1c' }}>
            <strong>Something went wrong rendering this page.</strong>
            <div style={{ marginTop: 6, fontSize: 12, fontFamily: 'monospace', color: '#7f1d1d' }}>
              {String(this.state.error.message || this.state.error)}
            </div>
            <div style={{ marginTop: 8, fontSize: 12 }}>
              Open the browser console (F12) for the full stack. Switch tabs to retry, or refresh the page.
            </div>
          </div>
        </div>
      </div>
    );
  }
}

function SignIn({ error }) {
  const [busy, setBusy] = aUseState(false);
  const [localErr, setLocalErr] = aUseState(null);

  const handleSignIn = async () => {
    setBusy(true);
    setLocalErr(null);
    try {
      await window.YDApp.signIn();
      // onAuthStateChanged in App.tsx will pick it up.
    } catch (e) {
      setLocalErr(e.message || String(e));
      setBusy(false);
    }
  };

  return (
    <div className="signin-shell">
      <div className="signin-bg-orb signin-bg-orb-mint"/>
      <div className="signin-bg-orb signin-bg-orb-coral"/>
      <div className="signin-card">
        <div className="signin-brand">
          <img src="/img/yenda-mark.png" alt="" width="22" height="22" style={{ borderRadius: '50%' }}/>
          <img src="/img/yenda-wordmark.svg" alt="Yenda" height="22"/>
        </div>
        <h1>Welcome back</h1>
        <p className="signin-sub">Team performance, clock-in triage, and payment tracking — all in one place.</p>
        <button className="signin-btn" onClick={handleSignIn} disabled={busy}>
          <svg width="16" height="16" viewBox="0 0 18 18" style={{ display: 'inline-block', verticalAlign: 'middle', marginRight: 2 }}>
            <path fill="#fff" d="M17.64 9.2c0-.64-.06-1.25-.17-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.71v2.26h2.92a8.78 8.78 0 0 0 2.68-6.61z"/>
            <path fill="#fff" d="M9 18c2.43 0 4.47-.81 5.96-2.18l-2.92-2.26a5.4 5.4 0 0 1-3.04.85 5.4 5.4 0 0 1-5.07-3.74H.96v2.34A9 9 0 0 0 9 18z" opacity=".75"/>
            <path fill="#fff" d="M3.93 10.71A5.4 5.4 0 0 1 3.64 9c0-.59.1-1.16.29-1.71V4.96H.96a9 9 0 0 0 0 8.07l2.97-2.32z" opacity=".55"/>
            <path fill="#fff" d="M9 3.58c1.32 0 2.5.45 3.44 1.34l2.58-2.58A9 9 0 0 0 9 0a9 9 0 0 0-8.04 4.96l2.97 2.33A5.4 5.4 0 0 1 9 3.58z" opacity=".35"/>
          </svg>
          {busy ? 'Signing in…' : 'Continue with Google'}
        </button>
        <div className="signin-foot">
          Use your work email. Access is granted to staff with a shift schedule on file.
        </div>
        {(localErr || error) && (
          <div className="signin-error">{localErr || error}</div>
        )}
      </div>
    </div>
  );
}

function BootScreen({ label }) {
  return (
    <div className="boot-screen">
      <div style={{ textAlign: 'center' }}>
        <div className="spinner"/>
        <div className="meta">{label || 'Loading…'}</div>
      </div>
    </div>
  );
}

function LeadShell({ session }) {
  const [tab, setTab] = aUseState('overview');
  // Admins can pivot the whole dashboard to a specific project. null = use
  // the caller's own team via getTeamData (works for both leads and
  // admins-on-their-own-team). When set, useTeamData routes to
  // getTeamDataAdmin. Team leads never get the picker, so this stays null
  // for them.
  const [selectedTeam, setSelectedTeam] = aUseState(null);
  // Cross-tab requests — set by Overview triage tiles to land on Roster
  // with a severity pre-filtered. Cleared in TabRoster after consumption
  // so a second click on the same tile re-applies it.
  const [rosterSev, setRosterSev] = aUseState(null);
  const goToRoster = (sev) => {
    setRosterSev(sev || null);
    setTab('roster');
  };
  const state = window.YDLoader.useTeamData(0, selectedTeam);

  if (state.loading && !state.data) return <BootScreen label="Loading team data…"/>;
  if (state.error) {
    return (
      <div className="ydx app-shell">
        <main className="app-main">
          <div className="app-main-inner">
            <div className="app-error">
              <strong>Failed to load team data.</strong>
              <div style={{ marginTop: 8 }}>{state.error}</div>
              <button className="btn" style={{ marginTop: 14 }} onClick={state.refresh}>Retry</button>
            </div>
          </div>
        </main>
      </div>
    );
  }

  const tabs = {
    overview:    () => <TabOverview setTab={setTab} goToRoster={goToRoster} weekOffset={state.weekOffset} setWeekOffset={state.setWeekOffset}/>,
    clockin:     () => <TabClockin/>,
    performance: () => <TabPerformance weekOffset={state.weekOffset} setWeekOffset={state.setWeekOffset}/>,
    roster:      () => <TabRoster initialSev={rosterSev} clearInitialSev={() => setRosterSev(null)}/>,
    actionlog:   () => <TabActionLog refresh={state.refresh}/>,
    requests:    () => <TabRequests viewer={session}/>,
    pl:          () => <TabPL/>,
    quality:     () => <TabQuality/>,
    admin:       () => <TabAdmin/>,
  };
  const Tab = tabs[tab] || tabs.overview;

  return (
    <div className="ydx app-shell">
      <Sidebar
        tab={tab}
        setTab={setTab}
        viewer={session}
        selectedTeam={selectedTeam}
        setSelectedTeam={setSelectedTeam}
        lastLoadedAt={state.lastLoadedAt}
        refreshing={state.loading}
        onRefresh={state.refresh}/>
      <main className="app-main">
        <div className="app-main-inner">
          <TabErrorBoundary tabKey={tab}>
            <Tab/>
          </TabErrorBoundary>
        </div>
      </main>
    </div>
  );
}

function App() {
  const [session, setSession] = aUseState(null);   // bootstrap response
  const [signInError, setSignInError] = aUseState(null);
  const [authState, setAuthState] = aUseState({ user: null, ready: false });

  // Listen for auth state changes.
  aUseEffect(() => {
    const unsub = window.YDApp.auth.onAuthStateChanged((user) => {
      setAuthState({ user, ready: true });
      if (!user) {
        setSession(null);
        setSignInError(null);
      }
    });
    return unsub;
  }, []);

  // Bootstrap the server session whenever a user signs in.
  aUseEffect(() => {
    if (!authState.user) return;
    setSignInError(null);
    window.YDApp.bootstrapSession()
      .then((resp) => {
        // Force a token refresh if the server re-minted claims, then store.
        const need = resp.claimsRefreshed === true;
        if (need) authState.user.getIdToken(true).then(() => setSession(resp));
        else setSession(resp);
      })
      .catch((err) => {
        // Common path: user signs in with an unauthorized email.
        setSignInError(err.message || String(err));
        // Sign them out so they see the gate, not a blank screen.
        window.YDApp.auth.signOut();
      });
  }, [authState.user]);

  if (!authState.ready) return <BootScreen label="Initializing…"/>;
  if (!authState.user) return <SignIn error={signInError}/>;
  if (!session) return <BootScreen label="Loading your session…"/>;

  // Annotators get the /me view; lead/admin get the team dashboard.
  if (session.role === 'admin' || session.role === 'teamLead') {
    return <LeadShell session={session}/>;
  }
  return <MeApp session={session}/>;
}

const rootEl = document.getElementById('root');
ReactDOM.createRoot(rootEl).render(<App/>);
