/* Campana de notificaciones — Supabase Realtime (admin) + polling (alumno demo) */

const ADMIN_NOTIF_TYPE_LABELS = {
  payment: 'Mensualidad',
  order: 'Tienda',
  lead: 'Contacto / interés',
  event: 'Evento',
  announcement: 'Aviso',
  inventory: 'Inventario',
};

/** Destino en panel admin según entity_type / category de Supabase */
function resolveAdminNotificationTarget (n) {
  if (!n) return null;
  const et = String(n.entity_type || '').toLowerCase();
  const cat = String(n.category || '').toLowerCase();
  const title = String(n.title || '').toLowerCase();
  const entityId = n.entity_id || null;

  if (et === 'interested_lead' || et === 'lead' || cat === 'lead') {
    return { view: 'interesados', entityId, entityType: 'interested_lead' };
  }
  if (et === 'event' || cat === 'event') {
    return { view: 'eventos', entityId, entityType: 'event' };
  }
  if (et === 'announcement' || cat === 'announcement') {
    return { view: 'anuncios', entityId, entityType: 'announcement' };
  }
  if (cat === 'inventory' || title.includes('stock')) {
    return { view: 'inventario', entityId, entityType: 'order' };
  }
  if (et === 'payment' || cat === 'payment') {
    if (title.includes('comprobante')) {
      return { view: 'comprobantes', entityId, entityType: 'payment', comprobantesTab: 'mensualidades' };
    }
    return { view: 'pagos', entityId, entityType: 'payment' };
  }
  if (et === 'order' || cat === 'order') {
    if (title.includes('nueva orden')) {
      return { view: 'comprobantes', entityId, entityType: 'order', comprobantesTab: 'tienda' };
    }
    if (title.includes('comprobante') || title.includes('revisar')) {
      return { view: 'comprobantes', entityId, entityType: 'order', comprobantesTab: 'tienda' };
    }
    return { view: 'comprobantes', entityId, entityType: 'order', comprobantesTab: 'tienda' };
  }
  return null;
}

/** Destino en portal alumno según categoría / entity_type */
function resolveStudentNotificationTarget (n) {
  if (!n) return null;
  const et = String(n.entity_type || '').toLowerCase();
  const cat = String(n.category || '').toLowerCase();
  if (et === 'payment' || cat.startsWith('payment')) return { view: 'a-pagos' };
  if (et === 'order' || cat === 'order') return { view: 'a-compras' };
  if (et === 'event' || cat === 'event') return { view: 'a-eventos' };
  if (cat.startsWith('birthday')) return { view: 'a-dashboard' };
  return { view: 'a-notificaciones' };
}

const formatNotifTime = (iso) => {
  if (!iso) return '';
  try {
    const d = new Date(iso);
    const diff = (Date.now() - d.getTime()) / 1000;
    if (diff < 60) return 'Hace un momento';
    if (diff < 3600) return `Hace ${Math.floor(diff / 60)} min`;
    if (diff < 86400) return `Hace ${Math.floor(diff / 3600)} h`;
    return d.toLocaleDateString('es-MX', { day: 'numeric', month: 'short' });
  } catch {
    return '';
  }
};

/** No leídas primero; dentro de cada grupo, las más recientes arriba. */
function sortNotificationItems (items) {
  return [...(items || [])].sort((a, b) => {
    const aRead = !!a.read_at;
    const bRead = !!b.read_at;
    if (aRead !== bRead) return aRead ? 1 : -1;
    const ta = new Date(a.created_at || 0).getTime();
    const tb = new Date(b.created_at || 0).getTime();
    return tb - ta;
  });
}

function partitionNotifications (items) {
  const sorted = sortNotificationItems(items);
  return {
    sorted,
    unread: sorted.filter((n) => !n.read_at),
    read: sorted.filter((n) => n.read_at),
  };
}

