/* Boot sequence (loaded last):
   1. Ask the server who we are.
   2. No session → show the login screen.
   3. Session → pick the active company, fetch its live dashboard, merge onto
      window.CB (preserving the helper fns from data.js), then render <App/>.
   Live data overwrites the mock arrays; opening the HTML without the backend
   still shows the mock as a preview. */

const CBNet = {
  async me() {
    const r = await fetch('/api/auth/me', { credentials: 'same-origin' });
    if (!r.ok) return null;
    return r.json();
  },
  async login(email, password) {
    const r = await fetch('/api/auth/login', {
      method: 'POST', credentials: 'same-origin',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password }),
    });
    if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || 'Login failed');
    return r.json();
  },
  async logout() { await fetch('/api/auth/logout', { method: 'POST', credentials: 'same-origin' }); },
  async companies() {
    const r = await fetch('/api/admin/companies', { credentials: 'same-origin' });
    if (!r.ok) return [];
    return r.json();
  },
  async dashboard(companyId, period) {
    const r = await fetch(`/api/company/${companyId}/dashboard?period=${period}`, { credentials: 'same-origin' });
    if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || `Request failed (${r.status})`);
    return r.json();
  },
};

function applyDashboard(data) {
  Object.keys(data).forEach((k) => { if (k !== '_meta') window.CB[k] = data[k]; });
}

let __activeCompanyId = null;

/* Used by <App/> when the period filter changes. */
window.__CB_LOAD_DASHBOARD = async (period = 'mtd') => {
  if (!__activeCompanyId) return null;
  const data = await CBNet.dashboard(__activeCompanyId, period);
  applyDashboard(data);
  return data;
};

window.__CB_LOGOUT = async () => { try { await CBNet.logout(); } finally { location.reload(); } };

/* ── UI screens ─────────────────────────────────────────────────────────── */

function LoginScreen({ onSuccess }) {
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [err, setErr] = React.useState(null);
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true); setErr(null);
    try {
      const { user } = await CBNet.login(email.trim(), password);
      onSuccess(user);
    } catch (ex) { setErr(ex.message); setBusy(false); }
  };

  return (
    <div className="cb-auth">
      <form className="cb-auth-card" onSubmit={submit}>
        <div className="cb-auth-brand">
          <span className="cb-brand-mark"><IconLogo size={20} /></span>
          <span className="cb-brand-name">contractor<i>books</i></span>
        </div>
        <h1 className="cb-auth-title">Sign in</h1>
        <p className="cb-auth-sub">Your live financial dashboard, straight from QuickBooks.</p>

        {err && <div className="cb-auth-err">{err}</div>}

        <label className="cb-auth-field">
          <span>Email</span>
          <input className="cb-input" type="email" autoComplete="username" required
                 value={email} onChange={(e) => setEmail(e.target.value)} />
        </label>
        <label className="cb-auth-field">
          <span>Password</span>
          <input className="cb-input" type="password" autoComplete="current-password" required
                 value={password} onChange={(e) => setPassword(e.target.value)} />
        </label>

        <button type="submit" className="cb-btn cb-btn-primary cb-btn-block" disabled={busy}>
          {busy ? 'Signing in…' : 'Sign in'}
        </button>
      </form>
    </div>
  );
}

function BootMessage({ title, body, children }) {
  return (
    <div className="cb-boot">
      <div className="cb-boot-card">
        <div className="cb-boot-spinner" />
        <h2>{title}</h2>
        {body && <p>{body}</p>}
        {children}
      </div>
    </div>
  );
}

function BootError({ message, onRetry, showConnect }) {
  return (
    <div className="cb-boot">
      <div className="cb-boot-card cb-boot-error">
        <span className="cb-placeholder-ico"><IconAlert size={26} /></span>
        <h2>Couldn't load your dashboard</h2>
        <p>{message}</p>
        <div className="cb-boot-actions">
          {showConnect && (
            <a className="cb-btn cb-btn-primary" href="/api/qbo/connect">
              <IconExternal size={14} /> Connect QuickBooks
            </a>
          )}
          {onRetry && <button type="button" className="cb-btn cb-btn-ghost" onClick={onRetry}>Try again</button>}
          <button type="button" className="cb-btn cb-btn-ghost" onClick={() => window.__CB_LOGOUT()}>Sign out</button>
        </div>
      </div>
    </div>
  );
}

/* ── Flow ───────────────────────────────────────────────────────────────── */

const __root = ReactDOM.createRoot(document.getElementById('root'));

function renderLogin() { __root.render(<LoginScreen onSuccess={start} />); }

// Admin lands here: manage clients, then drill into any one's live dashboard.
function renderAdminConsole(user) {
  __root.render(<AdminConsole user={user} onOpenDashboard={(id) => openClientDashboard(user, id)} />);
}

async function openClientDashboard(user, companyId, companyName) {
  __activeCompanyId = companyId;
  __root.render(<BootMessage title="Loading client books…" body="Fetching live data from QuickBooks." />);
  try {
    await window.__CB_LOAD_DASHBOARD('mtd');
    const name = companyName || (window.CB.company && window.CB.company.name) || 'client';
    __root.render(
      <React.Fragment>
        <AdminBackBar companyName={name} onBack={() => renderAdminConsole(user)} />
        <App />
      </React.Fragment>
    );
  } catch (ex) {
    __root.render(<BootError message={ex.message}
      onRetry={() => openClientDashboard(user, companyId, companyName)} />);
  }
}

async function start(user) {
  window.__CB_USER = user;
  if (user.role === 'admin') { renderAdminConsole(user); return; }

  // Client: straight to their own dashboard.
  __root.render(<BootMessage title="Loading your books…" body="Fetching live data from QuickBooks." />);
  try {
    __activeCompanyId = user.companyId;
    if (!__activeCompanyId) {
      __root.render(<BootError message="Your account isn't linked to a company yet. Ask your bookkeeper to finish setup." />);
      return;
    }
    await window.__CB_LOAD_DASHBOARD('mtd');
    __root.render(<App />);
  } catch (ex) {
    __root.render(<BootError message={ex.message} onRetry={() => start(user)} />);
  }
}

(async function boot() {
  // Invite landing page — no session required.
  if (location.pathname.replace(/\/+$/, '') === '/set-password') {
    __root.render(<SetPasswordScreen />);
    return;
  }
  try {
    const me = await CBNet.me();
    if (!me || !me.user) { renderLogin(); return; }
    start(me.user);
  } catch {
    renderLogin();
  }
})();
