// App shell — top bar with user menu + role switcher for demo + sub-nav per role + theme toggle + notifications pop-up & toasts

// ── Global Toast Notification Manager ─────────────────────────────────────────
let _toastListeners = [];
let _toastId = 0;

window.showToast = (opt) => {
  const item = typeof opt === "string" ? { message: opt, type: "info" } : opt;
  const id = ++_toastId;
  const toast = {
    id,
    title: item.title || (item.type === "error" ? "Error" : item.type === "success" ? "Success" : "Notification"),
    message: item.message || "",
    type: item.type || "info", // "success" | "error" | "info" | "warning"
    duration: item.duration || 4500,
    created: Date.now(),
  };
  _toastListeners.forEach((fn) => fn({ action: "add", toast }));
  setTimeout(() => {
    _toastListeners.forEach((fn) => fn({ action: "remove", id }));
  }, toast.duration);
  return id;
};
window.notify = window.showToast;

const ToastContainer = () => {
  const [toasts, setToasts] = React.useState([]);

  React.useEffect(() => {
    const listener = (event) => {
      if (event.action === "add") {
        setToasts((prev) => [event.toast, ...prev].slice(0, 5));
      } else if (event.action === "remove") {
        setToasts((prev) => prev.filter((t) => t.id !== event.id));
      }
    };
    _toastListeners.push(listener);
    return () => {
      _toastListeners = _toastListeners.filter((fn) => fn !== listener);
    };
  }, []);

  if (!toasts.length) return null;

  const typeConfig = {
    success: { bg: "var(--moss)", icon: "✓", border: "rgba(0,0,0,0.15)", text: "#fff" },
    error:   { bg: "var(--coral)", icon: "✕", border: "rgba(0,0,0,0.15)", text: "#fff" },
    warning: { bg: "var(--gold)", icon: "⚠️", border: "rgba(0,0,0,0.15)", text: "#000" },
    info:    { bg: "var(--sky)", icon: "ℹ", border: "rgba(0,0,0,0.15)", text: "#fff" },
  };

  return (
    <div style={{
      position: "fixed", top: 20, right: 24, zIndex: 99999,
      display: "flex", flexDirection: "column", gap: 10, maxWidth: 380, width: "calc(100vw - 48px)",
      pointerEvents: "none",
    }}>
      {toasts.map((t) => {
        const conf = typeConfig[t.type] || typeConfig.info;
        return (
          <div
            key={t.id}
            style={{
              pointerEvents: "auto",
              background: "var(--paper-card)",
              border: `1.5px solid ${conf.bg}`,
              borderRadius: 14,
              boxShadow: "0 14px 34px rgba(0,0,0,0.22), 0 4px 10px rgba(0,0,0,0.1)",
              overflow: "hidden",
              animation: "toastSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1)",
              display: "flex",
              flexDirection: "column",
            }}>
            <div style={{ display: "flex", alignItems: "flex-start", gap: 12, padding: "12px 14px" }}>
              <div style={{
                width: 28, height: 28, borderRadius: "50%", background: conf.bg,
                color: conf.text, display: "flex", alignItems: "center", justifyContent: "center",
                fontWeight: 800, fontSize: 13, flexShrink: 0, marginTop: 1,
              }}>
                {conf.icon}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13, color: "var(--ink)", lineHeight: 1.3 }}>
                  {t.title}
                </div>
                <div style={{ fontSize: 12, color: "var(--ink-soft)", marginTop: 2, lineHeight: 1.4 }}>
                  {t.message}
                </div>
              </div>
              <button
                onClick={() => setToasts((prev) => prev.filter((x) => x.id !== t.id))}
                style={{
                  background: "none", border: "none", color: "var(--ink-mute)",
                  fontSize: 16, cursor: "pointer", padding: "0 2px", lineHeight: 1,
                }}>
                ×
              </button>
            </div>
            {/* Progress line */}
            <div style={{
              height: 3, background: conf.bg,
              animation: `toastProgress ${t.duration}ms linear forwards`,
              transformOrigin: "left",
            }}/>
          </div>
        );
      })}
      <style>{`
        @keyframes toastSlideIn {
          from { opacity: 0; transform: translateY(-16px) scale(0.96); }
          to { opacity: 1; transform: translateY(0) scale(1); }
        }
        @keyframes toastProgress {
          from { transform: scaleX(1); }
          to { transform: scaleX(0); }
        }
      `}</style>
    </div>
  );
};