const NotificationRow = ({ n, theme, onRead, onActivate, onStudentNavigate }) => {
  const target = onActivate
    ? resolveAdminNotificationTarget(n)
    : (onStudentNavigate ? resolveStudentNotificationTarget(n) : null);
  const canNavigate = !!(target?.view && (onActivate || onStudentNavigate));
  return (
  <button
    type="button"
    onClick={() => {
      if (canNavigate) {
        if (onActivate) onActivate(target, n);
        else if (onStudentNavigate) onStudentNavigate(target, n);
      }
      onRead(n);
    }}
    title={canNavigate ? 'Ir al módulo' : undefined}
    style={{
      display: 'flex', gap: 12, padding: 12, width: '100%', textAlign: 'left',
      border: 'none', cursor: 'pointer', borderRadius: 8,
      background: n.read_at ? 'transparent' : `${theme.primary}14`,
      borderBottom: `1px solid ${theme.border}`,
      fontFamily: 'Inter, sans-serif',
      opacity: n.read_at ? 0.72 : 1,
    }}
  >
    <div style={{
      width: 40, height: 40, borderRadius: 10, flexShrink: 0,
      background: `${theme.primary}22`, color: theme.primary,
      display: 'grid', placeItems: 'center',
    }}>
      <Icon name={n.icon || 'bell'} size={18} />
    </div>
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'flex-start' }}>
        <span style={{ fontWeight: 700, fontSize: 13, color: theme.text }}>{n.title}</span>
        {!n.read_at && <span style={{ width: 8, height: 8, borderRadius: '50%', background: theme.danger, flexShrink: 0, marginTop: 4 }} />}
      </div>
      {n.body && <p style={{ margin: '4px 0 0', fontSize: 12, color: theme.textDim, lineHeight: 1.4 }}>{n.body}</p>}
      {(n.category || n.entity_type) && onActivate && (
        <span style={{
          display: 'inline-block', marginTop: 6, padding: '2px 8px', borderRadius: 999,
          fontSize: 9, fontWeight: 700, letterSpacing: 0.6, textTransform: 'uppercase',
          background: `${theme.primary}18`, color: theme.primary,
        }}>
          {ADMIN_NOTIF_TYPE_LABELS[String(n.category || n.entity_type || '').toLowerCase()]
            || ADMIN_NOTIF_TYPE_LABELS[String(n.entity_type || '').toLowerCase()]
            || 'Actividad'}
        </span>
      )}
      <div style={{ fontSize: 10, color: theme.textMute, marginTop: 6, display: 'flex', justifyContent: 'space-between', gap: 8 }}>
        <span>{formatNotifTime(n.created_at)}</span>
        {canNavigate && <span style={{ color: theme.primary, fontWeight: 600 }}>Abrir módulo →</span>}
      </div>
    </div>
  </button>
  );
};

