// App.jsx — AegisComply Main Shell (v3 — with admin panel, frozen guard, error boundary)

// ── Frozen account banner ──────────────────────────────────────────────────
function FrozenBanner({ onNav }) {
  return (
    <div style={{ background: '#FFF5F5', border: '1px solid #FECACA', borderLeft: '4px solid #DC2626', margin: '0 24px 0', padding: '12px 18px', display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0 }}>
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#DC2626" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: '#DC2626' }}>Subscription Lapsed — Read-Only Mode</div>
        <div style={{ fontSize: 12, color: '#7F1D1D', marginTop: 1 }}>You can view your data but cannot add, edit, or approve anything. Renew to restore full access.</div>
      </div>
      <button onClick={() => onNav('subscription')} style={{ height: 30, padding: '0 14px', border: 'none', borderRadius: 6, background: '#DC2626', fontSize: 12, fontWeight: 700, color: 'white', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif", whiteSpace: 'nowrap' }}>
        Renew Now →
      </button>
    </div>
  );
}

// ── Pilot expiry banner ────────────────────────────────────────────────────
function PilotBanner({ daysLeft, onNav }) {
  if (daysLeft > 7) return null;
  const urgent = daysLeft <= 3;
  return (
    <div style={{ background: urgent ? '#FFFBEB' : '#F0FDFA', border: `1px solid ${urgent ? '#FDE68A' : '#99F6E4'}`, borderLeft: `4px solid ${urgent ? '#D97706' : '#0D9488'}`, margin: '0 24px 0', padding: '10px 18px', display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0 }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={urgent ? '#D97706' : '#0D9488'} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
      <div style={{ flex: 1, fontSize: 12, color: urgent ? '#92400E' : '#0F766E' }}>
        <strong>{daysLeft} day{daysLeft !== 1 ? 's' : ''} left</strong> on your free pilot. Subscribe to keep full access after your trial ends.
      </div>
      <button onClick={() => onNav('subscription')} style={{ height: 28, padding: '0 12px', border: 'none', borderRadius: 5, background: urgent ? '#D97706' : '#0D9488', fontSize: 12, fontWeight: 700, color: 'white', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif", whiteSpace: 'nowrap' }}>
        Subscribe →
      </button>
    </div>
  );
}

// ── Error boundary ─────────────────────────────────────────────────────────
class ErrorBoundary extends React.Component {
  constructor(props) { super(props); this.state = { hasError: false, error: null }; }
  static getDerivedStateFromError(error) { return { hasError: true, error }; }
  componentDidCatch(error, info) { console.error('[AegisComply Error]', error, info); }
  render() {
    if (!this.state.hasError) return this.props.children;
    return (
      <div style={{ padding: 40, textAlign: 'center', color: '#64748B' }}>
        <div style={{ width: 56, height: 56, borderRadius: 12, background: '#FFF5F5', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px' }}>
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#DC2626" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
        </div>
        <div style={{ fontFamily: "'Helvetica',Arial,sans-serif", fontSize: 16, fontWeight: 700, color: '#0F172A', marginBottom: 8 }}>Something went wrong</div>
        <div style={{ fontSize: 13, marginBottom: 20, maxWidth: 360, margin: '0 auto 20px' }}>
          {String(this.state.error?.message || 'An unexpected error occurred.')}
        </div>
        <button
          style={{ height: 36, padding: '0 20px', border: 'none', borderRadius: 6, background: '#0D9488', color: 'white', fontSize: 13, fontWeight: 700, cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" }}
          onClick={() => { this.setState({ hasError: false, error: null }); }}
        >Try Again</button>
        <div style={{ marginTop: 10 }}>
          <span
            style={{ fontSize: 12, color: '#0D9488', cursor: 'pointer' }}
            onClick={() => window.location.reload()}
          >Reload page</span>
        </div>
      </div>
    );
  }
}

// ── Tweak defaults ──────────────────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "primaryColor": "#0D9488",
  "sidebarColor": "#0B1F3A",
  "companyName": "Petronas Chemicals Bhd",
  "userName": "Ahmad Razif",
  "userRole": "Safety Officer",
  "developerEmail": "developer@aegiscomply.my"
}/*EDITMODE-END*/;

// ── Screen meta ─────────────────────────────────────────────────────────────
const appShellStyles = {
  shell:   { display: 'flex', height: '100vh', overflow: 'hidden' },
  main:    { marginLeft: 240, flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' },
  content: { flex: 1, overflowY: 'auto', background: '#F1F5F9' },
  placeholder: { padding: 40, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: 300, gap: 12 },
  placeholderIcon: { width: 48, height: 48, borderRadius: 12, background: '#E2E8F0', display: 'flex', alignItems: 'center', justifyContent: 'center' },
  placeholderText: { fontSize: 14, fontWeight: 500, color: '#64748B' },
  placeholderSub:  { fontSize: 12, color: '#94A3B8' },
};

const screenMeta = {
  dashboard:    { title: 'Dashboard',            breadcrumb: null },
  equipment:    { title: 'Equipment Management', breadcrumb: 'Equipment' },
  calibration:  { title: 'Calibration Records',  breadcrumb: 'Calibration' },
  ppe:          { title: 'PPE Inventory',         breadcrumb: 'PPE' },
  documents:    { title: 'Document Management',  breadcrumb: 'Documents' },
  reports:      { title: 'Audit Reports',         breadcrumb: 'Reports' },
  alerts:       { title: 'Alerts',               breadcrumb: 'Alerts' },
  roi:          { title: 'ROI Report',            breadcrumb: 'Insights' },
  subscription: { title: 'Subscription Plans',   breadcrumb: 'Account' },
  settings:     { title: 'Settings',             breadcrumb: 'Settings' },
};

const topbarActions = {
  dashboard:    [{ label: 'Generate Report', primary: true }],
  equipment:    [], // Import/Export/Add live in the screen's toolbar
  calibration:  [], // Export PDF + Add Record live in the screen's toolbar
  ppe:          [], // Import/Export/Issue/Add live in the screen's toolbar
  documents:    [], // Upload button lives in the screen toolbar
  reports:      [{ label: 'Export PDF', primary: true }],
  alerts:       [{ label: 'Mark All Read' }],
  roi:          [{ label: 'Export PDF Report', primary: true }],
  subscription: [],
  settings:     [],
};

function PlaceholderScreen({ screen }) {
  return (
    <div style={appShellStyles.placeholder}>
      <div style={appShellStyles.placeholderIcon}>
        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#94A3B8" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="9" y1="9" x2="15" y2="9"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="12" y2="17"/></svg>
      </div>
      <div style={appShellStyles.placeholderText}>{screenMeta[screen]?.title}</div>
      <div style={appShellStyles.placeholderSub}>This screen is not yet fully prototyped</div>
    </div>
  );
}

// ── Compute pilot days left ────────────────────────────────────────────────
function getPilotDaysLeft(user) {
  if (!user?.registeredAt) return 14;
  const start = new Date(user.registeredAt);
  const now = new Date();
  const diffMs = (start.getTime() + 14 * 86400000) - now.getTime();
  return Math.max(0, Math.ceil(diffMs / 86400000));
}

// ── Main App ────────────────────────────────────────────────────────────────
function App() {
  const [screen, setScreen] = React.useState(() => localStorage.getItem('aegis-screen') || 'dashboard');
  const [tweaks, setTweaks] = React.useState(TWEAK_DEFAULTS);
  const [showTweaks, setShowTweaks] = React.useState(false);
  const [showAdmin, setShowAdmin] = React.useState(false);
  const [user, setUser] = React.useState(null);
  const [authReady, setAuthReady] = React.useState(false);
  const [badges, setBadges] = React.useState({ equipment: 0, calibration: 0, alerts: 0 });

  // ── ALL hooks BEFORE any conditional return (Rules of Hooks) ────────────
  React.useEffect(() => {
    if (user) localStorage.setItem('aegis-screen', screen);
  }, [screen, user]);

  React.useEffect(() => {
    const handler = (e) => {
      if (e.data?.type === '__activate_edit_mode')   setShowTweaks(true);
      if (e.data?.type === '__deactivate_edit_mode') setShowTweaks(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  // ── Supabase session restore + auth state subscription ──────────────────
  React.useEffect(() => {
    const sb = window.supabaseClient;
    if (!sb) {
      console.error('[App] Supabase client not initialised');
      setAuthReady(true);
      return;
    }

    let mounted = true;

    const loadProfile = async (userId) => {
      try {
        const { data, error } = await sb.from('users').select('*').eq('id', userId).single();
        if (error) throw error;
        if (mounted) setUser(data);
      } catch (err) {
        console.error('[App] Failed to load user profile:', err);
        if (mounted) setUser(null);
      }
    };

    // Restore existing session on page load
    sb.auth.getSession().then(({ data: { session } }) => {
      if (!mounted) return;
      if (session?.user) {
        loadProfile(session.user.id).finally(() => mounted && setAuthReady(true));
      } else {
        setAuthReady(true);
      }
    });

    // React to login / logout from anywhere
    const { data: { subscription } } = sb.auth.onAuthStateChange((event, session) => {
      if (!mounted) return;
      if (event === 'SIGNED_OUT' || !session) {
        setUser(null);
      } else if (event === 'SIGNED_IN' && session?.user) {
        loadProfile(session.user.id);
      }
    });

    return () => { mounted = false; subscription?.unsubscribe(); };
  }, []);

  // ── Load sidebar badge counts (urgent + expiring equipment) ─────────────
  React.useEffect(() => {
    if (!user) { setBadges({ equipment: 0, calibration: 0, alerts: 0 }); return; }
    const sb = window.supabaseClient;
    if (!sb) return;

    let cancelled = false;
    const loadBadges = async () => {
      try {
        const [urgent, expiring] = await Promise.all([
          sb.from('equipment').select('id', { count: 'exact', head: true }).in('status', ['overdue', 'expired']),
          sb.from('equipment').select('id', { count: 'exact', head: true }).eq('status', 'expiring'),
        ]);
        if (cancelled) return;
        const urgentCount   = urgent.count || 0;
        const expiringCount = expiring.count || 0;
        setBadges({
          equipment:   urgentCount,
          calibration: expiringCount,
          alerts:      urgentCount + expiringCount,
        });
      } catch (err) {
        console.error('[App] Badge count failed:', err);
      }
    };
    loadBadges();

    // Subscribe to equipment changes via Supabase Realtime — badges update live
    // Requires: ALTER PUBLICATION supabase_realtime ADD TABLE public.equipment;
    const channel = sb.channel(`badge-watcher-${user.id}`)
      .on('postgres_changes',
        { event: '*', schema: 'public', table: 'equipment', filter: `user_id=eq.${user.id}` },
        () => { loadBadges(); }
      )
      .subscribe();

    return () => {
      cancelled = true;
      sb.removeChannel(channel);
    };
  }, [user]);

  // ── Auth handlers ────────────────────────────────────────────────────────
  const handleLogin = (profile) => {
    setUser(profile);
    setScreen('dashboard');
  };
  const handleLogout = async () => {
    const sb = window.supabaseClient;
    if (sb) await sb.auth.signOut();
    setUser(null);
    setScreen('dashboard');
    localStorage.removeItem('aegis-screen');
  };

  const handleTweakChange = (key, val) => {
    setTweaks(t => ({ ...t, [key]: val }));
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [key]: val } }, '*');
  };

  // ── Conditional render AFTER all hooks ───────────────────────────────────
  if (!authReady) return (
    <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#F1F5F9' }}>
      <div style={{ fontSize: 13, color: '#64748B', fontFamily: "'DM Sans',sans-serif" }}>Loading…</div>
    </div>
  );
  if (!user) return <AuthScreen onLogin={handleLogin} />;

  // ── Access control ───────────────────────────────────────────────────────
  // Map Supabase profile fields (snake_case) to the shape the rest of the app expects
  const userTier  = user.tier;
  const isMaster  = userTier === 'full_forever';
  const isFrozen  = userTier === 'frozen';
  const isPilot   = userTier === 'pilot';
  // pilot_start (from public.users) determines days remaining
  const pilotDays = isPilot ? getPilotDaysLeft({ registeredAt: user.pilot_start || user.created_at }) : 14;
  const isAdmin   = isMaster; // only master account sees admin panel

  const meta    = screenMeta[screen] || screenMeta.dashboard;
  const actions = topbarActions[screen] || [];

  // ── Screen renderer ──────────────────────────────────────────────────────
  const renderScreen = () => {
    switch (screen) {
      case 'dashboard':    return <DashboardScreen onNav={setScreen} user={user} />;
      case 'equipment':    return <EquipmentScreen user={user} isFrozen={isFrozen}/>;
      case 'calibration':  return <CalibrationScreen devEmail={tweaks.developerEmail} user={user} isFrozen={isFrozen}/>;
      case 'ppe':          return <PPEScreen devEmail={tweaks.developerEmail} user={user} isFrozen={isFrozen}/>;
      case 'alerts':       return <AlertsScreen user={user} onNav={setScreen}/>;
      case 'roi':          return <ROIScreen user={user}/>;
      case 'subscription': return <SubscriptionScreen user={user}/>;
      case 'settings':     return <SettingsScreen user={user}/>;
      case 'documents':    return <DocumentsScreen user={user} isFrozen={isFrozen}/>;
      default:             return <PlaceholderScreen screen={screen} />;
    }
  };

  return (
    <div style={appShellStyles.shell}>
      <Sidebar active={screen} onNav={setScreen} badges={badges} onLogout={handleLogout} user={user} />

      <div style={appShellStyles.main}>
        <Topbar
          title={meta.title}
          breadcrumb={meta.breadcrumb}
          actions={isFrozen ? [] : actions}
          hasAlerts={badges.alerts > 0}
          isAdmin={isAdmin}
          onAdminOpen={() => setShowAdmin(true)}
        />

        {/* Status banners */}
        {isFrozen && <FrozenBanner onNav={setScreen} />}
        {isPilot && pilotDays <= 7 && !isFrozen && <PilotBanner daysLeft={pilotDays} onNav={setScreen} />}

        <div style={{ ...appShellStyles.content, marginTop: (isFrozen || (isPilot && pilotDays <= 7)) ? 8 : 0 }}>
          <ErrorBoundary key={screen}>
            {renderScreen()}
          </ErrorBoundary>
        </div>
      </div>

      {/* Admin Panel */}
      {showAdmin && isAdmin && <AdminPanel onClose={() => setShowAdmin(false)} user={user}/>}

      {/* Tweaks Panel */}
      {showTweaks && (
        <div style={{ position: 'fixed', bottom: 16, right: 16, width: 280, background: 'white', border: '1px solid #E2E8F0', borderRadius: 10, boxShadow: '0 8px 24px rgba(0,0,0,0.12)', zIndex: 9999, padding: 16 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: '#334155', marginBottom: 14, letterSpacing: '0.08em', textTransform: 'uppercase' }}>Tweaks</div>
          {[
            { key: 'primaryColor',   label: 'Primary Color',             type: 'color' },
            { key: 'sidebarColor',   label: 'Sidebar Color',             type: 'color' },
            { key: 'companyName',    label: 'Company Name',              type: 'text' },
            { key: 'userName',       label: 'User Name',                 type: 'text' },
            { key: 'userRole',       label: 'User Role',                 type: 'text' },
            { key: 'developerEmail', label: 'Contact / Developer Email', type: 'email' },
          ].map(({ key, label, type }) => (
            <div key={key} style={{ marginBottom: 12 }}>
              <label style={{ fontSize: 11, fontWeight: 600, color: '#64748B', display: 'block', marginBottom: 4 }}>{label}</label>
              <input
                type={type}
                value={tweaks[key]}
                onChange={e => handleTweakChange(key, e.target.value)}
                style={{ width: '100%', height: type === 'color' ? 32 : 30, border: '1px solid #CBD5E1', borderRadius: 5, padding: type === 'color' ? '2px 4px' : '0 8px', fontSize: 12, fontFamily: "'DM Sans',sans-serif", color: '#334155', outline: 'none', background: 'white' }}
              />
              {key === 'developerEmail' && <div style={{ fontSize: 10, color: '#94A3B8', marginTop: 3 }}>Calibration booking & PPE order emails</div>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

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