// ── Notification Dropdown Flyout ──────────────────────────────────────────────
const NotificationBell = ({ session }) => {
  const [open, setOpen] = React.useState(false);
  const [notifications, setNotifications] = React.useState([]);
  const [unreadCount, setUnreadCount] = React.useState(0);
  const dropdownRef = React.useRef(null);
  const lastSeenId = React.useRef(null);

  const fetchNotifications = React.useCallback(async (isPoll = false) => {
    try {
      const res = await apiFetch("/notifications");
      if (res.ok) {
        const list = await res.json();
        if (Array.isArray(list)) {
          setNotifications(list);
          const unread = list.filter((n) => n.unread).length;
          setUnreadCount(unread);

          // If a new item arrived via polling, trigger a toast popup
          if (isPoll && list.length && lastSeenId.current && list[0].id !== lastSeenId.current) {
            const newest = list[0];
            window.showToast({
              title: newest.title || "New Notification",
              message: newest.message || "",
              type: newest.type || "info",
            });
          }
          if (list.length) {
            lastSeenId.current = list[0].id;
          }
        }
      }
    } catch {}
  }, []);

  React.useEffect(() => {
    fetchNotifications(false);
    const interval = setInterval(() => fetchNotifications(true), 15000);
    return () => clearInterval(interval);
  }, [fetchNotifications]);

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

  return (
    <div style={{ position: "relative" }} ref={dropdownRef}>
      <button
        onClick={() => {
          setOpen(!open);
          if (!open) fetchNotifications(false);
        }}
        className="btn btn-ghost"
        style={{
          padding: "6px 10px", fontSize: 13, display: "inline-flex",
          alignItems: "center", position: "relative",
        }}
        title="Notifications">
        <span style={{ fontSize: 16 }}>🔔</span>
        {unreadCount > 0 && (
          <span style={{
            position: "absolute", top: 2, right: 2, background: "var(--coral)",
            color: "white", borderRadius: "50%", width: 16, height: 16,
            fontSize: 9, fontWeight: 800, display: "flex", alignItems: "center",
            justifyContent: "center", boxShadow: "0 0 0 2px var(--paper-card)",
          }}>
            {unreadCount > 9 ? "9+" : unreadCount}
          </span>
        )}
      </button>

      {open && (
        <div style={{
          position: "absolute", right: 0, top: "calc(100% + 8px)", width: 340,
          background: "var(--paper-card)", border: "var(--border-thin)",
          borderRadius: 16, boxShadow: "0 18px 45px rgba(0,0,0,0.25)",
          zIndex: 9999, overflow: "hidden", display: "flex", flexDirection: "column",
          maxHeight: 460,
        }}>
          <div style={{
            padding: "12px 16px", borderBottom: "var(--border-thin)",
            display: "flex", alignItems: "center", justifyContent: "space-between",
            background: "var(--paper-deep)",
          }}>
            <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <span style={{ fontWeight: 700, fontSize: 14 }}>Notifications</span>
              {unreadCount > 0 && (
                <span style={{
                  fontSize: 10, background: "var(--coral)", color: "white",
                  padding: "1px 6px", borderRadius: 999, fontWeight: 700,
                }}>
                  {unreadCount} new
                </span>
              )}
            </div>
          </div>

          <div style={{ flex: 1, overflowY: "auto", padding: "6px 0" }}>
            {notifications.length === 0 ? (
              <div style={{ padding: "30px 16px", textAlign: "center", color: "var(--ink-mute)", fontSize: 13 }}>
                <div style={{ fontSize: 24, marginBottom: 6 }}>✨</div>
                <div>No new notifications</div>
              </div>
            ) : (
              notifications.map((n) => {
                const iconColor = n.type === "success" ? "var(--moss)" : n.type === "error" ? "var(--coral)" : "var(--sky)";
                return (
                  <div
                    key={n.id}
                    style={{
                      padding: "10px 16px",
                      borderBottom: "var(--border-thin)",
                      background: n.unread ? "var(--paper-deep)" : "transparent",
                      display: "flex",
                      gap: 10,
                      alignItems: "flex-start",
                      cursor: "default",
                      transition: "background 0.15s ease",
                    }}>
                    <div style={{
                      width: 8, height: 8, borderRadius: "50%",
                      background: n.unread ? "var(--coral)" : "transparent",
                      marginTop: 6, flexShrink: 0,
                    }}/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 2 }}>
                        <div style={{ fontWeight: 700, fontSize: 12, color: iconColor }}>
                          {n.title}
                        </div>
                        {n.time && (
                          <div style={{ fontSize: 10, color: "var(--ink-mute)" }}>
                            {typeof n.time === "string" && n.time.includes("T")
                              ? new Date(n.time).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
                              : n.time}
                          </div>
                        )}
                      </div>
                      <div style={{ fontSize: 12, color: "var(--ink-soft)", lineHeight: 1.35 }}>
                        {n.message}
                      </div>
                    </div>
                  </div>
                );
              })
            )}
          </div>
        </div>
      )}
    </div>
  );
};