const useNotifications = ({ audience, studentCode }) => {
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  const load = React.useCallback(async () => {
    if (!isSupabaseReady()) {
      setItems([]);
      setLoading(false);
      return;
    }
    try {
      if (audience === 'admin') {
        const rows = await fetchAdminNotifications();
        setItems(sortNotificationItems(rows));
      } else if (studentCode) {
        const rows = await fetchStudentNotificationsByCode(studentCode);
        setItems(sortNotificationItems(rows));
      }
    } catch (e) {
      console.error('[Tecos] notifications', e);
    }
    setLoading(false);
  }, [audience, studentCode]);

  React.useEffect(() => {
    setLoading(true);
    load();
    let unsub = () => {};
    let pollId = null;

    if (isSupabaseReady()) {
      if (audience === 'admin') {
        unsub = subscribeAdminNotifications(() => load());
        pollId = setInterval(load, 15000);
      } else if (studentCode) {
        pollId = setInterval(load, 8000);
      }
    }

    const onLocal = () => load();
    window.addEventListener('tecos:notifications-changed', onLocal);

    return () => {
      unsub();
      if (pollId) clearInterval(pollId);
      window.removeEventListener('tecos:notifications-changed', onLocal);
    };
  }, [audience, studentCode, load]);

  const unread = items.filter(n => !n.read_at).length;

  const markRead = async (n) => {
    if (!n?.id || n.read_at) return;
    try {
      if (audience === 'admin') await markNotificationRead(n.id);
      else if (studentCode) await markNotificationReadByCode(n.id, studentCode);
      const now = new Date().toISOString();
      setItems((prev) => sortNotificationItems(
        prev.map((x) => (x.id === n.id ? { ...x, read_at: now } : x)),
      ));
      window.dispatchNotificationsChanged?.();
    } catch (e) {
      console.error('[Tecos] mark read', e);
      alert(e.message || 'No se pudo marcar como leída. Inicia sesión como administrador.');
    }
  };

  const markAllRead = async () => {
    const unreadItems = items.filter(n => !n.read_at);
    if (!unreadItems.length) return;
    try {
      if (audience === 'admin') {
        const session = typeof getAuthSession === 'function' ? await getAuthSession() : null;
        if (!session) {
          alert('Inicia sesión como administrador (correo y contraseña) para marcar notificaciones como leídas.');
          return;
        }
        await markAllNotificationsRead('admin');
      } else if (studentCode) {
        await markAllNotificationsRead('student', studentCode);
      }
      const now = new Date().toISOString();
      setItems((prev) => sortNotificationItems(
        prev.map((x) => ({ ...x, read_at: x.read_at || now })),
      ));
      await load();
      window.dispatchNotificationsChanged?.();
    } catch (e) {
      console.error('[Tecos] mark all', e);
      alert(e.message || 'No se pudieron marcar como leídas.');
    }
  };

  const deleteAll = async () => {
    if (!items.length) return;
    try {
      if (audience === 'admin') {
        await deleteAdminNotifications();
      } else if (studentCode) {
        await deleteStudentNotificationsByCode(studentCode);
      }
      setItems([]);
      await load();
      window.dispatchNotificationsChanged?.();
    } catch (e) {
      console.error('[Tecos] delete notifications', e);
      alert(e.message || 'No se pudieron borrar las notificaciones.');
    }
  };

  const sortedItems = React.useMemo(() => sortNotificationItems(items), [items]);
  const { unread: unreadList, read: readList } = React.useMemo(
    () => partitionNotifications(items),
    [items],
  );

  return {
    items: sortedItems,
    unreadList,
    readList,
    loading,
    unread,
    load,
    markRead,
    markAllRead,
    deleteAll,
  };
};

const NotificationListBody = ({
  theme, loading, items, unreadList, readList, markRead, onActivate, onStudentNavigate, maxItems,
}) => {
  if (loading) {
    return <div style={{ padding: 24, textAlign: 'center', color: theme.textMute, fontSize: 13 }}>Cargando…</div>;
  }
  if (!items.length) {
    return (
      <div className="tecos-page-shell" style={{ padding: 32, textAlign: 'center', color: theme.textDim, fontSize: 13 }}>
        Sin notificaciones
      </div>
    );
  }

  const slice = (list) => (maxItems ? list.slice(0, maxItems) : list);
  const unreadShow = slice(unreadList);
  const readShow = maxItems
    ? readList.slice(0, Math.max(0, maxItems - unreadShow.length))
    : readList;

  const sectionLabel = (text) => (
    <div style={{
      padding: '8px 14px 6px', fontSize: 10, fontWeight: 700, letterSpacing: 0.8,
      textTransform: 'uppercase', color: theme.textMute, fontFamily: 'Inter, sans-serif',
      background: theme.bgInput, borderBottom: `1px solid ${theme.border}`,
    }}>{text}</div>
  );

  return (
    <>
      {unreadShow.length > 0 && (
        <>
          {readShow.length > 0 && sectionLabel('Sin leer')}
          {unreadShow.map((n) => (
            <NotificationRow key={n.id} n={n} theme={theme} onRead={markRead}
              onActivate={onActivate} onStudentNavigate={onStudentNavigate} />
          ))}
        </>
      )}
      {readShow.length > 0 && (
        <>
          {unreadShow.length > 0 && sectionLabel('Leídas')}
          {readShow.map((n) => (
            <NotificationRow key={n.id} n={n} theme={theme} onRead={markRead}
              onActivate={onActivate} onStudentNavigate={onStudentNavigate} />
          ))}
        </>
      )}
    </>
  );
};

