/* Main App: navigation, screens, tweaks */

const { useState, useEffect, useMemo } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "heroVariant": "animated",
  "sidebarVariant": "expanded",
  "cardVariant": "standard",
  "tiendaLayout": "grid"
}/*EDITMODE-END*/;

/** Anclas reales en la landing (contacto/inscripción → formulario, no el mapa). */
const PUBLIC_NAV_ANCHORS = {
  home: 'top',
  avisos: 'avisos',
  calendario: 'calendario',
  entrenadores: 'entrenadores',
  galeria: 'galeria',
  tienda: 'tienda',
  ubicacion: 'ubicacion',
  contacto: 'solicita-informacion',
  inscripcion: 'solicita-informacion',
};

function resolvePublicAnchorId (navId) {
  return PUBLIC_NAV_ANCHORS[navId] || navId || 'solicita-informacion';
}

if (typeof window !== 'undefined') {
  window.resolvePublicAnchorId = resolvePublicAnchorId;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const theme = THEMES[t.theme] || THEMES.light;
  const [screen, setScreen] = useState('public');
  const [publicSection, setPublicSection] = useState('home');
  const [adminView, setAdminView] = useState('dashboard');
  const [alumnoView, setAlumnoView] = useState('a-dashboard');

  React.useEffect(() => {
    try {
      const saved = localStorage.getItem('tecos-theme');
      if (saved && THEMES[saved] && saved !== t.theme) setTweak('theme', saved);
    } catch (_) { /* ignore */ }
  }, []);

  React.useEffect(() => {
    try { localStorage.setItem('tecos-theme', t.theme); } catch (_) { /* ignore */ }
  }, [t.theme]);

  React.useEffect(() => {
    if (screen !== 'admin' || !isSupabaseReady()) return;
    const flag = 'tecos:phones-normalized-intl-2';
    try {
      if (localStorage.getItem(flag) === 'done') return;
    } catch (_) { /* ignore */ }
    if (typeof migrateAllStudentPhonesOnce !== 'function') return;
    let cancelled = false;
    (async () => {
      try {
        const r = await migrateAllStudentPhonesOnce();
        if (cancelled) return;
        try { localStorage.setItem(flag, 'done'); } catch (_) { /* ignore */ }
        if (r.updated > 0) {
          console.info(`[Tecos] Teléfonos normalizados: ${r.updated} de ${r.total} alumnos.`);
        }
      } catch (e) {
        console.warn('[Tecos] No se pudieron normalizar teléfonos de alumnos:', e.message || e);
      }
    })();
    return () => { cancelled = true; };
  }, [screen]);

  // Modals state
  const [eventModal, setEventModal] = useState(null);
  const [birthdayModal, setBirthdayModal] = useState(null);
  const [avisoModal, setAvisoModal] = useState(null);
  const [calendarHighlight, setCalendarHighlight] = useState(null);
  const [coachModal, setCoachModal] = useState(null);
  const [orderProduct, setOrderProduct] = useState(null);
  const [inscripcionModalOpen, setInscripcionModalOpen] = useState(false);
  const [waPreview, setWaPreview] = useState(null);
  const [paymentDetail, setPaymentDetail] = useState(null);
  const [activeStudent, setActiveStudent] = useState(null);
  const [alumnoPayments, setAlumnoPayments] = useState([]);
  const [alumnoOrders, setAlumnoOrders] = useState([]);
  const [alumnoExpediente, setAlumnoExpediente] = useState([]);
  const [alumnoDocuments, setAlumnoDocuments] = useState([]);
  const [paymentCalendarYear, setPaymentCalendarYear] = useState(() => new Date().getFullYear());
  const [portalBillingCtx, setPortalBillingCtx] = useState(null);
  const portalStudentCodeRef = React.useRef(null);
  const [portalLoading, setPortalLoading] = useState(false);
  const [orderDetail, setOrderDetail] = useState(null);
  const [adminDrawerOpen, setAdminDrawerOpen] = useState(false);
  const [alumnoDrawerOpen, setAlumnoDrawerOpen] = useState(false);
  useEffect(() => {
    try {
      window.dispatchEvent(new CustomEvent('tecos:app-ready'));
      document.documentElement.classList.add('tecos-app-ready');
    } catch (_) { /* ignore */ }
  }, []);

  useEffect(() => {
    if (screen !== 'admin') return;
    if (typeof tecosEnsureChartJs === 'function') tecosEnsureChartJs().catch(() => {});
    if (typeof tecosEnsureExportLibs === 'function') tecosEnsureExportLibs().catch(() => {});
  }, [screen]);

  const reloadStudentPortal = React.useCallback(async (code) => {
    if (!code || !isSupabaseReady()) return;
    setPortalLoading(true);
    try {
      let [portal, settings] = await Promise.all([
        fetchStudentPortalByCode(code),
        fetchAcademySettings(),
      ]);
      if (!portal?.student) {
        setActiveStudent(null);
        setAlumnoPayments([]);
        setAlumnoOrders([]);
        setAlumnoExpediente([]);
        setAlumnoDocuments([]);
        setPortalBillingCtx(null);
        portalStudentCodeRef.current = null;
        if (code) {
          setScreen('login');
          alert('Tu cuenta ya no está activa en la academia. Si crees que es un error, contacta a administración.');
        }
        return;
      } else {
      const joinDate = portal.student?.joined_at || portal.student?.joinedAt;
      if (portal.student?.id && joinDate) {
        try {
          let pruned = 0;
          if (typeof pruneStudentPreJoinPayments === 'function') {
            pruned += await pruneStudentPreJoinPayments(portal.student.id, joinDate);
          }
          if (typeof pruneStudentOutOfCyclePendingPayments === 'function') {
            pruned += await pruneStudentOutOfCyclePendingPayments(portal.student.id, joinDate);
          }
          if (pruned > 0) {
            const refreshed = await fetchStudentPortalByCode(code);
            if (refreshed) portal = refreshed;
          }
        } catch (e) {
          console.warn('[Tecos] limpieza mensualidades portal', e);
        }
      }
      if (portal.student?.id && joinDate && typeof generateStudentBillingCyclePayments === 'function') {
        try {
          const created = await generateStudentBillingCyclePayments(portal.student.id, joinDate, {
            skipExisting: true,
            joinedAt: joinDate,
          });
          if (created > 0) {
            const refreshed = await fetchStudentPortalByCode(code);
            if (refreshed) portal = refreshed;
          }
        } catch (e) {
          console.warn('[Tecos] ciclo mensualidades portal', e);
        }
      }
      const normCode = typeof normalizeTecStudentCode === 'function'
        ? normalizeTecStudentCode(code)
        : String(code).trim().toUpperCase();
      if (portalStudentCodeRef.current !== normCode) {
        portalStudentCodeRef.current = normCode;
        setPaymentCalendarYear(new Date().getFullYear());
      }
      const portalPayments = typeof filterPaymentsForJoin === 'function'
        ? filterPaymentsForJoin(portal.payments, joinDate)
        : portal.payments;
      const adeudo = typeof computeStudentAdeudoAmount === 'function'
        ? computeStudentAdeudoAmount(portalPayments, settings, joinDate)
        : 0;
      setActiveStudent(mapPortalStudent(portal.student, { adeudo }));
      setPortalBillingCtx({ payments: portalPayments, settings, joinDate });
      setAlumnoExpediente(mapPortalPaymentsExpediente(portal.payments, settings, joinDate));
      setAlumnoOrders(mapPortalOrders(portal.orders));
      if (typeof fetchStudentDocumentsByCode === 'function') {
        try {
          const docs = await fetchStudentDocumentsByCode(normCode || code);
          setAlumnoDocuments(docs || []);
        } catch (docErr) {
          console.warn('[Tecos] documentos alumno', docErr);
          setAlumnoDocuments([]);
        }
      } else {
        setAlumnoDocuments([]);
      }
      if (typeof syncStudentPortalNotifications === 'function') {
        try {
          await syncStudentPortalNotifications(code);
          window.dispatchNotificationsChanged?.();
        } catch (syncErr) {
          console.warn('[Tecos] sync notificaciones alumno', syncErr);
        }
      }
      }
    } catch (e) {
      console.error('[Tecos] portal alumno', e);
    } finally {
      setPortalLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!portalBillingCtx) {
      setAlumnoPayments([]);
      return;
    }
    const months = mapPortalPaymentsToMonths(
      portalBillingCtx.payments,
      paymentCalendarYear,
      portalBillingCtx.settings,
      portalBillingCtx.joinDate,
      { mode: 'billing_schedule', allowAdvancePay: true },
    );
    setAlumnoPayments(months);
  }, [paymentCalendarYear, portalBillingCtx]);

  const portalBillingCtxRef = React.useRef(portalBillingCtx);
  portalBillingCtxRef.current = portalBillingCtx;

  useEffect(() => {
    const refreshPortalTariffs = async () => {
      const ctx = portalBillingCtxRef.current;
      if (!ctx || typeof fetchAcademySettings !== 'function' || !isSupabaseReady()) return;
      try {
        const settings = await fetchAcademySettings();
        setPortalBillingCtx((prev) => (prev ? { ...prev, settings } : prev));
      } catch (e) {
        console.warn('[Tecos] actualizar tarifas portal', e);
      }
    };
    window.addEventListener('tecos:settings-changed', refreshPortalTariffs);
    return () => window.removeEventListener('tecos:settings-changed', refreshPortalTariffs);
  }, []);

  const paymentCalendarYearBounds = React.useMemo(() => {
    if (typeof getPaymentCalendarYearBounds === 'function') {
      return getPaymentCalendarYearBounds(activeStudent?.joined_at || activeStudent?.joinedAt);
    }
    const y = new Date().getFullYear();
    return { minYear: y - 2, maxYear: y + 8 };
  }, [activeStudent?.joined_at, activeStudent?.joinedAt]);

  const goPaymentCalendarYearPrev = () => {
    setPaymentCalendarYear((y) => Math.max(paymentCalendarYearBounds.minYear, y - 1));
  };
  const goPaymentCalendarYearNext = () => {
    setPaymentCalendarYear((y) => Math.min(paymentCalendarYearBounds.maxYear, y + 1));
  };

  const paymentCalendarNavProps = {
    calendarYear: paymentCalendarYear,
    onCalendarYearPrev: goPaymentCalendarYearPrev,
    onCalendarYearNext: goPaymentCalendarYearNext,
    calendarYearBounds: paymentCalendarYearBounds,
  };

  useEffect(() => {
    window.__onAlumnoPaymentSync = (code) => {
      if (!activeStudent?.code) return;
      const mine = typeof normalizeTecStudentCode === 'function'
        ? normalizeTecStudentCode(activeStudent.code)
        : String(activeStudent.code).trim().toUpperCase();
      const theirs = code && typeof normalizeTecStudentCode === 'function'
        ? normalizeTecStudentCode(code)
        : String(code || mine).trim().toUpperCase();
      if (theirs && theirs !== mine) return;
      reloadStudentPortal(activeStudent.code);
      window.dispatchNotificationsChanged?.();
    };
    window.__onAlumnoOrderSync = () => {
      if (!activeStudent?.code) return;
      reloadStudentPortal(activeStudent.code);
      window.dispatchNotificationsChanged?.();
    };
    return () => {
      window.__onAlumnoPaymentSync = null;
      window.__onAlumnoOrderSync = null;
    };
  }, [activeStudent?.code, reloadStudentPortal]);

  useEffect(() => {
    if (screen !== 'alumno' || !activeStudent?.code) return;
    const onPayments = () => reloadStudentPortal(activeStudent.code);
    window.addEventListener('tecos:payments-changed', onPayments);
    return () => window.removeEventListener('tecos:payments-changed', onPayments);
  }, [screen, activeStudent?.code, reloadStudentPortal]);

  useEffect(() => {
    if (screen !== 'alumno' || !activeStudent?.code) return;
    const onDocs = () => reloadStudentPortal(activeStudent.code);
    window.addEventListener('tecos:student-documents-changed', onDocs);
    return () => window.removeEventListener('tecos:student-documents-changed', onDocs);
  }, [screen, activeStudent?.code, reloadStudentPortal]);

  useEffect(() => {
    if (screen !== 'alumno' || !activeStudent?.code) return;
    const onVisible = () => {
      if (document.visibilityState === 'visible') reloadStudentPortal(activeStudent.code);
    };
    document.addEventListener('visibilitychange', onVisible);
    return () => document.removeEventListener('visibilitychange', onVisible);
  }, [screen, activeStudent?.code, reloadStudentPortal]);

  useEffect(() => {
    const onStudentsChanged = (e) => {
      const deletedCode = e.detail?.deletedCode;
      if (!deletedCode || !activeStudent?.code) return;
      const normDeleted = typeof normalizeTecStudentCode === 'function'
        ? normalizeTecStudentCode(deletedCode)
        : String(deletedCode).trim().toUpperCase();
      const normActive = typeof normalizeTecStudentCode === 'function'
        ? normalizeTecStudentCode(activeStudent.code)
        : String(activeStudent.code).trim().toUpperCase();
      if (normDeleted !== normActive) return;
      reloadStudentPortal(activeStudent.code);
    };
    window.addEventListener('tecos:students-changed', onStudentsChanged);
    return () => window.removeEventListener('tecos:students-changed', onStudentsChanged);
  }, [activeStudent?.code, reloadStudentPortal]);

  const navigateAdminFromNotification = React.useCallback((target) => {
    if (!target?.view) return;
    setAdminView(target.view);
    window.setTimeout(() => {
      window.dispatchEvent(new CustomEvent('tecos:admin-focus-entity', { detail: target }));
    }, 80);
  }, []);

  const navigateStudentFromNotification = React.useCallback((target) => {
    if (!target?.view) return;
    setAlumnoView(target.view);
  }, []);

  const pendingPublicScrollRef = React.useRef(null);

  const scrollToPublicAnchor = React.useCallback((navId, attempt = 0) => {
    const anchorId = resolvePublicAnchorId(navId);
    if (anchorId === 'top') {
      window.scrollTo({ top: 0, behavior: 'smooth' });
      return;
    }
    window.dispatchEvent(new CustomEvent('tecos:lazy-mount-section', { detail: { sectionId: anchorId } }));
    const el = document.getElementById(anchorId);
    if (!el) {
      if (attempt < 60) {
        window.setTimeout(() => scrollToPublicAnchor(navId, attempt + 1), 50);
      }
      return;
    }
    try {
      el.scrollIntoView({ behavior: attempt === 0 ? 'smooth' : 'auto', block: 'start' });
    } catch (_) {
      const navOffset = 88;
      const y = el.getBoundingClientRect().top + window.scrollY - navOffset;
      window.scrollTo({ top: Math.max(0, y), behavior: attempt === 0 ? 'smooth' : 'auto' });
    }
    if (attempt < 2) {
      window.setTimeout(() => scrollToPublicAnchor(navId, attempt + 1), 500);
    }
  }, []);

  const goToPublicSection = React.useCallback((id) => {
    const navKey = id || 'contacto';
    pendingPublicScrollRef.current = navKey;
    setScreen('public');
    setPublicSection(navKey);
    window.scrollTo(0, 0);
    window.requestAnimationFrame(() => {
      window.requestAnimationFrame(() => {
        window.setTimeout(() => {
          scrollToPublicAnchor(navKey);
          pendingPublicScrollRef.current = null;
        }, 200);
      });
    });
  }, [scrollToPublicAnchor]);

  useEffect(() => {
    if (pendingPublicScrollRef.current) return;
    if (screen === 'public' && publicSection && publicSection !== 'home') {
      scrollToPublicAnchor(publicSection);
    }
  }, [publicSection, screen, scrollToPublicAnchor]);

  React.useEffect(() => {
    window.__goToPublicSection = goToPublicSection;
    return () => { window.__goToPublicSection = null; };
  }, [goToPublicSection]);

  const handlePublicNav = (id) => {
    if (id === 'login') {
      if (typeof tecosEnsureAdminScripts === 'function') {
        tecosEnsureAdminScripts().catch(() => {});
      }
      setScreen('login');
      return;
    }
    if (id === 'inscripcion') {
      setInscripcionModalOpen(true);
      return;
    }
    setScreen('public');
    const navKey = (id === 'calendario' || id === 'eventos') ? 'calendario' : (id || 'home');
    pendingPublicScrollRef.current = navKey;
    setPublicSection(navKey);
    if (navKey === 'home') {
      pendingPublicScrollRef.current = null;
      window.scrollTo({ top: 0, behavior: 'smooth' });
      return;
    }
    window.setTimeout(() => {
      scrollToPublicAnchor(navKey, 0);
      pendingPublicScrollRef.current = null;
    }, 40);
  };

  const [passwordChangeCode, setPasswordChangeCode] = React.useState(null);

  const enterStudentPortal = React.useCallback(async (code) => {
    const normalized = typeof normalizeTecStudentCode === 'function'
      ? normalizeTecStudentCode(code)
      : String(code || '').trim().toUpperCase();
    setAlumnoPayments([]);
    setAlumnoOrders([]);
    setAlumnoExpediente([]);
    setActiveStudent(null);
    setScreen('alumno');
    setAlumnoView('a-dashboard');
    if (!isSupabaseReady()) {
      setActiveStudent({ code: normalized, name: normalized, shortName: normalized, cat: '—', status: 'activo' });
      return;
    }
    const found = await lookupStudentCode(normalized);
    if (!found) {
      setScreen('login');
      alert('No existe un alumno con ese ID. Verifica el código en Admin → Alumnos.');
      return;
    }
    await reloadStudentPortal(normalized);
  }, [reloadStudentPortal]);

  const handleLogin = async (mode, payload) => {
    if (mode === 'admin') {
      setAdminView('dashboard');
      setScreen('admin');
      return;
    }
    const code = payload?.code || payload?.student?.code;
    if (payload?.mustChangePassword) {
      setPasswordChangeCode(code);
      return;
    }
    await enterStudentPortal(code);
  };

  const handleLogout = async () => {
    if (typeof signOutSupabase === 'function') await signOutSupabase();
    setActiveStudent(null);
    setAlumnoPayments([]);
    setAlumnoOrders([]);
    setAlumnoExpediente([]);
    setScreen('public');
    setPublicSection('home');
    window.scrollTo(0, 0);
  };

  // Render
  if (screen === 'login') {
    return (
      <>
        <LoginScreen
          theme={theme}
          onLogin={handleLogin}
          onBack={() => setScreen('public')}
        />
        <StudentChangePasswordModal
          open={!!passwordChangeCode}
          theme={theme}
          studentCode={passwordChangeCode}
          onClose={() => setPasswordChangeCode(null)}
          onSuccess={async () => {
            const c = passwordChangeCode;
            setPasswordChangeCode(null);
            await enterStudentPortal(c);
          }}
        />
        <TweaksUi t={t} setTweak={setTweak} />
      </>
    );
  }

  if (screen === 'admin') {
    if (typeof Sidebar !== 'function' || typeof AdminTopbar !== 'function') {
      return (
        <div style={{
          minHeight: '100vh', background: theme.bg, color: theme.text,
          display: 'grid', placeItems: 'center', padding: 24, textAlign: 'center',
        }} data-screen-label="Admin">
          <LoadingBlock theme={theme} label="Cargando panel de administración…" />
          <p style={{ marginTop: 16, fontSize: 13, color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>
            Si no avanza, recarga con Ctrl+Shift+R (o limpia caché).
          </p>
          <TweaksUi t={t} setTweak={setTweak} />
        </div>
      );
    }
    return (
      <div className="tecos-shell-admin" style={{
        display: 'flex', minHeight: '100vh', background: theme.bg, color: theme.text,
        width: '100%', maxWidth: '100%', overflowX: 'hidden',
      }} data-screen-label="Admin">
        <Sidebar theme={theme} current={adminView} onNav={setAdminView} variant={t.sidebarVariant} onLogout={handleLogout}
          mobileOpen={adminDrawerOpen} onMobileClose={() => setAdminDrawerOpen(false)} />
        <main className="tecos-main tecos-main--admin" style={{ flex: 1, minWidth: 0, width: '100%', maxWidth: '100%', overflowX: 'hidden' }}>
          <AdminTopbar theme={theme}
            title={adminViewTitle(adminView)}
            subtitle={adminViewSub(adminView)}
            notificationAudience="admin"
            onAdminNavigate={navigateAdminFromNotification}
            themeKey={t.theme}
            onThemeToggle={() => setTweak('theme', t.theme === 'dark' ? 'light' : 'dark')}
            onMenuToggle={() => setAdminDrawerOpen(o => !o)} />
          {renderAdminView(adminView, theme, t, { onWhatsApp: setWaPreview, onNav: setAdminView })}
        </main>
        {typeof WaPreviewModal === 'function' && (
          <WaPreviewModal open={!!waPreview} onClose={() => setWaPreview(null)} recipient={waPreview} theme={theme} />
        )}
        <TweaksUi t={t} setTweak={setTweak} />
      </div>
    );
  }

  if (screen === 'alumno') {
    return (
      <div className="tecos-shell-alumno" style={{ display: 'flex', minHeight: '100vh', background: theme.bg, color: theme.text }} data-screen-label="Alumno">
        <AlumnoSidebar theme={theme} current={alumnoView} onNav={setAlumnoView} onLogout={handleLogout} student={activeStudent}
          mobileOpen={alumnoDrawerOpen} onMobileClose={() => setAlumnoDrawerOpen(false)} />
        <main className="tecos-main" style={{ flex: 1, minWidth: 0 }}>
          <AdminTopbar theme={theme} title={alumnoViewTitle(alumnoView)} subtitle="Portal del Alumno"
            panelLabel="Portal del alumno" notificationAudience="student" studentCode={activeStudent?.code}
            onStudentNavigate={navigateStudentFromNotification}
            themeKey={t.theme}
            onThemeToggle={() => setTweak('theme', t.theme === 'dark' ? 'light' : 'dark')}
            onMenuToggle={() => setAlumnoDrawerOpen(o => !o)} />
          {portalLoading ? <LoadingBlock theme={theme} label="Cargando tu portal…" /> : alumnoView === 'a-dashboard'
            ? <AlumnoDashboard theme={theme} student={activeStudent} studentCode={activeStudent?.code}
              onPayClick={setPaymentDetail} months={alumnoPayments} orders={alumnoOrders} onOrderClick={setOrderDetail}
              onNav={setAlumnoView} onNotifNavigate={navigateStudentFromNotification}
              billingSettings={portalBillingCtx?.settings}
              {...paymentCalendarNavProps} />
            : <AlumnoSubview theme={theme} view={alumnoView} student={activeStudent} onPayClick={setPaymentDetail} months={alumnoPayments} orders={alumnoOrders} expediente={alumnoExpediente} documents={alumnoDocuments}
              documentRequirements={activeStudent?.document_requirements}
              onDocumentsUpdated={() => activeStudent?.code && reloadStudentPortal(activeStudent.code)}
              onOrderClick={setOrderDetail}
              billingSettings={portalBillingCtx?.settings}
              onNotifNavigate={navigateStudentFromNotification}
              onPhotoUpdated={() => activeStudent?.code && reloadStudentPortal(activeStudent.code)}
              {...paymentCalendarNavProps} />}
        </main>
        <AlumnoOrderModal
          open={!!orderDetail}
          onClose={() => setOrderDetail(null)}
          order={orderDetail}
          theme={theme}
          studentCode={activeStudent?.code}
          studentName={activeStudent?.name}
          onOrderUpdated={(updated) => {
            setAlumnoOrders(prev => prev.map(o => o.id === updated.id ? { ...o, ...updated } : o));
            setOrderDetail(null);
            if (activeStudent?.code) reloadStudentPortal(activeStudent.code);
          }}
        />
        <PaymentModal
          open={!!paymentDetail}
          onClose={() => setPaymentDetail(null)}
          payment={paymentDetail}
          theme={theme}
          student={activeStudent}
          studentCode={activeStudent?.code}
          studentUuid={activeStudent?._uuid}
          onPaymentUpdated={(updated) => {
            setAlumnoPayments(prev => prev.map(m => m.key === updated.key ? { ...m, ...updated } : m));
            setPaymentDetail(updated);
            if (activeStudent?.code) reloadStudentPortal(activeStudent.code);
          }}
        />
        <TweaksUi t={t} setTweak={setTweak} />
      </div>
    );
  }

  if (screen === 'mobile-public') {
    return (
      <div data-screen-label="Mobile · Público">
        <MobilePreviewSingle theme={theme} kind="public" onBack={() => setScreen('public')} />
        <TweaksUi t={t} setTweak={setTweak} />
        <RoleSwitcher screen={screen} setScreen={setScreen} setAdminView={setAdminView} setAlumnoView={setAlumnoView} theme={theme} />
      </div>
    );
  }

  if (screen === 'mobile-alumno') {
    return (
      <div data-screen-label="Mobile · Alumno">
        <MobilePreviewSingle theme={theme} kind="alumno" onBack={() => setScreen('public')} />
        <TweaksUi t={t} setTweak={setTweak} />
        <RoleSwitcher screen={screen} setScreen={setScreen} setAdminView={setAdminView} setAlumnoView={setAlumnoView} theme={theme} />
      </div>
    );
  }

  if (screen === 'mobile-both') {
    return (
      <div data-screen-label="Mobile · Ambos">
        <MobilePreview theme={theme} />
        <TweaksUi t={t} setTweak={setTweak} />
        <RoleSwitcher screen={screen} setScreen={setScreen} setAdminView={setAdminView} setAlumnoView={setAlumnoView} theme={theme} />
      </div>
    );
  }

  const Section = (typeof window !== 'undefined' && typeof window.LandingSectionAnchor === 'function')
    ? window.LandingSectionAnchor
    : (typeof LazyWhenVisible === 'function' ? LazyWhenVisible : ({ id, sectionId, children }) => (
      <div id={id || sectionId}>{children}</div>
    ));
  const SettingsWrap = typeof AcademySettingsProvider === 'function'
    ? AcademySettingsProvider
    : ({ children }) => children;

  // Public site
  return (
    <SettingsWrap>
    <div style={{ background: theme.bg, color: theme.text, minHeight: '100vh' }} data-screen-label="Public">
      <TopNav
        theme={theme}
        onNav={handlePublicNav}
        current={publicSection}
        themeKey={t.theme}
        onThemeToggle={() => setTweak('theme', t.theme === 'dark' ? 'light' : 'dark')}
      />
      <div id="top"></div>
      <Hero theme={theme} onNav={handlePublicNav} heroVariant={t.heroVariant} />
      <Section id="avisos" eager minHeight={120} rootMargin="200px 0px">
        <AvisosSection theme={theme} />
      </Section>
      <Section id="calendario" eager minHeight={360} rootMargin="500px 0px">
      <CalendarioSection
        theme={theme}
        onEventClick={setEventModal}
        onAnnouncementClick={setAvisoModal}
        onBirthdayClick={setBirthdayModal}
        highlightDayKey={calendarHighlight?.dayKey}
        highlightColor={calendarHighlight?.color}
        onCalendarFocus={(ev) => {
          const mapped = ev?.dayKeys
            ? ev
            : (ev?.itemKind === 'anuncio' || ev?.body
              ? mapAnnouncementCalendar(ev._raw || ev, theme)
              : mapEventCalendar(ev._raw || ev, theme));
          if (!mapped) return;
          const dayKey = mapped.dayKeys?.[0];
          if (!dayKey) return;
          setCalendarHighlight({ dayKey, color: mapped.color, eventId: mapped.id });
          requestAnimationFrame(() => {
            document.getElementById('calendario')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
          });
          window.setTimeout(() => setCalendarHighlight(null), 8000);
        }}
      />
      </Section>
      <Section id="entrenadores" eager minHeight={300} rootMargin="500px 0px">
        <EntrenadoresSection theme={theme} onCoachClick={setCoachModal} />
      </Section>
      <Section id="galeria" eager minHeight={320} rootMargin="500px 0px">
        <GaleriaSection theme={theme} />
      </Section>
      <Section id="tienda" eager minHeight={280} rootMargin="500px 0px">
        <TiendaSection theme={theme} onOrder={setOrderProduct} compact landingOnly showStoreLink />
      </Section>
      <Section id="ubicacion" eager minHeight={380} rootMargin="500px 0px">
        <MapaSection theme={theme} />
      </Section>
      <Section id="solicita-informacion" eager minHeight={240} rootMargin="400px 0px">
        <FormSection theme={theme} />
      </Section>
      <Footer theme={theme} onNav={handlePublicNav} onOpenInscripcion={() => setInscripcionModalOpen(true)} />

      <SolicitaInformacionModal
        open={inscripcionModalOpen}
        onClose={() => setInscripcionModalOpen(false)}
        theme={theme}
      />

      <EventModal open={!!eventModal} onClose={() => setEventModal(null)} ev={eventModal} theme={theme} />
      <AvisoModal open={!!avisoModal} onClose={() => setAvisoModal(null)} aviso={avisoModal} theme={theme} />
      <BirthdayCongratsModal
        open={!!birthdayModal}
        onClose={() => setBirthdayModal(null)}
        item={birthdayModal}
        theme={theme}
      />
      <CoachModal open={!!coachModal} onClose={() => setCoachModal(null)} coach={coachModal} theme={theme} />
      <OrderFlow
        open={!!orderProduct}
        onClose={() => setOrderProduct(null)}
        product={orderProduct}
        theme={theme}
        onOrderPlaced={(meta) => {
          if (!activeStudent?.code || meta.studentCode?.toUpperCase() !== activeStudent.code.toUpperCase()) return;
          const fecha = new Date().toLocaleDateString('es-MX', { day: 'numeric', month: 'short', year: 'numeric' });
          setAlumnoOrders(prev => [{
            id: meta.orderId || `local-${Date.now()}`,
            p: meta.productName,
            d: fecha,
            n: meta.orderNumber,
            a: meta.total,
            s: 'en_revision',
            i: meta.icon || 'cart',
            phone: meta.phone,
            orderId: meta.orderId,
          }, ...prev]);
        }}
      />

      <TweaksUi t={t} setTweak={setTweak} />
    </div>
    </SettingsWrap>
  );
}

function adminViewTitle(v) {
  const titles = {
    dashboard: 'Dashboard', alumnos: 'Alumnos', pagos: 'Ventas y Pagos', comprobantes: 'Verificar comprobantes',
    historial: 'Historial',
    'wa-dashboard': 'WhatsApp', 'wa-recordatorios': 'Recordatorios de pago',
    'wa-pendientes': 'Mensajes pendientes', 'wa-urgentes': 'Mensajes urgentes',
    'wa-campanas': 'Campañas', 'wa-plantillas': 'Plantillas',
    'wa-historial': 'Historial', 'wa-programar': 'Programar mensajes',
    anuncios: 'Anuncios', eventos: 'Eventos',
    inventario: 'Inventario', 'tienda-admin': 'Tienda online',
    'nomina-gastos': 'Nómina y gastos',
    'galeria-admin': 'Galería', 'entrenadores-admin': 'Entrenadores',
    ubicacion: 'Ubicación', interesados: 'Interesados', config: 'Configuración',
  };
  return titles[v] || 'Panel';
}

function adminViewSub(v) {
  if (v.startsWith('wa-')) return 'Módulo de mensajería WhatsApp';
  if (v === 'pagos') return 'Registro de pagos por alumno y calendario mensual';
  if (v === 'comprobantes') return 'Revisa comprobantes subidos por alumnos';
  if (v === 'historial') return 'Mensualidades y órdenes de tienda ya confirmadas';
  if (v === 'nomina-gastos') return 'Nómina de entrenadores, gastos operativos y retiros con fecha y hora';
  if (v === 'alumnos') return 'Expedientes de alumnos';
  return 'Panel administrador · Tecos Elite';
}

function alumnoViewTitle(v) {
  const titles = {
    'a-dashboard': 'Mi inicio', 'a-pagos': 'Calendario de pagos',
    'a-papeleria': 'Mi papelería', 'a-expediente': 'Expediente de pagos', 'a-compras': 'Mis compras',
    'a-eventos': 'Eventos', 'a-avisos': 'Avisos',
    'a-notificaciones': 'Notificaciones', 'a-perfil': 'Mi perfil',
  };
  return titles[v] || 'Portal';
}

function renderAdminView(v, theme, t, handlers) {
  if (v === 'dashboard') {
    if (typeof AdminDashboard !== 'function') {
      return (
        <div style={{ padding: 24, fontFamily: 'Inter, sans-serif', color: theme.text }}>
          No se pudo cargar el dashboard. Recarga la página (Ctrl+F5).
        </div>
      );
    }
    return <AdminDashboard theme={theme} cardVariant={t.cardVariant} onNav={handlers.onNav} />;
  }
  if (v === 'alumnos') return <AlumnosModule theme={theme} onWhatsApp={handlers.onWhatsApp} />;
  if (v === 'pagos') return <PagosModule theme={theme} onWhatsApp={handlers.onWhatsApp} />;
  if (v === 'comprobantes') return <ComprobantesModule theme={theme} />;
  if (v === 'historial') return <HistorialModule theme={theme} />;
  if (v.startsWith('wa-')) return <WhatsAppModule theme={theme} view={v} onPreview={handlers.onWhatsApp} />;
  const entity = typeof renderAdminEntityView === 'function' ? renderAdminEntityView(v, theme) : null;
  if (entity) return entity;
  return <EmptyState theme={theme} title="Módulo" message="Sección no configurada." icon="settings" />;
}

/* Floating role switcher (top-right corner) */
function RoleSwitcher({ screen, setScreen, setAdminView, setAlumnoView, theme }) {
  const [open, setOpen] = useState(false);
  return (
    <div className="tecos-role-switcher" style={{
      position: 'fixed', top: 100, right: 16, zIndex: 950,
    }}>
      <button onClick={() => setOpen(!open)} style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 14px', borderRadius: 999,
        background: theme.primary, color: '#fff',
        border: 'none', cursor: 'pointer',
        fontSize: 11, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase',
        fontFamily: 'Inter, sans-serif',
        boxShadow: `0 8px 24px ${theme.primaryGlow}`,
      }}>
        <Icon name="eye" size={14} />Ver como
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 48, right: 0, width: 200,
          background: theme.bgElev, border: `1px solid ${theme.borderStrong}`,
          borderRadius: 12, padding: 6,
          boxShadow: `0 12px 40px rgba(0,0,0,0.3)`,
          display: 'grid', gap: 2,
        }}>
          {[
            { id: 'public', l: 'Sitio público', icon: 'home', go: () => { setScreen('public'); setOpen(false); } },
            { id: 'login', l: 'Pantalla de login', icon: 'user', go: () => { setScreen('login'); setOpen(false); } },
            { id: 'admin', l: 'Panel administrador', icon: 'settings', go: () => { setScreen('admin'); setAdminView('dashboard'); setOpen(false); } },
            { id: 'alumno', l: 'Portal del alumno', icon: 'medal', go: () => { setScreen('alumno'); setAlumnoView('a-dashboard'); setOpen(false); } },
            { sep: true },
            { id: 'mobile-public', l: '📱 Mobile · Público', icon: 'image', go: () => { setScreen('mobile-public'); setOpen(false); } },
            { id: 'mobile-alumno', l: '📱 Mobile · Alumno', icon: 'image', go: () => { setScreen('mobile-alumno'); setOpen(false); } },
            { id: 'mobile-both', l: '📱 Mobile · Ambos', icon: 'grid', go: () => { setScreen('mobile-both'); setOpen(false); } },
          ].map((o, i) => o.sep ? (
            <div key={'sep' + i} style={{ height: 1, background: theme.border, margin: '4px 8px' }}></div>
          ) : (
            <button key={o.id} onClick={o.go} style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '8px 12px', borderRadius: 8, border: 'none',
              background: screen === o.id ? `${theme.primary}22` : 'transparent',
              color: screen === o.id ? theme.primary : theme.text,
              cursor: 'pointer', fontSize: 12, fontWeight: 600, textAlign: 'left',
              fontFamily: 'Inter, sans-serif',
            }}><Icon name={o.icon} size={14} />{o.l}</button>
          ))}
        </div>
      )}
    </div>
  );
}

