import { jsx as f, jsxs as O } from "react/jsx-runtime";
import { NotificationClient as G } from "@edusight/notification-sdk";
import U, { useState as v, useCallback as T, useEffect as N, Component as Q, createContext as X, useReducer as Y, useRef as Z, useContext as ee } from "react";
import { io as te } from "socket.io-client";
import { u as ne, c as R } from "./hooks-S0z2_-4B.js";
import { M as re, a as ie, C as K, B as F, S as ae, I as oe, L as se } from "./components-DUT08KJF.js";
import { N as Oe, P as xe } from "./components-DUT08KJF.js";
const ce = () => window.__notificationSDK?.client, le = ({
  onPreferencesLoaded: t,
  onError: n
}) => {
  const u = ce(), [w, s] = v(!0), [d, c] = v(null), [r, l] = v(null), y = T(async () => {
    try {
      if (s(!0), c(null), !u)
        throw new Error("Notification client not available");
      const h = window.__notificationSDK?.config;
      if (!h)
        throw new Error("SDK configuration not available");
      const { subscriberId: g, tenantId: I, environmentId: b } = h;
      if (!g || !I || !b)
        throw new Error("SubscriberId, TenantId or EnvironmentId not available in config");
      const S = await u.preferences.get(
        I,
        g,
        b
      );
      let a = null;
      try {
        a = await u.preferences.getSchedule(
          I,
          g,
          b
        );
      } catch {
      }
      const k = {
        channels: {
          email: S.emailEnabled ?? !0,
          push: S.pushEnabled ?? !0,
          sms: S.smsEnabled ?? !1,
          inApp: S.inAppEnabled ?? !0
        },
        subscriptions: [],
        deliverySchedule: {
          enabled: a?.isEnabled || !1,
          timezone: "UTC",
          quietHours: {
            start: S.quietHoursStart ?? "22:00",
            end: S.quietHoursEnd ?? "08:00"
          },
          weekdays: a?.weeklySchedule ? [
            !!a.weeklySchedule.monday,
            !!a.weeklySchedule.tuesday,
            !!a.weeklySchedule.wednesday,
            !!a.weeklySchedule.thursday,
            !!a.weeklySchedule.friday,
            !!a.weeklySchedule.saturday,
            !!a.weeklySchedule.sunday
          ] : [!0, !0, !0, !0, !0, !1, !1],
          weeklySchedule: a?.weeklySchedule || void 0
        }
      };
      S.categories && Object.entries(S.categories).forEach(([C, _]) => {
        k.subscriptions.push({
          workflowId: C,
          name: C,
          enabled: !0,
          channels: {
            email: _.emailEnabled ?? !0,
            push: _.pushEnabled ?? !0,
            sms: _.smsEnabled ?? !1,
            inApp: _.inAppEnabled ?? !0
          }
        });
      }), l(k), t(k);
    } catch (h) {
      const g = h instanceof Error ? h : new Error("Failed to load preferences");
      h?.response?.status === 404 || h?.status === 404 || (c(g), n?.(g));
      const b = {
        channels: {
          email: !0,
          push: !0,
          sms: !1,
          inApp: !0
        },
        subscriptions: [],
        deliverySchedule: {
          enabled: !1,
          timezone: "UTC",
          quietHours: {
            start: "22:00",
            end: "08:00"
          },
          weekdays: [!0, !0, !0, !0, !0, !1, !1]
        }
      };
      l(b), t(b);
    } finally {
      s(!1);
    }
  }, [u, t, n]);
  return N(() => {
    u && y();
  }, [u, y]), {
    isLoading: w,
    error: d,
    preferences: r
  };
}, de = () => window.__notificationSDK?.client, fe = () => {
  const t = de(), [n, u] = v([]), [w, s] = v(!1), [d, c] = v(!0), [r, l] = v(0), y = 5, h = T(async () => {
    if (!(!t || w || !d))
      try {
        s(!0);
        const I = window.__notificationSDK?.config;
        if (!I) return;
        const b = await t.preferences.listSpecific(
          I.tenantId,
          I.subscriberId,
          {
            includeWorkflows: !0,
            includeTemplates: !1,
            activeOnly: !0,
            limit: y,
            offset: r
          }
        ), S = (b.items || []).map((a) => ({
          workflowId: a.identifier,
          name: a.name,
          enabled: a.preference.enabled,
          channels: {
            email: a.preference.channels.email || !1,
            push: a.preference.channels.push || !1,
            inApp: a.preference.channels.in_app || !1,
            sms: a.preference.channels.sms || !1
          }
        }));
        u((a) => {
          const k = new Set(a.map((_) => _.workflowId)), C = S.filter((_) => !k.has(_.workflowId));
          return [...a, ...C];
        }), l((a) => a + y), (S.length < y || b.total !== void 0 && n.length + S.length >= b.total) && c(!1);
      } catch {
      } finally {
        s(!1);
      }
  }, [t, r, d, w, n.length]);
  return N(() => {
    t && r === 0 && n.length === 0 && h();
  }, [t, h, r, n.length]), {
    specificPreferences: n,
    isLoading: w,
    hasMore: d,
    loadMore: h,
    refetch: async () => {
      u([]), l(0), c(!0);
    }
  };
}, ue = ({ error: t, onRetry: n }) => /* @__PURE__ */ O(
  "div",
  {
    className: "p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg",
    role: "alert",
    "data-testid": "error-boundary-fallback",
    children: [
      /* @__PURE__ */ O("div", { className: "flex items-center mb-2", children: [
        /* @__PURE__ */ f(re, { className: "w-6 h-6 text-[var(--widget-error)] mr-2", "aria-hidden": "true" }),
        /* @__PURE__ */ f("h3", { className: "text-sm font-medium text-[var(--widget-error)]", children: "Something went wrong" })
      ] }),
      /* @__PURE__ */ f("p", { className: "text-sm mb-3 text-[var(--widget-error)]/80", children: "The notification widget encountered an error and couldn't load properly." }),
      process.env.NODE_ENV === "development" && t && /* @__PURE__ */ O("details", { className: "mb-3", children: [
        /* @__PURE__ */ f("summary", { className: "text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors", children: "Error details (development only)" }),
        /* @__PURE__ */ O("pre", { className: "mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]", children: [
          t.message,
          t.stack && `

${t.stack}`
        ] })
      ] }),
      /* @__PURE__ */ O(
        "button",
        {
          type: "button",
          className: "inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-[var(--widget-error)] bg-[var(--widget-error)]/10 hover:bg-[var(--widget-error)]/20 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--widget-error)] transition-colors",
          onClick: n,
          "data-testid": "error-retry-button",
          children: [
            /* @__PURE__ */ f(ie, { className: "mr-1 w-4 h-4", "aria-hidden": "true" }),
            "Try again"
          ]
        }
      )
    ]
  }
);
class pe extends Q {
  constructor(n) {
    super(n), this.handleRetry = () => {
      this.setState({
        hasError: !1,
        error: null,
        errorInfo: null
      });
    }, this.state = {
      hasError: !1,
      error: null,
      errorInfo: null
    };
  }
  static getDerivedStateFromError(n) {
    return {
      hasError: !0,
      error: n
    };
  }
  componentDidCatch(n, u) {
    this.setState({
      errorInfo: u
    }), this.props.onError && this.props.onError(n, u);
  }
  render() {
    return this.state.hasError ? /* @__PURE__ */ f(ue, { error: this.state.error, onRetry: this.handleRetry }) : this.props.children;
  }
}
const W = X(null), he = () => {
  const t = ee(W);
  if (!t)
    throw new Error("useSDK must be used within a NotificationWidget");
  return t;
}, me = {
  notifications: [],
  unreadCount: 0,
  preferences: {
    channels: {
      email: !0,
      push: !0,
      sms: !1,
      inApp: !0
    },
    subscriptions: [],
    deliverySchedule: {
      timezone: "UTC",
      quietHours: {
        start: "22:00",
        end: "08:00"
      },
      weekdays: [!0, !0, !0, !0, !0, !1, !1]
    }
  },
  ui: {
    isOpen: !1,
    currentView: "notifications",
    selectedNotifications: [],
    isLoading: !1,
    error: null
  },
  websocket: {
    connected: !1,
    reconnecting: !1
  }
}, we = ({
  config: t,
  children: n
}) => {
  const [u, w] = U.useState({
    client: null,
    isInitialized: !1,
    error: null
  });
  return N(() => {
    let s = !0;
    return (async () => {
      try {
        const c = window.__notificationSDK;
        if (c?.client && JSON.stringify(c.config) === JSON.stringify(t)) {
          s && w({
            client: c.client,
            isInitialized: !0,
            error: null
          });
          return;
        }
        const r = new G({
          apiUrl: t.baseUrl,
          apiKey: t.apiKey,
          tenantId: t.tenantId,
          environmentId: t.environmentId
        });
        window.__notificationSDK = { client: r, config: t }, s && w({
          client: r,
          isInitialized: !0,
          error: null
        });
      } catch (c) {
        s && w({
          client: null,
          isInitialized: !1,
          error: c
        });
      }
    })(), () => {
      s = !1;
    };
  }, [t]), /* @__PURE__ */ f(W.Provider, { value: u, children: n });
}, ye = (t, n) => {
  switch (n.type) {
    case "SET_NOTIFICATIONS":
      return {
        ...t,
        notifications: n.payload,
        unreadCount: n.payload.filter((d) => !d.isRead).length
      };
    case "ADD_NOTIFICATION":
      const u = [n.payload, ...t.notifications];
      return {
        ...t,
        notifications: u,
        unreadCount: u.filter((d) => !d.isRead).length
      };
    case "UPDATE_NOTIFICATION":
      const w = t.notifications.map(
        (d) => d.id === n.payload.id ? { ...d, ...n.payload.updates } : d
      );
      return {
        ...t,
        notifications: w,
        unreadCount: w.filter((d) => !d.isRead).length
      };
    case "DELETE_NOTIFICATION":
      const s = t.notifications.filter((d) => d.id !== n.payload);
      return {
        ...t,
        notifications: s,
        unreadCount: s.filter((d) => !d.isRead).length
      };
    case "SET_PREFERENCES":
      return {
        ...t,
        preferences: n.payload
      };
    case "SET_UI_STATE":
      return {
        ...t,
        ui: { ...t.ui, ...n.payload }
      };
    case "SET_WEBSOCKET_STATE":
      return {
        ...t,
        websocket: { ...t.websocket, ...n.payload }
      };
    default:
      return t;
  }
}, Se = ({
  position: t = "right",
  size: n = "medium",
  theme: u = "light",
  className: w = "",
  onError: s,
  onMorePreferencesClick: d
}) => {
  const [c, r] = Y(ye, me), { client: l, isInitialized: y, error: h } = he(), g = Z(null), I = T((e) => {
    r({
      type: "SET_PREFERENCES",
      payload: e
    });
  }, []), b = T(
    (e) => {
      s && s(e);
    },
    [s]
  ), { error: S } = le({
    onPreferencesLoaded: I,
    onError: b
  }), {
    specificPreferences: a,
    isLoading: k,
    hasMore: C,
    loadMore: _
  } = fe(), {
    updatePreference: M,
    isSaving: P,
    error: L
  } = ne({
    preferences: c.preferences,
    onPreferencesChange: I,
    onError: b
  });
  N(() => {
    if (a.length > 0) {
      const i = [...c.preferences.subscriptions];
      let o = !1;
      a.forEach((E) => {
        const m = i.findIndex((p) => p.workflowId === E.workflowId);
        if (m === -1)
          i.push(E), o = !0;
        else {
          const p = i[m], A = {
            ...p,
            name: E.name || p.name,
            enabled: E.enabled,
            channels: E.channels
          };
          (p.name !== A.name || p.enabled !== A.enabled || JSON.stringify(p.channels) !== JSON.stringify(A.channels)) && (i[m] = A, o = !0);
        }
      }), o && r({
        type: "SET_PREFERENCES",
        payload: {
          ...c.preferences,
          subscriptions: i
        }
      });
    }
  }, [a]);
  const B = U.useMemo(() => a.map((e) => c.preferences.subscriptions.find((o) => o.workflowId === e.workflowId) || e), [a, c.preferences.subscriptions]), D = T((e) => {
    try {
      const i = R();
      switch (e.type) {
        case "notification_received": {
          const o = e.data;
          if (!i.validateWebSocketPayload(o))
            break;
          const E = i.toWidgetNotificationFromWebSocket(o);
          r({
            type: "ADD_NOTIFICATION",
            payload: E
          });
          break;
        }
        case "notification_updated":
          r({
            type: "UPDATE_NOTIFICATION",
            payload: {
              id: e.data.id || e.data.notificationId,
              updates: e.data
            }
          });
          break;
        case "notification_deleted":
          r({
            type: "DELETE_NOTIFICATION",
            payload: e.data.id || e.data.notificationId
          });
          break;
        case "preferences_updated":
          r({
            type: "SET_PREFERENCES",
            payload: e.data
          });
          break;
        default:
      }
    } catch {
    }
  }, []), V = T(async () => {
    if (!(!l || !y || g.current))
      try {
        r({
          type: "SET_WEBSOCKET_STATE",
          payload: { reconnecting: !0 }
        });
        const e = window.__notificationSDK?.config;
        if (!e)
          throw new Error("SDK configuration not available for WebSocket connection");
        const E = `${l.getApiHost()}/v1/notifications`, m = te(E, {
          query: {
            tenantId: e.tenantId,
            subscriberId: e.subscriberId,
            environmentId: e.environmentId
          },
          transports: ["websocket", "polling"],
          autoConnect: !1,
          reconnection: !0,
          reconnectionAttempts: 10,
          reconnectionDelay: 1e3,
          reconnectionDelayMax: 5e3
        });
        g.current = m;
        let p = null;
        const A = () => {
          p && clearInterval(p), p = setInterval(() => {
            m.connected && m.emit("ping", { timestamp: (/* @__PURE__ */ new Date()).toISOString() });
          }, 12e4);
        }, j = () => {
          p && (clearInterval(p), p = null);
        };
        m.on("notification", (x) => {
          D({
            type: "notification_received",
            data: x
          });
        }), m.on("connect", () => {
          r({
            type: "SET_WEBSOCKET_STATE",
            payload: { connected: !0, reconnecting: !1 }
          }), A();
        }), m.on("disconnect", (x) => {
          r({
            type: "SET_WEBSOCKET_STATE",
            payload: { connected: !1, reconnecting: !1 }
          }), j();
        }), m.on("reconnect_attempt", (x) => {
          r({
            type: "SET_WEBSOCKET_STATE",
            payload: { connected: !1, reconnecting: !0 }
          });
        }), m.on("connect_error", (x) => {
          r({
            type: "SET_WEBSOCKET_STATE",
            payload: { connected: !1, reconnecting: !1 }
          }), s && s(x);
        }), m.connect();
      } catch (e) {
        r({
          type: "SET_WEBSOCKET_STATE",
          payload: { connected: !1, reconnecting: !1 }
        }), s && s(e);
      }
  }, [l, y, D, s]), H = T(() => {
    if (g.current)
      try {
        g.current.disconnect && g.current.disconnect(), g.current = null, r({
          type: "SET_WEBSOCKET_STATE",
          payload: { connected: !1, reconnecting: !1 }
        });
      } catch {
      }
  }, []), q = T(() => {
    r({
      type: "SET_UI_STATE",
      payload: { isOpen: !c.ui.isOpen }
    });
  }, [c.ui.isOpen]), z = T(() => {
    r({
      type: "SET_UI_STATE",
      payload: { isOpen: !1 }
    });
  }, []), $ = T((e) => {
    r({
      type: "SET_UI_STATE",
      payload: { currentView: e }
    });
  }, []), J = T(
    async (e, i) => {
      if (!l || !y)
        return;
      const o = window.__notificationSDK?.config;
      if (o) {
        if (!e)
          throw new Error("notificationId is required");
        try {
          switch (i.type) {
            case "mark_read":
              await l.inbox.markAsRead(
                e,
                o.tenantId,
                o.environmentId,
                o.subscriberId
              );
              break;
            case "mark_unread":
              await l.inbox.markAsUnread(
                e,
                o.tenantId,
                o.environmentId,
                o.subscriberId
              );
              break;
            case "archive":
              await l.inbox.archive(
                e,
                o.tenantId,
                o.environmentId,
                o.subscriberId
              );
              break;
            case "delete":
              await l.inbox.delete(
                e,
                o.tenantId,
                o.environmentId,
                o.subscriberId
              );
              break;
            default:
              i.handler && await i.handler(e);
              break;
          }
          switch (i.type) {
            case "mark_read":
              r({
                type: "UPDATE_NOTIFICATION",
                payload: { id: e, updates: { isRead: !0 } }
              });
              break;
            case "mark_unread":
              r({
                type: "UPDATE_NOTIFICATION",
                payload: { id: e, updates: { isRead: !1 } }
              });
              break;
            case "archive":
              r({
                type: "UPDATE_NOTIFICATION",
                payload: { id: e, updates: { isArchived: !0 } }
              });
              break;
            case "delete":
              r({
                type: "DELETE_NOTIFICATION",
                payload: e
              });
              break;
          }
        } catch (E) {
          s && s(E);
        }
      }
    },
    [l]
  );
  return N(() => {
    if (!l || !y) return;
    (async () => {
      try {
        r({
          type: "SET_UI_STATE",
          payload: { isLoading: !0 }
        });
        const i = window.__notificationSDK?.config;
        if (!i)
          throw new Error("SDK configuration not available");
        const o = R(), m = ((await l.inbox.getRenderedNotifications(
          {
            channel: "in_app",
            limit: 50,
            offset: 0
          },
          i.tenantId,
          i.environmentId,
          i.subscriberId
        ))?.items || []).map(
          (p) => o.toWidgetNotification(p)
        );
        r({
          type: "SET_NOTIFICATIONS",
          payload: m
        }), r({
          type: "SET_UI_STATE",
          payload: { isLoading: !1, error: null }
        });
      } catch (i) {
        r({
          type: "SET_UI_STATE",
          payload: {
            isLoading: !1,
            error: i
          }
        }), s && s(i);
      }
    })();
  }, [l, y, s]), N(() => (l && y && V(), () => {
    H();
  }), [l]), N(() => {
    if (!l || !y || c.websocket.connected) return;
    const e = setInterval(async () => {
      try {
        const i = window.__notificationSDK?.config;
        if (!i)
          return;
        const o = R(), m = ((await l.inbox.getRenderedNotifications(
          {
            channel: "in_app",
            limit: 50,
            offset: 0
          },
          i.tenantId,
          i.environmentId,
          i.subscriberId
        ))?.items || []).map(
          (p) => o.toWidgetNotification(p)
        );
        r({
          type: "SET_NOTIFICATIONS",
          payload: m
        });
      } catch {
      }
    }, 3e4);
    return () => clearInterval(e);
  }, [l, c.websocket.connected]), N(() => {
    const e = (i) => {
      if (i.key === "notification_widget_sync" && i.newValue)
        try {
          const o = JSON.parse(i.newValue);
          D(o);
        } catch {
        }
    };
    return window.addEventListener("storage", e), () => window.removeEventListener("storage", e);
  }, [D]), N(() => {
    r({
      type: "SET_UI_STATE",
      payload: { isLoading: P }
    });
  }, [P]), N(() => {
    const e = h || L || S;
    e && r({
      type: "SET_UI_STATE",
      payload: { error: e }
    });
  }, [h, L, S]), !y && !h ? /* @__PURE__ */ f(
    "div",
    {
      className: `mx-widget-root relative inline-block ${w}`,
      "data-mx-widget": "root",
      "data-widget-size": n || "small",
      "data-theme": u,
      "data-testid": "notification-widget",
      children: /* @__PURE__ */ f(K, { componentName: "BellComponent", children: /* @__PURE__ */ f(F, { unreadCount: 0, onClick: () => {
      }, size: n, disabled: !0 }) })
    }
  ) : h ? /* @__PURE__ */ f(
    "div",
    {
      className: `mx-widget-root relative inline-block ${w}`,
      "data-mx-widget": "root",
      "data-widget-size": n || "small",
      "data-theme": u,
      "data-testid": "notification-widget",
      children: /* @__PURE__ */ f(
        K,
        {
          componentName: "BellComponent",
          fallback: /* @__PURE__ */ f(
            ae,
            {
              error: h.message,
              onRetry: () => window.location.reload()
            }
          ),
          children: /* @__PURE__ */ f(F, { unreadCount: 0, onClick: () => {
          }, size: n, disabled: !0 })
        }
      )
    }
  ) : /* @__PURE__ */ O(
    "div",
    {
      className: `mx-widget-root  min-w-[20rem] relative inline-block ${w}`,
      "data-mx-widget": "root",
      "data-widget-size": n || "small",
      "data-theme": u,
      "data-testid": "notification-widget",
      children: [
        /* @__PURE__ */ f(K, { componentName: "BellComponent", children: /* @__PURE__ */ f(
          F,
          {
            unreadCount: c.unreadCount,
            onClick: q,
            size: n,
            disabled: c.ui.isLoading
          }
        ) }),
        /* @__PURE__ */ f(
          K,
          {
            componentName: "InboxPopover",
            fallback: /* @__PURE__ */ f(se, { message: "Unable to load notifications" }),
            children: /* @__PURE__ */ f(
              oe,
              {
                isOpen: c.ui.isOpen,
                onClose: z,
                position: t,
                currentView: c.ui.currentView,
                onViewChange: $,
                notifications: c.notifications,
                onNotificationAction: J,
                preferences: c.preferences,
                onPreferenceChange: M,
                isPreferencesLoading: P,
                specificPreferences: B,
                onLoadMoreSpecific: _,
                hasMoreSpecific: C,
                isListLoading: k,
                onMorePreferencesClick: d
              }
            )
          }
        )
      ]
    }
  );
}, Ne = ({ sdkConfig: t, ...n }) => /* @__PURE__ */ f(pe, { onError: n.onError, children: /* @__PURE__ */ f(we, { config: t, children: /* @__PURE__ */ f(Se, { ...n }) }) }), ke = "3.0.0", Ce = "@edusight/notification-widget";
export {
  F as BellComponent,
  oe as InboxPopover,
  Oe as NotificationItem,
  Ne as NotificationWidget,
  pe as NotificationWidgetErrorBoundary,
  xe as PreferencesView,
  ke as VERSION,
  Ce as WIDGET_NAME
};
//# sourceMappingURL=index.esm.js.map