const NotificationBell = ({ theme, audience = 'admin', studentCode, onAdminNavigate, onStudentNavigate }) => {
  const [open, setOpen] = React.useState(false);
  const [markingAll, setMarkingAll] = React.useState(false);
  const ref = React.useRef(null);
  const {
    items, unreadList, readList, loading, unread, load, markRead, markAllRead, deleteAll,
  } = useNotifications({ audience, studentCode });
  const [deletingAll, setDeletingAll] = React.useState(false);

  const handleMarkAllRead = async (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (markingAll || unread === 0) return;
    setMarkingAll(true);
    await markAllRead();
    setMarkingAll(false);
  };

  const handleDeleteAll = async (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (deletingAll || !items.length) return;
    if (!confirm('¿Borrar todas las notificaciones? Esta acción no se puede deshacer.')) return;
    setDeletingAll(true);
    await deleteAll();
    setDeletingAll(false);
  };

  const handleActivate = React.useCallback((target) => {
    if (audience === 'admin' && typeof onAdminNavigate === 'function') {
      onAdminNavigate(target);
      setOpen(false);
      return;
    }
    if (audience === 'student' && typeof onStudentNavigate === 'function') {
      onStudentNavigate(target);
      setOpen(false);
    }
  }, [audience, onAdminNavigate, onStudentNavigate]);

  React.useEffect(() => {
    const close = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    if (open) document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, [open]);

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button
        type="button"
        onClick={() => { setOpen(o => !o); if (!open) load(); }}
        style={{
          width: 40, height: 40, borderRadius: 10,
          background: theme.bgInput, border: `1px solid ${theme.border}`,
          color: theme.text, cursor: 'pointer', position: 'relative',
          display: 'grid', placeItems: 'center',
        }}
        aria-label="Notificaciones"
      >
        <Icon name="bell" size={18} />
        {unread > 0 && (
          <span style={{
            position: 'absolute', top: 4, right: 4, minWidth: 18, height: 18, padding: '0 5px',
            borderRadius: 999, background: theme.danger, color: '#fff',
            fontSize: 10, fontWeight: 800, display: 'grid', placeItems: 'center',
            border: `2px solid ${theme.bg}`,
          }}>{unread > 9 ? '9+' : unread}</span>
        )}
      </button>

      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 8px)', right: 0, width: 360, maxHeight: 420,
          background: theme.bgElev, border: `1px solid ${theme.border}`,
          borderRadius: 12, boxShadow: '0 16px 48px rgba(0,0,0,0.35)',
          zIndex: 200, overflow: 'hidden', display: 'flex', flexDirection: 'column',
        }}>
          <div style={{
            padding: '14px 16px', borderBottom: `1px solid ${theme.border}`,
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <span style={{ fontWeight: 700, fontSize: 14, color: theme.text, fontFamily: 'Inter, sans-serif' }}>Notificaciones</span>
            <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
              {unread > 0 && (
                <button type="button" onClick={handleMarkAllRead} disabled={markingAll || deletingAll} style={{
                  background: 'none', border: 'none', color: theme.primary, fontSize: 11,
                  fontWeight: 700, cursor: markingAll ? 'wait' : 'pointer', fontFamily: 'Inter, sans-serif',
                  opacity: markingAll ? 0.6 : 1,
                }}>{markingAll ? 'Marcando…' : 'Marcar leídas'}</button>
              )}
              {items.length > 0 && (
                <button type="button" onClick={handleDeleteAll} disabled={deletingAll || markingAll} style={{
                  background: 'none', border: 'none', color: theme.danger, fontSize: 11,
                  fontWeight: 700, cursor: deletingAll ? 'wait' : 'pointer', fontFamily: 'Inter, sans-serif',
                  opacity: deletingAll ? 0.6 : 1,
                }}>{deletingAll ? 'Borrando…' : 'Borrar todas'}</button>
              )}
            </div>
          </div>
          <div style={{ overflowY: 'auto', flex: 1 }}>
            <NotificationListBody
              theme={theme}
              loading={loading}
              items={items}
              unreadList={unreadList}
              readList={readList}
              markRead={markRead}
              maxItems={35}
              onActivate={audience === 'admin' ? handleActivate : undefined}
              onStudentNavigate={audience === 'student' ? handleActivate : undefined}
            />
          </div>
        </div>
      )}
    </div>
  );
};