/* TWEAKS UI */
function TweaksUi({ t, setTweak }) {
  return (
    <TweaksPanel title="Tweaks · Tecos Elite">
      <TweakSection label="Tema visual" />
      <TweakRadio label="Tema" value={t.theme}
        options={['light', 'dark', 'blue']}
        onChange={(v) => setTweak('theme', v)} />

      <TweakSection label="Hero (inicio público)" />
      <TweakRadio label="Variante" value={t.heroVariant}
        options={['animated', 'static', 'video']}
        onChange={(v) => setTweak('heroVariant', v)} />

      <TweakSection label="Sidebar admin" />
      <TweakRadio label="Estilo" value={t.sidebarVariant}
        options={['expanded', 'compact', 'icons']}
        onChange={(v) => setTweak('sidebarVariant', v)} />

      <TweakSection label="Tarjetas dashboard" />
      <TweakRadio label="Estilo" value={t.cardVariant}
        options={['standard', 'minimal', 'gradient']}
        onChange={(v) => setTweak('cardVariant', v)} />

      <TweakSection label="Tienda" />
      <TweakSelect label="Layout" value={t.tiendaLayout}
        options={['grid', 'list', 'featured']}
        onChange={(v) => setTweak('tiendaLayout', v)} />
    </TweaksPanel>
  );
}

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

