// src/core/events.ts
var TypedEventEmitter = class {
  constructor() {
    this.listeners = /* @__PURE__ */ new Map();
  }
  on(event, handler) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, /* @__PURE__ */ new Set());
    }
    this.listeners.get(event).add(handler);
    return () => this.off(event, handler);
  }
  off(event, handler) {
    this.listeners.get(event)?.delete(handler);
  }
  emit(event, payload) {
    this.listeners.get(event)?.forEach((handler) => {
      try {
        handler(payload);
      } catch (error) {
        console.error(`Error in ${String(event)} handler:`, error);
      }
    });
  }
  clear() {
    this.listeners.clear();
  }
  removeAllListeners(event) {
    if (event) {
      this.listeners.delete(event);
    } else {
      this.listeners.clear();
    }
  }
};

// src/core/api.ts
var WidgetAPI = class {
  constructor(config) {
    this.config = {
      baseUrl: "http://localhost:3000",
      userId: "",
      debug: false,
      assistantId: config.apiKey,
      // Default to apiKey for backwards compatibility
      ...config
    };
  }
  async createSession() {
    const response = await this.request("/sessions", {
      method: "POST",
      body: JSON.stringify({
        // apiKey IS the assistantId
        assistantId: this.config.apiKey,
        userId: this.config.userId
      })
    });
    return response;
  }
  async sendMessage(sessionId, content) {
    const response = await this.request(
      `/sessions/${sessionId}/messages`,
      {
        method: "POST",
        body: JSON.stringify({ content })
      }
    );
    return response;
  }
  async getHistory(sessionId) {
    return this.request(`/sessions/${sessionId}/messages`);
  }
  async getSessions() {
    return this.request("/sessions");
  }
  async getArtifacts() {
    return this.request("/artifacts");
  }
  async getArtifact(id) {
    return this.request(`/artifacts/${id}`);
  }
  async createArtifact(artifact) {
    return this.request("/artifacts", {
      method: "POST",
      body: JSON.stringify(artifact)
    });
  }
  async request(endpoint, options = {}) {
    const url = `${this.config.baseUrl}${endpoint}`;
    this.log("Request:", url, options);
    const response = await fetch(url, {
      ...options,
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${this.config.apiKey}`,
        ...options.headers
      }
    });
    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      throw new Error(error.message || `HTTP ${response.status}`);
    }
    return response.json();
  }
  log(...args) {
    if (this.config.debug) {
      console.log("[CourseAI]", ...args);
    }
  }
};

// src/core/client.ts
var WidgetClient = class {
  constructor(config) {
    this.state = { status: "idle" };
    this.events = new TypedEventEmitter();
    this.config = config;
    this.api = new WidgetAPI(config);
  }
  /**
   * Initialize the widget and create a chat session
   */
  async initialize() {
    if (this.state.status !== "idle") {
      throw new Error("Widget already initialized");
    }
    this.setState({ status: "initializing" });
    try {
      const session = await this.api.createSession();
      this.setState({ status: "ready", session });
      this.events.emit("session:created", { session });
    } catch (error) {
      const widgetError = {
        code: "INIT_FAILED",
        message: error instanceof Error ? error.message : "Unknown error",
        details: error
      };
      this.setState({ status: "error", error: widgetError });
      this.events.emit("error", { error: widgetError });
      throw error;
    }
  }
  /**
   * Send a message to the AI assistant
   */
  async sendMessage(content) {
    if (this.state.status !== "ready") {
      throw new Error("Widget not ready. Call initialize() first.");
    }
    const userMessage = {
      id: crypto.randomUUID(),
      role: "user",
      content,
      timestamp: Date.now()
    };
    const session = {
      ...this.state.session,
      messages: [...this.state.session.messages, userMessage]
    };
    this.setState({ status: "ready", session });
    this.events.emit("message:sent", { message: userMessage });
    this.setState({ status: "loading" });
    try {
      const assistantMessage = await this.api.sendMessage(
        session.id,
        content
      );
      const updatedSession = {
        ...session,
        messages: [...session.messages, assistantMessage]
      };
      this.setState({ status: "ready", session: updatedSession });
      this.events.emit("message:received", { message: assistantMessage });
      return assistantMessage;
    } catch (error) {
      const widgetError = {
        code: "SEND_MESSAGE_FAILED",
        message: error instanceof Error ? error.message : "Failed to send message",
        details: error
      };
      this.setState({ status: "ready", session });
      this.events.emit("error", { error: widgetError });
      throw error;
    }
  }
  /**
   * Get current state
   */
  getState() {
    return this.state;
  }
  /**
   * Get the API instance for direct calls
   */
  getAPI() {
    return this.api;
  }
  /**
   * Get the widget configuration
   */
  getConfig() {
    return this.config;
  }
  /**
   * Subscribe to events
   */
  on(event, handler) {
    return this.events.on(event, handler);
  }
  /**
   * Unsubscribe from events
   */
  off(event, handler) {
    this.events.off(event, handler);
  }
  /**
   * Clean up resources
   */
  destroy() {
    this.events.clear();
    this.setState({ status: "idle" });
  }
  setState(newState) {
    const previous = this.state;
    this.state = newState;
    this.events.emit("state:change", { previous, current: newState });
  }
};

export { TypedEventEmitter, WidgetAPI, WidgetClient };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map