const NotificationsFullPage = ({ theme, audience = 'admin', studentCode, onAdminNavigate, onStudentNavigate }) => {
  const {
    items, unreadList, readList, loading, unread, markRead, markAllRead, deleteAll,
  } = useNotifications({ audience, studentCode });
  const [markingAll, setMarkingAll] = React.useState(false);
  const [deletingAll, setDeletingAll] = React.useState(false);
  const handleActivate = React.useCallback((target) => {
    if (audience === 'admin' && typeof onAdminNavigate === 'function') onAdminNavigate(target);
    else if (audience === 'student' && typeof onStudentNavigate === 'function') onStudentNavigate(target);
  }, [audience, onAdminNavigate, onStudentNavigate]);

  const handleMarkAllRead = async () => {
    if (markingAll || unread === 0) return;
    setMarkingAll(true);
    await markAllRead();
    setMarkingAll(false);
  };

  const handleDeleteAll = async () => {
    if (deletingAll || !items.length) return;
    if (!confirm('¿Borrar todas las notificaciones? Esta acción no se puede deshacer.')) return;
    setDeletingAll(true);
    await deleteAll();
    setDeletingAll(false);
  };

  return (
    <div className="tecos-page-shell" style={{ padding: 32 }}>
      <Card theme={theme}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14, flexWrap: 'wrap', gap: 10 }}>
          <h3 style={{ fontFamily: 'Bebas Neue, sans-serif', fontSize: 24, color: theme.text, letterSpacing: 1, margin: 0, fontWeight: 400 }}>
            TODAS LAS NOTIFICACIONES {unread > 0 ? `(${unread})` : ''}
          </h3>
          <div style={{ display: 'flex', gap: 8 }}>
            {unread > 0 && (
              <Btn theme={theme} kind="ghost" size="sm" onClick={handleMarkAllRead} disabled={markingAll || deletingAll}>
                {markingAll ? 'Marcando…' : 'Marcar todas como leídas'}
              </Btn>
            )}
            {items.length > 0 && (
              <Btn theme={theme} kind="ghost" size="sm" onClick={handleDeleteAll} disabled={deletingAll || markingAll}>
                {deletingAll ? 'Borrando…' : 'Borrar todas'}
              </Btn>
            )}
          </div>
        </div>
        {loading ? (
          <p style={{ color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>Cargando…</p>
        ) : items.length === 0 ? (
          <p style={{ color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>No tienes notificaciones.</p>
        ) : (
          <div style={{ display: 'grid', gap: 0 }}>
            <NotificationListBody
              theme={theme}
              loading={false}
              items={items}
              unreadList={unreadList}
              readList={readList}
              markRead={markRead}
              onActivate={audience === 'admin' ? handleActivate : undefined}
              onStudentNavigate={audience === 'student' ? handleActivate : undefined}
            />
          </div>
        )}
      </Card>
    </div>
  );
};

window.dispatchNotificationsChanged = () => {
  window.dispatchEvent(new Event('tecos:notifications-changed'));
};

Object.assign(window, {
  NotificationBell,
  NotificationsFullPage,
  useNotifications,
  sortNotificationItems,
  partitionNotifications,
  resolveAdminNotificationTarget,
  resolveStudentNotificationTarget,
  formatNotifTime,
});
