/* ============================================================
   ELECTROMED — App root & routing
   ============================================================ */
function Placeholder({ route }) {
  const meta = (window.NAV || []).find((n) => n.id === route) || {};
  return (
    <div className="view-enter">
      <PageHead title={meta.label || 'Module'} sub="This module is part of the Electromed platform." />
      <div className="card ph-img" style={{ height: 360 }}>module · {route}</div>
    </div>
  );
}

// Route → required permission module (help/none). Drives both nav-landing and
// the in-app route guard, so they can never disagree.
const ROUTE_PERM = {
  dashboard: 'dashboard', crm: 'customers', sales: 'sales', rentals: 'rentals',
  workshop: 'workshop', inventory: 'inventory', payments: 'payments',
  reports: 'reports', notifications: 'settings', settings: 'settings',
};
const canRoute = (route) => {
  const need = ROUTE_PERM[route];
  return !need || (window.can ? window.can(need, 'view') : true);
};
// First page the user is actually allowed to see (their landing page).
const firstAllowedRoute = () => {
  const navs = window.NAV || [];
  const hit = navs.find((n) => !n.perm || (window.can && window.can(n.perm, 'view')));
  if (hit) return hit.id;
  if (window.can && window.can('settings', 'view')) return 'settings';
  return 'help';
};