/* Single-mobile preview wrapper — shows one device centered with a back button */
function MobilePreviewSingle({ theme, kind, onBack }) {
  return (
    <div style={{
      minHeight: '100vh',
      background: `linear-gradient(135deg, ${theme.bg}, ${theme.bgElev})`,
      padding: 40, position: 'relative', overflow: 'hidden',
      display: 'grid', placeItems: 'center',
      fontFamily: 'Inter, sans-serif',
    }}>
      <div style={{ position: 'absolute', top: -120, right: -120, opacity: 0.06 }}>
        <Volleyball size={500} color={theme.primary} />
      </div>
      <div style={{ position: 'absolute', bottom: -120, left: -120, opacity: 0.05 }}>
        <Volleyball size={400} color={theme.accent} />
      </div>
      <button onClick={onBack} style={{
        position: 'absolute', top: 24, left: 24,
        padding: '10px 16px', borderRadius: 10,
        background: theme.bgElev, border: `1px solid ${theme.borderStrong}`,
        color: theme.text, cursor: 'pointer',
        display: 'flex', alignItems: 'center', gap: 8,
        fontSize: 12, fontWeight: 600, fontFamily: 'Inter, sans-serif',
      }}><Icon name="arrowLeft" size={14} />Volver al desktop</button>
      <div style={{ textAlign: 'center', position: 'absolute', top: 30, left: 0, right: 0 }}>
        <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: 3, color: theme.primary, textTransform: 'uppercase' }}>
          📱 Vista mobile · {kind === 'public' ? 'Sitio público' : 'Portal alumno'}
        </div>
      </div>
      <div style={{ position: 'relative' }}>
        {kind === 'public' ? <MobilePublic theme={theme} /> : <MobileAlumno theme={theme} />}
      </div>
    </div>
  );
}