// ── App Navigation Bar ────────────────────────────────────────────────────────
const AppNav = ({ session, route, go, logout, theme = "light", toggleTheme }) => {
  const role = session?.role || "parent";

  const sub = {
    student: [["/app/student","Home"],["/app/student/courses","Courses"],["/app/student/progress","Progress"],["/app/student/quiz","Quiz"],["/app/student/homework","Homework"],["/app/student/forum","Forum"]],
    parent: [["/app/parent","Home"],["/app/parent/schedule","Schedule"],["/app/parent/shop","Shop"]],
  }[role] || [];

  const accent = {
    student: "var(--coral)", parent: "var(--moss)",
    teacher: "var(--sky)", admin: "var(--plum)",
    content_manager: "var(--ink)", superadmin: "var(--ink)",
  }[role] || "var(--ink)";

  return (
    <>
      <ToastContainer />
      <div className="codeland" style={{
        display: "flex", alignItems: "center", gap: 12,
        padding: "10px 22px", background: "var(--paper-card)",
        borderBottom: "var(--border-thin)", flexWrap: "wrap",
      }}>
        <a href="https://epiqminds.com" className="display" style={{
          fontSize: 18, letterSpacing: "-0.03em", textDecoration: "none", color: "var(--ink)",
        }}>
          <span style={{ color: "var(--coral)" }}>Epiq</span>Minds
        </a>
        <span className="chip" style={{ background: accent, color: "white", padding: "3px 10px", fontSize: 10 }}>
          {role.replace(/_/g, " ").toUpperCase()}
        </span>

        <div style={{ flex: 1 }}/>

        {sub.length > 1 && (
          <div style={{
            display: "inline-flex", padding: 3, background: "var(--paper-deep)",
            borderRadius: 999, border: "var(--border-thin)", overflowX: "auto", maxWidth: 500, flexShrink: 1,
          }}>
            {sub.map(([path, label]) => (
              <button key={path} onClick={() => go(path)} style={{
                padding: "5px 10px", borderRadius: 999, border: "none", whiteSpace: "nowrap",
                background: route === path ? "var(--ink)" : "transparent",
                color: route === path ? "var(--paper-card)" : "var(--ink-soft)",
                fontWeight: 700, fontSize: 11, fontFamily: "var(--font-ui)", cursor: "pointer",
              }}>{label}</button>
            ))}
          </div>
        )}

        <div style={{ flex: 1 }}/>

        {/* Notifications Pop-up Bell */}
        <NotificationBell session={session} />

        {/* Theme toggle: Bright mode / Dark mode */}
        <button
          onClick={toggleTheme}
          className="btn btn-ghost"
          style={{ padding: "6px 12px", fontSize: 12, display: "inline-flex", alignItems: "center", gap: 6 }}
          title="Toggle Bright / Dark mode">
          {theme === "dark" ? "☀️ Bright" : "🌙 Dark"}
        </button>

        <button onClick={logout} className="btn btn-ghost" style={{ padding: "6px 12px", fontSize: 12 }}>
          Sign out
        </button>
      </div>
    </>
  );
};

window.AppNav = AppNav;
window.ToastContainer = ToastContainer;
window.NotificationBell = NotificationBell;