function App() {
  /* Auth: require a real JWT token — em_auth alone is not enough */
  const [authed, setAuthed] = useState(() => !!localStorage.getItem('authToken'));
  const [route,  setRoute]  = useState(() => location.hash.replace('#', '') || 'dashboard');
  // Current logged-in user — read from localStorage on boot, updated on login
  const [currentUser, setCurrentUser] = useState(() => {
    try { return JSON.parse(localStorage.getItem('currentUser') || 'null'); } catch { return null; }
  });
  // Booting: while we re-fetch the identity + fresh permissions from /auth/me
  const [booting, setBooting] = useState(() => !!localStorage.getItem('authToken'));

  // Branch: admins default to 'All', non-admins locked to their branch
  const [branch, setBranch] = useState(() => {
    try {
      const u = JSON.parse(localStorage.getItem('currentUser') || 'null');
      const adminRoles = ['admin', 'owner', 'super admin', 'superadmin', 'super_admin'];
      if (u && u.branch_id && !adminRoles.includes((u.role || '').toLowerCase())) {
        return String(u.branch_id);
      }
    } catch {}
    return 'All';
  });
  const contentRef = useRef(null);

  // Detect accept-invite URL: /accept-invite?token=xxx
  const _inviteToken = (() => {
    try {
      if (location.pathname === '/accept-invite' || location.search.includes('token=')) {
        return new URLSearchParams(location.search).get('token') || null;
      }
    } catch {}
    return null;
  })();

  const go = (id) => { setRoute(id); location.hash = id; };

  const login = ({ branch: b, user }) => {
    localStorage.setItem('em_auth', '1');
    if (b && b !== 'All') setBranch(b);
    if (user) {
      setCurrentUser(user);
      // Lock non-admin users to their branch
      const adminRoles = ['admin', 'owner', 'super admin', 'superadmin', 'super_admin'];
      if (user.branch_id && !adminRoles.includes((user.role || '').toLowerCase())) {
        setBranch(String(user.branch_id));
      } else if (b && b !== 'All') {
        setBranch(b);
      }
      if (window.DATA) {
        window.DATA.company.user = {
          name:  user.name  || window.DATA.company.user.name,
          role:  user.display_role || user.role || window.DATA.company.user.role,
          email: user.email || window.DATA.company.user.email,
          init:  (user.name || 'U').split(' ').map((n) => n[0]).join('').toUpperCase().slice(0, 2),
        };
      }
    } else if (b && b !== 'All') {
      setBranch(b);
    }
    if (_inviteToken && window.history) {
      window.history.replaceState({}, document.title, '/');
    }
    setAuthed(true);
  };

  const logout = () => {
    api.clearAuth();
    localStorage.removeItem('em_auth');
    setAuthed(false);
    setRoute('dashboard');
    location.hash = 'dashboard';
  };
  useEffect(() => { window.__logout = logout; }, []);

  useEffect(() => {
    const onHash = () => setRoute(location.hash.replace('#', '') || 'dashboard');
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  useEffect(() => { if (contentRef.current) contentRef.current.scrollTop = 0; }, [route]);

  // Keep the API client aware of the branch being viewed (so new records are
  // tagged to it for super-admins). Set immediately + on every change.
  api.activeBranch = branch;
  useEffect(() => { api.activeBranch = branch; }, [branch]);

  // On boot, re-fetch identity + FRESH permissions so any stale session
  // self-heals (e.g. accepted before perms were returned, or role changed).
  useEffect(() => {
    let alive = true;
    if (!authed) { setBooting(false); return; }
    api.refreshSession().then((u) => {
      if (!alive) return;
      if (u) setCurrentUser(u);
      setBooting(false);
    });
    return () => { alive = false; };
  }, []);

  // Land the user on a page they can actually access (not a hard-coded
  // dashboard). Runs once permissions are loaded and whenever the route changes.
  useEffect(() => {
    if (booting || !authed) return;
    if (!canRoute(route)) {
      const dest = firstAllowedRoute();
      if (dest && dest !== route) go(dest);
    }
  }, [booting, route, currentUser]);

  // Show accept-invite page if token is in URL (even if already authed — must accept first)
  if (_inviteToken && window.AcceptInvite) return <window.AcceptInvite token={_inviteToken} onLogin={login} />;

  if (!authed) return <window.Login onLogin={login} />;

  // While fetching fresh permissions, hold render to avoid a flash of the
  // wrong page or a premature "Access Denied".
  if (booting) {
    return (
      <div className="app" style={{ display: 'grid', placeItems: 'center', minHeight: '100vh' }}>
        <div style={{ textAlign: 'center', color: 'var(--ink-3)' }}>
          <div style={{ width: 34, height: 34, border: '3px solid var(--line-2)', borderTopColor: 'var(--lime-700)', borderRadius: '50%', margin: '0 auto 12px', animation: 'spin 0.8s linear infinite' }} />
          <div className="tiny">Loading your workspace…</div>
        </div>
      </div>
    );
  }

  const views = {
    dashboard:     window.Dashboard,
    crm:           window.CRM,
    sales:         window.Sales,
    rentals:       window.Rentals,
    workshop:      window.Workshop,
    inventory:     window.Inventory,
    payments:      window.Payments,
    reports:       window.Reports,
    notifications: window.Notifications,
    settings:      window.Settings,
    help:          window.Help,
  };
  const View = views[route] || (() => <Placeholder route={route} />);
  const allowed = canRoute(route); // module-level guard (shared with nav-landing)

  return (
    <div className="app">
      <div className="app-shell">
        <Sidebar route={route} go={go} />
        <div className="main">
          <Topbar route={route} go={go} branch={branch} setBranch={setBranch} currentUser={currentUser} />
          <div className="content" ref={contentRef}>
            <div className="content-inner">
              {allowed
                ? <View key={route} go={go} branch={branch} setBranch={setBranch} />
                : <AccessDenied go={() => go(firstAllowedRoute())} />}
            </div>
          </div>
        </div>
      </div>
      {window.ToastContainer && <window.ToastContainer />}
    </div>
  );
}

function AccessDenied({ go }) {
  const Icons = window.Icons || {};
  return (
    <div className="view-enter card card-pad" style={{ textAlign: 'center', padding: '56px 24px', maxWidth: 460, margin: '40px auto' }}>
      <div style={{ width: 60, height: 60, borderRadius: 16, background: 'var(--bad-bg, #fdecec)', display: 'grid', placeItems: 'center', margin: '0 auto 18px' }}>
        {Icons.shield ? <Icons.shield size={30} style={{ color: 'var(--bad, #dc2626)' }} /> : <span style={{ fontSize: 28 }}>🔒</span>}
      </div>
      <div style={{ fontWeight: 800, fontSize: 19, marginBottom: 6 }}>Access Denied</div>
      <div className="tiny muted" style={{ marginBottom: 20, lineHeight: 1.6 }}>
        You don't have permission to view this page. If you think this is a mistake, ask your administrator to update your access.
      </div>
      {window.Btn && <window.Btn variant="primary" onClick={() => go()}>Go to my workspace</window.Btn>}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
