"use client";
import { jsx } from "react/jsx-runtime";
import * as React from "react";
import {
  createAiServerConversation,
  listAiServerConversations,
  updateAiServerConversation
} from "./conversation-store.js";
const STORAGE_KEY = "om-ai-chat-sessions-v1";
const HISTORY_LIMIT = 50;
const AiChatSessionsContext = React.createContext(null);
function makeId() {
  const g = globalThis;
  if (g.crypto && typeof g.crypto.randomUUID === "function") {
    try {
      return g.crypto.randomUUID();
    } catch {
    }
  }
  const rand = () => Math.random().toString(16).slice(2, 10);
  return `${Date.now().toString(16)}-${rand()}-${rand()}`;
}
function readPersisted() {
  if (typeof window === "undefined") return { sessions: [], activeByAgent: {} };
  try {
    const raw = window.localStorage.getItem(STORAGE_KEY);
    if (!raw) return { sessions: [], activeByAgent: {} };
    const parsed = JSON.parse(raw);
    const sessions = Array.isArray(parsed?.sessions) ? parsed.sessions.filter((entry) => {
      if (!entry || typeof entry !== "object") return false;
      const value = entry;
      return typeof value.id === "string" && typeof value.agentId === "string" && typeof value.conversationId === "string" && typeof value.createdAt === "number" && typeof value.lastUsedAt === "number" && (value.status === "open" || value.status === "closed");
    }).map((entry) => {
      const value = entry;
      const candidate = value.name;
      return {
        ...entry,
        name: typeof candidate === "string" ? candidate : void 0
      };
    }) : [];
    const activeByAgent = parsed?.activeByAgent && typeof parsed.activeByAgent === "object" ? Object.fromEntries(
      Object.entries(parsed.activeByAgent).filter(
        (entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
      )
    ) : {};
    return { sessions, activeByAgent };
  } catch {
    return { sessions: [], activeByAgent: {} };
  }
}
function writePersisted(state) {
  if (typeof window === "undefined") return;
  try {
    window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
  } catch {
  }
}
function serverConversationToSession(conversation, existing) {
  const createdAt = Date.parse(conversation.createdAt);
  const updatedAt = Date.parse(conversation.lastMessageAt ?? conversation.updatedAt);
  return {
    id: existing?.id ?? conversation.conversationId,
    agentId: conversation.agentId,
    conversationId: conversation.conversationId,
    name: conversation.title ?? existing?.name,
    createdAt: Number.isFinite(createdAt) ? createdAt : existing?.createdAt ?? Date.now(),
    lastUsedAt: Number.isFinite(updatedAt) ? updatedAt : existing?.lastUsedAt ?? Date.now(),
    status: conversation.status
  };
}
function mergeServerConversations(prev, conversations) {
  const byConversationId = new Map(prev.sessions.map((session) => [session.conversationId, session]));
  const serverSessions = conversations.map(
    (conversation) => serverConversationToSession(conversation, byConversationId.get(conversation.conversationId))
  );
  const serverIds = new Set(serverSessions.map((session) => session.conversationId));
  const localOnly = prev.sessions.filter((session) => !serverIds.has(session.conversationId));
  const sessions = [...serverSessions, ...localOnly];
  const activeByAgent = { ...prev.activeByAgent };
  const agentIds = new Set(sessions.map((session) => session.agentId));
  for (const agentId of agentIds) {
    const activeId = activeByAgent[agentId];
    const active = sessions.find((session) => session.id === activeId);
    if (active && active.status === "open") continue;
    const nextOpen = sessions.filter((session) => session.agentId === agentId && session.status === "open").sort((a, b) => b.lastUsedAt - a.lastUsedAt)[0];
    if (nextOpen) activeByAgent[agentId] = nextOpen.id;
    else delete activeByAgent[agentId];
  }
  return { sessions, activeByAgent };
}
function AiChatSessionsProvider({ children }) {
  const [state, setState] = React.useState(() => readPersisted());
  React.useEffect(() => {
    writePersisted(state);
  }, [state]);
  React.useEffect(() => {
    let cancelled = false;
    void listAiServerConversations({ limit: 100 }).then((conversations) => {
      if (cancelled || !conversations) return;
      setState((prev) => mergeServerConversations(prev, conversations));
    });
    return () => {
      cancelled = true;
    };
  }, []);
  const update = React.useCallback(
    (mutator) => {
      setState((prev) => mutator(prev));
    },
    []
  );
  const getOpenSessions = React.useCallback(
    (agentId) => state.sessions.filter((s) => s.agentId === agentId && s.status === "open").sort((a, b) => a.createdAt - b.createdAt),
    [state.sessions]
  );
  const getClosedSessions = React.useCallback(
    (agentId, limit = HISTORY_LIMIT) => state.sessions.filter((s) => s.agentId === agentId && s.status === "closed").sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit),
    [state.sessions]
  );
  const getActiveSession = React.useCallback(
    (agentId) => {
      const id = state.activeByAgent[agentId];
      if (!id) return null;
      const session = state.sessions.find((s) => s.id === id);
      if (!session || session.status !== "open") return null;
      return session;
    },
    [state.activeByAgent, state.sessions]
  );
  const createSession = React.useCallback((agentId) => {
    const session = {
      id: makeId(),
      agentId,
      conversationId: makeId(),
      createdAt: Date.now(),
      lastUsedAt: Date.now(),
      status: "open"
    };
    void createAiServerConversation({
      agentId: session.agentId,
      conversationId: session.conversationId
    });
    update((prev) => ({
      sessions: [...prev.sessions, session],
      activeByAgent: { ...prev.activeByAgent, [agentId]: session.id }
    }));
    return session;
  }, [update]);
  const closeSession = React.useCallback(
    (sessionId) => {
      const serverTarget = state.sessions.find((s) => s.id === sessionId);
      if (serverTarget) {
        void updateAiServerConversation(serverTarget.conversationId, { status: "closed" });
      }
      update((prev) => {
        const target = prev.sessions.find((s) => s.id === sessionId);
        if (!target) return prev;
        const sessions = prev.sessions.map(
          (s) => s.id === sessionId ? { ...s, status: "closed", lastUsedAt: Date.now() } : s
        );
        const activeByAgent = { ...prev.activeByAgent };
        if (activeByAgent[target.agentId] === sessionId) {
          const fallback = sessions.filter((s) => s.agentId === target.agentId && s.status === "open").sort((a, b) => b.lastUsedAt - a.lastUsedAt)[0];
          if (fallback) {
            activeByAgent[target.agentId] = fallback.id;
          } else {
            delete activeByAgent[target.agentId];
          }
        }
        return { sessions, activeByAgent };
      });
    },
    [state.sessions, update]
  );
  const reopenSession = React.useCallback(
    (sessionId) => {
      const serverTarget = state.sessions.find((s) => s.id === sessionId);
      if (serverTarget) {
        void updateAiServerConversation(serverTarget.conversationId, { status: "open" });
      }
      update((prev) => {
        const target = prev.sessions.find((s) => s.id === sessionId);
        if (!target) return prev;
        const sessions = prev.sessions.map(
          (s) => s.id === sessionId ? { ...s, status: "open", lastUsedAt: Date.now() } : s
        );
        return {
          sessions,
          activeByAgent: { ...prev.activeByAgent, [target.agentId]: sessionId }
        };
      });
    },
    [state.sessions, update]
  );
  const setActiveSession = React.useCallback(
    (sessionId) => {
      update((prev) => {
        const target = prev.sessions.find((s) => s.id === sessionId);
        if (!target || target.status !== "open") return prev;
        const sessions = prev.sessions.map(
          (s) => s.id === sessionId ? { ...s, lastUsedAt: Date.now() } : s
        );
        return {
          sessions,
          activeByAgent: { ...prev.activeByAgent, [target.agentId]: sessionId }
        };
      });
    },
    [update]
  );
  const renameSession = React.useCallback(
    (sessionId, name) => {
      const trimmed = name.trim();
      const serverTarget = state.sessions.find((s) => s.id === sessionId);
      if (serverTarget) {
        void updateAiServerConversation(serverTarget.conversationId, {
          title: trimmed.length > 0 ? trimmed : null
        });
      }
      update((prev) => ({
        ...prev,
        sessions: prev.sessions.map(
          (s) => s.id === sessionId ? { ...s, name: trimmed.length > 0 ? trimmed : void 0 } : s
        )
      }));
    },
    [state.sessions, update]
  );
  const touchSession = React.useCallback(
    (sessionId) => {
      update((prev) => ({
        ...prev,
        sessions: prev.sessions.map(
          (s) => s.id === sessionId ? { ...s, lastUsedAt: Date.now() } : s
        )
      }));
    },
    [update]
  );
  const ensureSession = React.useCallback(
    (agentId) => {
      let resolved = null;
      let mintedSession = null;
      setState((prev) => {
        const activeId = prev.activeByAgent[agentId];
        if (activeId) {
          const active = prev.sessions.find((s) => s.id === activeId);
          if (active && active.status === "open") {
            resolved = active;
            return prev;
          }
        }
        const anyOpen = prev.sessions.filter((s) => s.agentId === agentId && s.status === "open").sort((a, b) => b.lastUsedAt - a.lastUsedAt)[0];
        if (anyOpen) {
          resolved = anyOpen;
          return {
            ...prev,
            activeByAgent: { ...prev.activeByAgent, [agentId]: anyOpen.id }
          };
        }
        if (!mintedSession) {
          mintedSession = {
            id: makeId(),
            agentId,
            conversationId: makeId(),
            createdAt: Date.now(),
            lastUsedAt: Date.now(),
            status: "open"
          };
          void createAiServerConversation({
            agentId: mintedSession.agentId,
            conversationId: mintedSession.conversationId
          });
        }
        resolved = mintedSession;
        return {
          sessions: [...prev.sessions, mintedSession],
          activeByAgent: { ...prev.activeByAgent, [agentId]: mintedSession.id }
        };
      });
      return resolved;
    },
    []
  );
  const api = React.useMemo(
    () => ({
      state,
      getOpenSessions,
      getClosedSessions,
      getActiveSession,
      createSession,
      closeSession,
      reopenSession,
      setActiveSession,
      renameSession,
      touchSession,
      ensureSession
    }),
    [
      state,
      getOpenSessions,
      getClosedSessions,
      getActiveSession,
      createSession,
      closeSession,
      reopenSession,
      setActiveSession,
      renameSession,
      touchSession,
      ensureSession
    ]
  );
  return /* @__PURE__ */ jsx(AiChatSessionsContext.Provider, { value: api, children });
}
function useAiChatSessions() {
  const ctx = React.useContext(AiChatSessionsContext);
  if (ctx) return ctx;
  return {
    state: { sessions: [], activeByAgent: {} },
    getOpenSessions: () => [],
    getClosedSessions: () => [],
    getActiveSession: () => null,
    createSession: (agentId) => ({
      id: "noop",
      agentId,
      conversationId: "noop",
      createdAt: Date.now(),
      lastUsedAt: Date.now(),
      status: "open"
    }),
    closeSession: () => {
    },
    reopenSession: () => {
    },
    setActiveSession: () => {
    },
    renameSession: () => {
    },
    touchSession: () => {
    },
    ensureSession: (agentId) => ({
      id: "noop",
      agentId,
      conversationId: "noop",
      createdAt: Date.now(),
      lastUsedAt: Date.now(),
      status: "open"
    })
  };
}
function defaultSessionLabel(session) {
  if (session.name && session.name.trim().length > 0) return session.name.trim();
  const date = new Date(session.createdAt);
  if (Number.isNaN(date.getTime())) return "Session";
  return date.toLocaleString(void 0, {
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit"
  });
}
export {
  AiChatSessionsProvider,
  defaultSessionLabel,
  useAiChatSessions
};
//# sourceMappingURL=AiChatSessions.js.map
