@yassirbenmoussa/aicommerce-sdk 1.9.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-commerce.min.js +55 -35
- package/dist/index.cjs +37 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +37 -10
- package/dist/index.mjs.map +1 -1
- package/dist/widget.min.js +37 -17
- package/dist/widget.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/widget-styles.ts","../src/widget.ts","../src/index.ts"],"names":["AICommerce","AICommerceError","AICommerceWidget"],"mappings":"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AAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,EA6a9C,MAAA,GAAS,gBAAgB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AA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","file":"index.cjs","sourcesContent":["import type {\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Session,\r\n APIError,\r\n Product,\r\n} from './types';\r\n\r\n/**\r\n * AI Commerce SDK Client\r\n * \r\n * @example\r\n * ```typescript\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop under $1000');\r\n * console.log(response.products);\r\n * ```\r\n */\r\nexport class AICommerce {\r\n private readonly apiKey: string;\r\n private readonly storeId: string | undefined;\r\n private readonly baseUrl: string;\r\n private readonly timeout: number;\r\n private sessionToken: string | null = null;\r\n\r\n constructor(config: AICommerceConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('AICommerce: apiKey is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.storeId = config.storeId;\r\n this.baseUrl = this.normalizeUrl(config.baseUrl || this.detectBaseUrl());\r\n this.timeout = config.timeout || 30000;\r\n }\r\n\r\n /**\r\n * Detect the base URL based on environment\r\n */\r\n private detectBaseUrl(): string {\r\n // Check for data attribute on script tag (set by widget loader)\r\n if (typeof window !== 'undefined') {\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || 'https://api.aicommerce.dev';\r\n }\r\n }\r\n // Default to production API\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Normalize URL (remove trailing slash)\r\n */\r\n private normalizeUrl(url: string): string {\r\n return url.replace(/\\/$/, '');\r\n }\r\n\r\n /**\r\n * Make an API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n ...(this.storeId && { 'x-store-id': this.storeId }),\r\n ...(this.sessionToken && { 'X-Session-Token': this.sessionToken }),\r\n ...options.headers,\r\n },\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n const error: APIError = {\r\n code: errorData.code || 'UNKNOWN_ERROR',\r\n message: errorData.message || errorData.error || `HTTP ${response.status}`,\r\n status: response.status,\r\n };\r\n throw new AICommerceError(error.message, error.code, error.status);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n if (error instanceof AICommerceError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new AICommerceError('Request timeout', 'TIMEOUT', 408);\r\n }\r\n\r\n throw new AICommerceError(\r\n error instanceof Error ? error.message : 'Unknown error',\r\n 'NETWORK_ERROR',\r\n 0\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send a chat message and get product recommendations\r\n * \r\n * @param message - The user's message or full ChatRequest object\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Simple usage\r\n * const response = await client.chat('I need running shoes');\r\n * \r\n * // With context\r\n * const response = await client.chat('I need running shoes', {\r\n * budget: { max: 150 },\r\n * preferences: ['comfortable', 'lightweight']\r\n * });\r\n * ```\r\n */\r\n async chat(\r\n message: string | ChatRequest,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n const request: ChatRequest = typeof message === 'string'\r\n ? { message, context, sessionToken: this.sessionToken || undefined }\r\n : { ...message, sessionToken: message.sessionToken || this.sessionToken || undefined };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send an audio message and get product recommendations\r\n * \r\n * @param audioBlob - Audio blob (from MediaRecorder or file input)\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Record audio using MediaRecorder\r\n * const mediaRecorder = new MediaRecorder(stream);\r\n * const chunks: Blob[] = [];\r\n * mediaRecorder.ondataavailable = (e) => chunks.push(e.data);\r\n * mediaRecorder.onstop = async () => {\r\n * const audioBlob = new Blob(chunks, { type: 'audio/webm' });\r\n * const response = await client.chatWithAudio(audioBlob);\r\n * console.log(response.reply);\r\n * };\r\n * ```\r\n */\r\n async chatWithAudio(\r\n audioBlob: Blob,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n // Convert blob to base64\r\n const arrayBuffer = await audioBlob.arrayBuffer();\r\n const base64 = btoa(\r\n new Uint8Array(arrayBuffer).reduce(\r\n (data, byte) => data + String.fromCharCode(byte),\r\n ''\r\n )\r\n );\r\n\r\n const request: ChatRequest = {\r\n audioBase64: base64,\r\n audioMimeType: audioBlob.type || 'audio/webm',\r\n context,\r\n sessionToken: this.sessionToken || undefined,\r\n };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Create a new chat session\r\n * \r\n * @returns Session information with token\r\n */\r\n async createSession(): Promise<Session> {\r\n const response = await this.request<{ session: Session }>('/api/v1/chat/session', {\r\n method: 'POST',\r\n });\r\n\r\n this.sessionToken = response.session.token;\r\n return response.session;\r\n }\r\n\r\n /**\r\n * Clear the current session\r\n */\r\n clearSession(): void {\r\n this.sessionToken = null;\r\n }\r\n\r\n /**\r\n * Get the current session token\r\n */\r\n getSessionToken(): string | null {\r\n return this.sessionToken;\r\n }\r\n\r\n /**\r\n * Set a session token (for restoring sessions)\r\n */\r\n setSessionToken(token: string): void {\r\n this.sessionToken = token;\r\n }\r\n\r\n // ============================================\r\n // Products API\r\n // ============================================\r\n\r\n /**\r\n * Products API namespace\r\n */\r\n readonly products = {\r\n /**\r\n * Create a new product\r\n */\r\n create: async (product: CreateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify(product),\r\n });\r\n },\r\n\r\n /**\r\n * Batch upsert products (create or update)\r\n */\r\n batchUpsert: async (products: CreateProductInput[]): Promise<BatchUpsertResponse> => {\r\n return this.request<BatchUpsertResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify({ products }),\r\n });\r\n },\r\n\r\n /**\r\n * List products with pagination\r\n */\r\n list: async (options?: ListProductsOptions): Promise<ListProductsResponse> => {\r\n const params = new URLSearchParams();\r\n if (options?.page) params.set('page', String(options.page));\r\n if (options?.perPage) params.set('perPage', String(options.perPage));\r\n if (options?.search) params.set('search', options.search);\r\n if (options?.categoryId) params.set('categoryId', options.categoryId);\r\n if (options?.isActive !== undefined) params.set('isActive', String(options.isActive));\r\n\r\n const query = params.toString();\r\n return this.request<ListProductsResponse>(`/api/v1/products${query ? `?${query}` : ''}`);\r\n },\r\n\r\n /**\r\n * Get a single product by ID\r\n */\r\n get: async (productId: string): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`);\r\n },\r\n\r\n /**\r\n * Update a product\r\n */\r\n update: async (productId: string, data: UpdateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`, {\r\n method: 'PUT',\r\n body: JSON.stringify(data),\r\n });\r\n },\r\n\r\n /**\r\n * Delete a product\r\n */\r\n delete: async (productId: string): Promise<{ success: boolean; deleted: boolean }> => {\r\n return this.request<{ success: boolean; deleted: boolean }>(`/api/v1/products/${productId}`, {\r\n method: 'DELETE',\r\n });\r\n },\r\n };\r\n\r\n // ============================================\r\n // Upload API\r\n // ============================================\r\n\r\n /**\r\n * Upload an image file\r\n * \r\n * @example\r\n * ```typescript\r\n * // Upload from File input\r\n * const file = document.querySelector('input[type=\"file\"]').files[0];\r\n * const result = await client.upload(file);\r\n * console.log(result.url);\r\n * \r\n * // Upload and associate with product\r\n * const result = await client.upload(file, { productId: 'prod_123', isPrimary: true });\r\n * ```\r\n */\r\n async upload(file: File | Blob, options?: UploadOptions): Promise<UploadResponse> {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n\r\n if (options?.folder) formData.append('folder', options.folder);\r\n if (options?.productId) formData.append('productId', options.productId);\r\n if (options?.isPrimary) formData.append('isPrimary', 'true');\r\n\r\n const url = `${this.baseUrl}/api/v1/upload`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'X-API-Key': this.apiKey,\r\n },\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n throw new AICommerceError(\r\n errorData.message || errorData.error || `HTTP ${response.status}`,\r\n errorData.code || 'UPLOAD_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n /**\r\n * Static method for one-off chat requests\r\n * \r\n * @example\r\n * ```typescript\r\n * const response = await AICommerce.quickChat({\r\n * apiKey: 'your-api-key',\r\n * message: 'I need a laptop'\r\n * });\r\n * ```\r\n */\r\n static async quickChat(options: {\r\n apiKey: string;\r\n message: string;\r\n baseUrl?: string;\r\n context?: ChatContext;\r\n }): Promise<ChatResponse> {\r\n const client = new AICommerce({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl,\r\n });\r\n return client.chat(options.message, options.context);\r\n }\r\n}\r\n\r\n// ============================================\r\n// Product Types\r\n// ============================================\r\n\r\nexport interface CreateProductInput {\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n sku?: string;\r\n barcode?: string;\r\n price: number;\r\n compareAtPrice?: number;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string;\r\n externalId?: string;\r\n variantId?: string; // Shopify variant ID for add-to-cart\r\n categoryId?: string;\r\n images?: Array<{ url: string; alt?: string; isPrimary?: boolean }>;\r\n}\r\n\r\nexport interface UpdateProductInput {\r\n name?: string;\r\n slug?: string;\r\n description?: string | null;\r\n sku?: string | null;\r\n barcode?: string | null;\r\n price?: number;\r\n compareAtPrice?: number | null;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string | null;\r\n variantId?: string | null; // Shopify variant ID for add-to-cart\r\n categoryId?: string | null;\r\n}\r\n\r\nexport interface ProductResponse {\r\n success: boolean;\r\n product: Product;\r\n}\r\n\r\nexport interface BatchUpsertResponse {\r\n success: boolean;\r\n processed: number;\r\n errors: number;\r\n results: Array<{ id: string; slug: string; status: 'created' | 'updated' }>;\r\n errorDetails?: Array<{ slug: string; error: string }>;\r\n}\r\n\r\nexport interface ListProductsOptions {\r\n page?: number;\r\n perPage?: number;\r\n search?: string;\r\n categoryId?: string;\r\n isActive?: boolean;\r\n}\r\n\r\nexport interface ListProductsResponse {\r\n success: boolean;\r\n data: Product[];\r\n total: number;\r\n page: number;\r\n perPage: number;\r\n totalPages: number;\r\n}\r\n\r\nexport interface UploadOptions {\r\n folder?: string;\r\n productId?: string;\r\n isPrimary?: boolean;\r\n}\r\n\r\nexport interface UploadResponse {\r\n success: boolean;\r\n url: string;\r\n key: string;\r\n size: number;\r\n contentType: string;\r\n productImage?: {\r\n id: string;\r\n url: string;\r\n alt: string | null;\r\n isPrimary: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Custom error class for AI Commerce SDK\r\n */\r\nexport class AICommerceError extends Error {\r\n readonly code: string;\r\n readonly status: number;\r\n\r\n constructor(message: string, code: string, status: number) {\r\n super(message);\r\n this.name = 'AICommerceError';\r\n this.code = code;\r\n this.status = status;\r\n\r\n // Maintain proper prototype chain\r\n Object.setPrototypeOf(this, AICommerceError.prototype);\r\n }\r\n}\r\n","/**\r\n * Widget Styles (CSS-in-JS)\r\n * \r\n * Generates scoped CSS for the AI Commerce widget\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport type { WidgetConfig } from './types';\r\n\r\ntype ResolvedConfig = Required<Omit<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>> & Pick<WidgetConfig, 'storeId' | 'container'>;\r\n\r\n/**\r\n * Convert hex to RGB\r\n */\r\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : { r: 99, g: 102, b: 241 }; // Default indigo\r\n}\r\n\r\n/**\r\n * Create widget styles\r\n */\r\nexport function createWidgetStyles(config: ResolvedConfig): string {\r\n const primary = config.primaryColor;\r\n const rgb = hexToRgb(primary);\r\n const isLeft = config.position === 'bottom-left';\r\n\r\n return `\r\n/* AI Commerce Widget Styles */\r\n#aicommerce-widget {\r\n --aic-primary: ${primary};\r\n --aic-primary-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};\r\n --aic-primary-light: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.1);\r\n --aic-primary-dark: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.9);\r\n --aic-bg: #ffffff;\r\n --aic-bg-secondary: #f8fafc;\r\n --aic-text: #1e293b;\r\n --aic-text-secondary: #64748b;\r\n --aic-border: #e2e8f0;\r\n --aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\r\n --aic-radius: 16px;\r\n --aic-z-index: ${config.zIndex};\r\n \r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n position: fixed;\r\n bottom: 20px;\r\n ${isLeft ? 'left: 20px;' : 'right: 20px;'}\r\n z-index: var(--aic-z-index);\r\n}\r\n\r\n/* Dark theme */\r\n#aicommerce-widget.aicommerce-theme-dark,\r\n@media (prefers-color-scheme: dark) {\r\n #aicommerce-widget.aicommerce-theme-auto {\r\n --aic-bg: #1e293b;\r\n --aic-bg-secondary: #0f172a;\r\n --aic-text: #f1f5f9;\r\n --aic-text-secondary: #94a3b8;\r\n --aic-border: #334155;\r\n }\r\n}\r\n\r\n/* Launcher Button */\r\n.aicommerce-launcher {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n border: none;\r\n cursor: pointer;\r\n box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n animation: aic-pulse 2s infinite;\r\n}\r\n\r\n.aicommerce-launcher:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 30px rgba(var(--aic-primary-rgb), 0.5);\r\n}\r\n\r\n.aicommerce-launcher-icon {\r\n font-size: 24px;\r\n}\r\n\r\n.aicommerce-hidden {\r\n display: none !important;\r\n}\r\n\r\n@keyframes aic-pulse {\r\n 0%, 100% { box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4); }\r\n 50% { box-shadow: 0 4px 30px rgba(var(--aic-primary-rgb), 0.6); }\r\n}\r\n\r\n/* Chat Window */\r\n.aicommerce-chat {\r\n position: absolute;\r\n bottom: 0;\r\n ${isLeft ? 'left: 0;' : 'right: 0;'}\r\n width: 380px;\r\n max-width: calc(100vw - 40px);\r\n height: 600px;\r\n max-height: calc(100vh - 100px);\r\n background: var(--aic-bg);\r\n border-radius: var(--aic-radius);\r\n box-shadow: var(--aic-shadow);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n transform-origin: bottom ${isLeft ? 'left' : 'right'};\r\n}\r\n\r\n.aicommerce-chat.aicommerce-closed {\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n}\r\n\r\n.aicommerce-chat.aicommerce-open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n}\r\n\r\n/* Header */\r\n.aicommerce-header {\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n color: white;\r\n padding: 16px 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n}\r\n\r\n.aicommerce-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 20px;\r\n overflow: hidden;\r\n}\r\n\r\n.aicommerce-avatar img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-header-text {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.aicommerce-bot-name {\r\n font-weight: 600;\r\n font-size: 16px;\r\n}\r\n\r\n.aicommerce-status {\r\n font-size: 12px;\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-close {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n transition: background 0.2s;\r\n}\r\n\r\n.aicommerce-close:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Messages */\r\n.aicommerce-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n background: var(--aic-bg-secondary);\r\n}\r\n\r\n.aicommerce-message {\r\n max-width: 85%;\r\n animation: aic-slide-in 0.3s ease-out;\r\n}\r\n\r\n.aicommerce-message.aicommerce-user {\r\n align-self: flex-end;\r\n}\r\n\r\n.aicommerce-message.aicommerce-assistant {\r\n align-self: flex-start;\r\n}\r\n\r\n.aicommerce-message-content {\r\n padding: 12px 16px;\r\n border-radius: 16px;\r\n line-height: 1.5;\r\n}\r\n\r\n.aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.aicommerce-assistant .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n color: var(--aic-text);\r\n border-bottom-left-radius: 4px;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n@keyframes aic-slide-in {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n\r\n/* Typing Indicator */\r\n.aicommerce-typing {\r\n display: flex;\r\n gap: 4px;\r\n padding: 12px 16px;\r\n background: var(--aic-bg);\r\n border-radius: 16px;\r\n width: fit-content;\r\n}\r\n\r\n.aicommerce-typing span {\r\n width: 8px;\r\n height: 8px;\r\n background: var(--aic-text-secondary);\r\n border-radius: 50%;\r\n animation: aic-bounce 1.4s infinite ease-in-out;\r\n}\r\n\r\n.aicommerce-typing span:nth-child(1) { animation-delay: -0.32s; }\r\n.aicommerce-typing span:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes aic-bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}\r\n\r\n/* Product Cards */\r\n.aicommerce-products {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 12px;\r\n overflow-x: auto;\r\n padding-bottom: 16px;\r\n width: 100%;\r\n max-width: 100%;\r\n cursor: grab;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n scrollbar-width: none; /* Firefox */\r\n}\r\n.aicommerce-products::-webkit-scrollbar {\r\n display: none; /* Chrome/Safari */\r\n}\r\n\r\n.aicommerce-product-card {\r\n flex-shrink: 0;\r\n width: 280px;\r\n background: var(--aic-bg);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.aicommerce-product-card:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\r\n}\r\n\r\n.aicommerce-product-image {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-product-placeholder {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n background: var(--aic-bg-secondary);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 32px;\r\n}\r\n\r\n.aicommerce-product-info {\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.aicommerce-product-name {\r\n font-weight: 500;\r\n font-size: 13px;\r\n color: var(--aic-text);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.aicommerce-product-price {\r\n font-weight: 600;\r\n font-size: 14px;\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-product-desc {\r\n font-size: 12px;\r\n color: var(--aic-text-secondary);\r\n line-height: 1.4;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n margin-top: 4px;\r\n}\r\n\r\n/* Audio Player */\r\n.aicommerce-audio-player {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n min-width: 240px;\r\n padding: 4px 0;\r\n}\r\n\r\n.aicommerce-audio-btn {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n background: rgba(255, 255, 255, 0.25);\r\n color: white;\r\n flex-shrink: 0;\r\n padding: 0;\r\n}\r\n\r\n.aicommerce-audio-btn:hover {\r\n background: rgba(255, 255, 255, 0.35);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-audio-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n/* Invert colors for assistant (since background is white/gray) */\r\n.aicommerce-assistant .aicommerce-audio-btn {\r\n background: var(--aic-primary);\r\n color: white;\r\n}\r\n.aicommerce-assistant .aicommerce-audio-btn:hover {\r\n background: var(--aic-primary-dark);\r\n}\r\n\r\n.aicommerce-audio-waveform {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n min-width: 0; /* Prevent overflow */\r\n}\r\n\r\n.aicommerce-waveform-bars {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n height: 24px;\r\n cursor: pointer;\r\n width: 100%;\r\n}\r\n\r\n.aicommerce-waveform-bar {\r\n width: 3px;\r\n border-radius: 2px;\r\n min-height: 3px;\r\n transition: background-color 0.1s;\r\n flex-shrink: 0;\r\n}\r\n\r\n.aicommerce-audio-time {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 11px;\r\n font-weight: 500;\r\n}\r\n\r\n.aicommerce-user .aicommerce-audio-time {\r\n color: rgba(255, 255, 255, 0.8);\r\n}\r\n.aicommerce-assistant .aicommerce-audio-time {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* RTL Support */\r\n.aicommerce-rtl {\r\n direction: rtl;\r\n text-align: right;\r\n}\r\n.aicommerce-ltr {\r\n direction: ltr;\r\n text-align: left;\r\n}\r\n\r\n/* Input Area */\r\n.aicommerce-input-container {\r\n padding: 16px 20px;\r\n background: var(--aic-bg);\r\n border-top: 1px solid var(--aic-border);\r\n display: flex;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-input {\r\n flex: 1;\r\n padding: 12px 16px;\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n background: var(--aic-bg-secondary);\r\n color: var(--aic-text);\r\n font-size: 14px;\r\n outline: none;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-input:focus {\r\n border-color: var(--aic-primary);\r\n box-shadow: 0 0 0 3px var(--aic-primary-light);\r\n}\r\n\r\n.aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-send {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-send:hover:not(:disabled) {\r\n background: var(--aic-primary-dark);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-send:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n/* Microphone Button */\r\n.aicommerce-mic {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-bg-secondary);\r\n border: 1px solid var(--aic-border);\r\n color: var(--aic-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-mic:hover:not(:disabled) {\r\n background: var(--aic-primary-light);\r\n border-color: var(--aic-primary);\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-mic.aicommerce-recording {\r\n background: #ef4444;\r\n border-color: #ef4444;\r\n color: white;\r\n animation: aic-recording-pulse 1s infinite;\r\n}\r\n\r\n.aicommerce-mic:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n@keyframes aic-recording-pulse {\r\n 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }\r\n 50% { transform: scale(1.05); box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }\r\n}\r\n\r\n/* Mobile Responsive */\r\n@media (max-width: 420px) {\r\n #aicommerce-widget {\r\n bottom: 16px;\r\n ${isLeft ? 'left: 16px;' : 'right: 16px;'}\r\n }\r\n \r\n .aicommerce-chat {\r\n width: calc(100vw - 32px);\r\n height: calc(100vh - 100px);\r\n border-radius: 12px;\r\n }\r\n \r\n .aicommerce-launcher {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n}\r\n\r\n/* Scrollbar */\r\n.aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb {\r\n background: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background: var(--aic-text-secondary);\r\n}\r\n\r\n/* ============================================\r\n Embedded Mode Styles - ChatGPT Style\r\n ============================================ */\r\n\r\n/* Embedded container - fit content with max height */\r\n#aicommerce-widget.aicommerce-embedded {\r\n position: relative;\r\n bottom: auto;\r\n left: auto;\r\n right: auto;\r\n width: 100%;\r\n height: auto;\r\n max-height: var(--aic-max-height, 600px);\r\n display: flex;\r\n flex-direction: column;\r\n background: transparent;\r\n}\r\n\r\n/* Embedded mode: hide launcher button */\r\n.aicommerce-embedded .aicommerce-launcher {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: hide the header completely */\r\n.aicommerce-embedded .aicommerce-header {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: hide close button */\r\n.aicommerce-embedded .aicommerce-close {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: chat fills container with transparent background */\r\n.aicommerce-embedded .aicommerce-chat {\r\n position: relative;\r\n width: 100%;\r\n height: auto;\r\n max-width: 100%;\r\n border-radius: 0;\r\n background: transparent;\r\n box-shadow: none;\r\n transform: none !important;\r\n opacity: 1 !important;\r\n pointer-events: auto !important;\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n/* Embedded mode: no open/close animations */\r\n.aicommerce-embedded .aicommerce-chat.aicommerce-closed {\r\n opacity: 1 !important;\r\n transform: none !important;\r\n pointer-events: auto !important;\r\n}\r\n\r\n/* Embedded mode: messages area - messages start from bottom, grow upward */\r\n.aicommerce-embedded .aicommerce-messages {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-end;\r\n overflow-y: auto;\r\n max-height: calc(var(--aic-max-height, 600px) - 100px);\r\n padding: 16px;\r\n max-width: 700px;\r\n margin: 0 auto;\r\n width: 100%;\r\n background: transparent;\r\n gap: 12px;\r\n scrollbar-width: thin;\r\n scrollbar-color: var(--aic-border) transparent;\r\n}\r\n\r\n/* Embedded mode: custom scrollbar for webkit browsers */\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb {\r\n background-color: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background-color: var(--aic-text-secondary);\r\n}\r\n\r\n/* Embedded mode: messages have different styling */\r\n.aicommerce-embedded .aicommerce-message {\r\n max-width: 100%;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-color: var(--aic-primary);\r\n}\r\n\r\n/* Embedded mode: input container wrapper - always at bottom */\r\n.aicommerce-embedded .aicommerce-input-wrapper {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n padding: 16px;\r\n flex-shrink: 0;\r\n}\r\n\r\n/* Embedded mode: input container styled like ChatGPT */\r\n.aicommerce-embedded .aicommerce-input-container {\r\n width: 100%;\r\n max-width: 700px;\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n padding: 8px 12px;\r\n display: flex;\r\n align-items: flex-end;\r\n gap: 8px;\r\n}\r\n\r\n/* Embedded mode: textarea field styling - auto-grow */\r\n.aicommerce-embedded .aicommerce-input {\r\n flex: 1;\r\n min-width: 0;\r\n border: none;\r\n background: transparent;\r\n padding: 8px 4px;\r\n font-size: 16px;\r\n font-family: inherit;\r\n color: var(--aic-text);\r\n outline: none;\r\n resize: none;\r\n min-height: 24px;\r\n max-height: 150px;\r\n line-height: 1.5;\r\n overflow-y: auto;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* Embedded mode: buttons styling - smaller, no overflow */\r\n.aicommerce-embedded .aicommerce-mic,\r\n.aicommerce-embedded .aicommerce-send {\r\n flex-shrink: 0;\r\n width: 36px;\r\n height: 36px;\r\n min-width: 36px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n color: white;\r\n border: none;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic:hover,\r\n.aicommerce-embedded .aicommerce-send:hover {\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic {\r\n background: transparent;\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic:hover {\r\n background: rgba(0, 0, 0, 0.05);\r\n color: var(--aic-text);\r\n}\r\n\r\n/* Embedded mode: product cards styling */\r\n.aicommerce-embedded .aicommerce-products {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 12px;\r\n margin-top: 12px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-product-card {\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n max-width: 180px;\r\n}\r\n\r\n/* Embedded mode: typing indicator */\r\n.aicommerce-embedded .aicommerce-typing {\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n}\r\n\r\n/* Embedded mode responsive - mobile fixes */\r\n@media (max-width: 640px) {\r\n .aicommerce-embedded .aicommerce-input-container {\r\n padding: 6px 10px;\r\n gap: 6px;\r\n border-radius: 20px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-mic,\r\n .aicommerce-embedded .aicommerce-send {\r\n width: 32px;\r\n height: 32px;\r\n min-width: 32px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-mic svg,\r\n .aicommerce-embedded .aicommerce-send svg {\r\n width: 16px;\r\n height: 16px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-input {\r\n font-size: 16px;\r\n padding: 6px 4px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-messages {\r\n padding: 12px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-input-wrapper {\r\n padding: 12px;\r\n }\r\n}\r\n\r\n/* ============================================\r\n Add to Cart Button Styles\r\n ============================================ */\r\n\r\n.aicommerce-add-to-cart {\r\n width: 100%;\r\n padding: 8px 12px;\r\n background: var(--aic-primary);\r\n color: white;\r\n border: none;\r\n border-radius: 6px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n margin-top: 8px;\r\n transition: all 0.2s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n}\r\n\r\n.aicommerce-add-to-cart:hover {\r\n opacity: 0.9;\r\n transform: translateY(-1px);\r\n}\r\n\r\n.aicommerce-add-to-cart:active {\r\n transform: translateY(0);\r\n}\r\n\r\n.aicommerce-add-to-cart:disabled {\r\n opacity: 0.7;\r\n cursor: not-allowed;\r\n transform: none;\r\n}\r\n\r\n.aicommerce-add-to-cart svg {\r\n flex-shrink: 0;\r\n}\r\n\r\n/* Spinner animation for loading state */\r\n@keyframes aicommerce-spin {\r\n to { transform: rotate(360deg); }\r\n}\r\n\r\n.aicommerce-spinner {\r\n animation: aicommerce-spin 1s linear infinite;\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Inject styles into the document\r\n */\r\nexport function injectStyles(css: string): HTMLStyleElement {\r\n const style = document.createElement('style');\r\n style.id = 'aicommerce-widget-styles';\r\n style.textContent = css;\r\n\r\n // Remove existing styles\r\n const existing = document.getElementById('aicommerce-widget-styles');\r\n if (existing) {\r\n existing.remove();\r\n }\r\n\r\n document.head.appendChild(style);\r\n return style;\r\n}\r\n","/**\r\n * AI Commerce Chat Widget\r\n * \r\n * Embeddable chat widget for e-commerce stores\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport { AICommerce } from './client';\r\nimport type {\r\n WidgetConfig,\r\n WidgetInstance,\r\n WidgetDisplayMode,\r\n StoreConfig,\r\n Product,\r\n ChatResponse\r\n} from './types';\r\nimport { createWidgetStyles, injectStyles } from './widget-styles';\r\n\r\n// Widget state\r\ninterface WidgetState {\r\n isOpen: boolean;\r\n isLoading: boolean;\r\n isRecording: boolean;\r\n messages: Array<{\r\n role: 'user' | 'assistant';\r\n content: string;\r\n products?: Product[];\r\n audioUrl?: string; // Voice message URL\r\n audioDuration?: number;\r\n waveformBars?: number[];\r\n }>;\r\n storeConfig: StoreConfig | null;\r\n}\r\n\r\n/**\r\n * Create and initialize the AI Commerce chat widget\r\n */\r\nexport function createWidget(config: WidgetConfig): WidgetInstance {\r\n // Validate config\r\n if (!config.apiKey) {\r\n throw new Error('AICommerceWidget: apiKey is required');\r\n }\r\n\r\n // Initialize client\r\n const client = new AICommerce({\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl,\r\n });\r\n\r\n // Widget state\r\n const state: WidgetState = {\r\n isOpen: false,\r\n isLoading: true,\r\n isRecording: false,\r\n messages: [],\r\n storeConfig: null,\r\n };\r\n\r\n // Audio recording state\r\n let mediaRecorder: MediaRecorder | null = null;\r\n let audioChunks: Blob[] = [];\r\n\r\n // DOM elements\r\n let container: HTMLDivElement | null = null;\r\n let launcher: HTMLButtonElement | null = null;\r\n let chatWindow: HTMLDivElement | null = null;\r\n let styleElement: HTMLStyleElement | null = null;\r\n\r\n // Resolved config (merged with store config)\r\n let resolvedConfig: Required<Omit<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>> &\r\n Pick<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>;\r\n\r\n /**\r\n * Fetch store configuration\r\n */\r\n async function fetchStoreConfig(): Promise<StoreConfig | null> {\r\n try {\r\n const baseUrl = config.baseUrl || detectBaseUrl();\r\n const response = await fetch(`${baseUrl}/api/v1/store`, {\r\n headers: { 'x-api-key': config.apiKey },\r\n });\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data.store;\r\n } catch (error) {\r\n console.error('Failed to fetch store config:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Detect base URL\r\n */\r\n function detectBaseUrl(): string {\r\n if (typeof window !== 'undefined') {\r\n // Check for data attribute on script tag\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || '';\r\n }\r\n }\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Initialize the widget\r\n */\r\n async function initialize(): Promise<void> {\r\n // Fetch store config\r\n state.storeConfig = await fetchStoreConfig();\r\n\r\n // Determine display mode\r\n const displayMode: WidgetDisplayMode = config.displayMode || 'widget';\r\n const isEmbedded = displayMode === 'embedded';\r\n\r\n // Merge configs\r\n resolvedConfig = {\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl || detectBaseUrl(),\r\n displayMode: displayMode,\r\n container: config.container,\r\n maxHeight: config.maxHeight || '600px',\r\n placeholder: config.placeholder || 'Ask me anything about our products...',\r\n position: config.position || 'bottom-right',\r\n theme: config.theme || 'auto',\r\n primaryColor: config.primaryColor || state.storeConfig?.primaryColor || '#6366f1',\r\n welcomeMessage: config.welcomeMessage || state.storeConfig?.welcomeMessage || 'Hi! How can I help you find the perfect product today?',\r\n botName: config.botName || state.storeConfig?.chatBotName || 'Shopping Assistant',\r\n zIndex: config.zIndex || 9999,\r\n buttonText: config.buttonText || '💬',\r\n hideLauncher: config.hideLauncher || false,\r\n addToCartText: config.addToCartText,\r\n onOpen: config.onOpen,\r\n onClose: config.onClose,\r\n onProductClick: config.onProductClick,\r\n onAddToCart: config.onAddToCart,\r\n onMessage: config.onMessage,\r\n };\r\n\r\n // Inject styles\r\n const styles = createWidgetStyles(resolvedConfig);\r\n styleElement = injectStyles(styles);\r\n\r\n // Create or use container based on display mode\r\n if (isEmbedded) {\r\n // Embedded mode: render into provided container\r\n let targetContainer: HTMLElement | null = null;\r\n\r\n if (typeof config.container === 'string') {\r\n targetContainer = document.querySelector(config.container);\r\n } else if (config.container instanceof HTMLElement) {\r\n targetContainer = config.container;\r\n }\r\n\r\n if (!targetContainer) {\r\n console.error('[AI Commerce] Embedded mode requires a valid container element or selector');\r\n return;\r\n }\r\n\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-embedded aicommerce-theme-${resolvedConfig.theme}`;\r\n container.style.setProperty('--aic-max-height', resolvedConfig.maxHeight);\r\n\r\n targetContainer.appendChild(container);\r\n\r\n // In embedded mode, chat is always open\r\n state.isOpen = true;\r\n } else {\r\n // Widget mode: append to body with fixed positioning\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;\r\n document.body.appendChild(container);\r\n }\r\n\r\n // Render widget\r\n render();\r\n\r\n // For widget mode, add welcome message. For embedded mode, start empty (ChatGPT style)\r\n if (!isEmbedded) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: resolvedConfig.welcomeMessage,\r\n });\r\n }\r\n state.isLoading = false;\r\n render();\r\n }\r\n\r\n /**\r\n * Add product to Shopify cart using Ajax Cart API\r\n */\r\n async function addToShopifyCart(variantId: string, quantity: number = 1): Promise<void> {\r\n const response = await fetch('/cart/add.js', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n id: variantId,\r\n quantity: quantity,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error('Failed to add to cart');\r\n }\r\n\r\n // Trigger cart update event for Shopify themes\r\n document.dispatchEvent(new CustomEvent('cart:refresh'));\r\n }\r\n\r\n /**\r\n * Render the widget\r\n */\r\n function render(): void {\r\n if (!container) return;\r\n\r\n const isEmbedded = resolvedConfig.displayMode === 'embedded';\r\n const hasUserMessages = state.messages.some(m => m.role === 'user');\r\n\r\n // Update container class for embedded mode based on message state\r\n if (isEmbedded) {\r\n container.classList.remove('aicommerce-no-messages', 'aicommerce-has-messages');\r\n container.classList.add(hasUserMessages ? 'aicommerce-has-messages' : 'aicommerce-no-messages');\r\n }\r\n\r\n const placeholder = resolvedConfig.placeholder || 'Ask me anything about our products...';\r\n\r\n // Generate input container HTML - use textarea for embedded mode for auto-grow\r\n const inputContainerHtml = `\r\n <div class=\"aicommerce-input-container\">\r\n ${isEmbedded ? `\r\n <textarea \r\n class=\"aicommerce-input\" \r\n placeholder=\"${placeholder}\"\r\n rows=\"1\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n ></textarea>\r\n ` : `\r\n <input \r\n type=\"text\" \r\n class=\"aicommerce-input\" \r\n placeholder=\"${placeholder}\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n />\r\n `}\r\n <button class=\"aicommerce-mic ${state.isRecording ? 'aicommerce-recording' : ''}\" ${state.isLoading ? 'disabled' : ''} aria-label=\"${state.isRecording ? 'Stop recording' : 'Voice input'}\">\r\n ${state.isRecording ? `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/>\r\n </svg>\r\n ` : `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\r\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>\r\n </svg>\r\n `}\r\n </button>\r\n <button class=\"aicommerce-send\" ${state.isLoading || state.isRecording ? 'disabled' : ''} aria-label=\"Send message\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n `;\r\n\r\n const html = `\r\n ${!isEmbedded && !resolvedConfig.hideLauncher ? `\r\n <button class=\"aicommerce-launcher ${state.isOpen ? 'aicommerce-hidden' : ''}\" aria-label=\"Open chat\">\r\n <span class=\"aicommerce-launcher-icon\">${resolvedConfig.buttonText}</span>\r\n </button>\r\n ` : ''}\r\n \r\n <div class=\"aicommerce-chat ${state.isOpen ? 'aicommerce-open' : 'aicommerce-closed'}\">\r\n ${!isEmbedded ? `\r\n <div class=\"aicommerce-header\">\r\n <div class=\"aicommerce-header-info\">\r\n <div class=\"aicommerce-avatar\">\r\n ${state.storeConfig?.logo\r\n ? `<img src=\"${state.storeConfig.logo}\" alt=\"${resolvedConfig.botName}\" />`\r\n : `<span>🤖</span>`\r\n }\r\n </div>\r\n <div class=\"aicommerce-header-text\">\r\n <span class=\"aicommerce-bot-name\">${resolvedConfig.botName}</span>\r\n <span class=\"aicommerce-status\">Online</span>\r\n </div>\r\n </div>\r\n <button class=\"aicommerce-close\" aria-label=\"Close chat\">✕</button>\r\n </div>\r\n ` : ''}\r\n \r\n ${isEmbedded && hasUserMessages ? `\r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n ` : ''}\r\n \r\n ${!isEmbedded ? `\r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\" data-variant-id=\"${product.variantId || ''}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n <button class=\"aicommerce-add-to-cart\" data-product-id=\"${product.id}\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <circle cx=\"9\" cy=\"21\" r=\"1\"/><circle cx=\"20\" cy=\"21\" r=\"1\"/>\r\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"/>\r\n </svg>\r\n ${resolvedConfig.addToCartText || 'Add to Cart'}\r\n </button>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n ` : ''}\r\n \r\n ${isEmbedded ? `\r\n <div class=\"aicommerce-input-wrapper\">\r\n ${inputContainerHtml}\r\n </div>\r\n ` : inputContainerHtml}\r\n </div>\r\n `;\r\n\r\n container.innerHTML = html;\r\n\r\n // Attach event listeners\r\n attachEventListeners();\r\n\r\n // Scroll to bottom\r\n const messagesEl = container.querySelector('.aicommerce-messages');\r\n if (messagesEl) {\r\n messagesEl.scrollTop = messagesEl.scrollHeight;\r\n }\r\n }\r\n\r\n function renderAudioPlayer(msg: any, index: number, isUser: boolean): string {\r\n return `\r\n <div class=\"aicommerce-audio-player\" data-message-index=\"${index}\">\r\n <button class=\"aicommerce-audio-btn\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>\r\n </button>\r\n <div class=\"aicommerce-audio-waveform\">\r\n <div class=\"aicommerce-waveform-bars\">\r\n ${(msg.waveformBars || Array(40).fill(10)).map((height: number) => `\r\n <div class=\"aicommerce-waveform-bar\" style=\"height: ${height}%; background-color: ${isUser ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)'}\"></div>\r\n `).join('')}\r\n </div>\r\n <div class=\"aicommerce-audio-time\">\r\n <span class=\"aicommerce-current-time\">0:00</span>\r\n <span>${formatTime(msg.audioDuration || 0)}</span>\r\n </div>\r\n </div>\r\n <audio src=\"${msg.audioUrl}\" preload=\"metadata\"></audio>\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Attach event listeners\r\n */\r\n function attachEventListeners(): void {\r\n if (!container) return;\r\n\r\n // Launcher click\r\n const launcherEl = container.querySelector('.aicommerce-launcher');\r\n if (launcherEl) {\r\n launcherEl.addEventListener('click', () => open());\r\n }\r\n\r\n // Close button\r\n const closeEl = container.querySelector('.aicommerce-close');\r\n if (closeEl) {\r\n closeEl.addEventListener('click', () => close());\r\n }\r\n\r\n // Input\r\n const inputEl = container.querySelector('.aicommerce-input') as HTMLInputElement | HTMLTextAreaElement;\r\n const sendEl = container.querySelector('.aicommerce-send');\r\n\r\n if (inputEl) {\r\n // Handle Enter key - for textarea, Shift+Enter adds newline, Enter alone sends\r\n inputEl.addEventListener('keydown', (e: Event) => {\r\n const keyEvent = e as KeyboardEvent;\r\n if (keyEvent.key === 'Enter') {\r\n const isTextarea = inputEl instanceof HTMLTextAreaElement;\r\n // For textarea: Shift+Enter = newline, Enter = send\r\n // For input: Enter = send\r\n if (isTextarea && keyEvent.shiftKey) {\r\n // Allow default behavior (new line)\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n const value = inputEl.value.trim();\r\n if (value) {\r\n handleSend(value);\r\n inputEl.value = '';\r\n // Reset textarea height after sending\r\n if (isTextarea) {\r\n inputEl.style.height = 'auto';\r\n }\r\n }\r\n }\r\n });\r\n\r\n // Auto-grow for textarea\r\n if (inputEl instanceof HTMLTextAreaElement) {\r\n inputEl.addEventListener('input', () => {\r\n inputEl.style.height = 'auto';\r\n inputEl.style.height = Math.min(inputEl.scrollHeight, 150) + 'px';\r\n });\r\n }\r\n }\r\n\r\n if (sendEl && inputEl) {\r\n sendEl.addEventListener('click', () => {\r\n const value = inputEl.value.trim();\r\n if (value) {\r\n handleSend(value);\r\n inputEl.value = '';\r\n // Reset textarea height after sending\r\n if (inputEl instanceof HTMLTextAreaElement) {\r\n inputEl.style.height = 'auto';\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Microphone button\r\n const micEl = container.querySelector('.aicommerce-mic');\r\n if (micEl) {\r\n micEl.addEventListener('click', () => handleMicClick());\r\n }\r\n\r\n // Product clicks\r\n const productCards = container.querySelectorAll('.aicommerce-product-card');\r\n productCards.forEach(card => {\r\n card.addEventListener('click', (e) => {\r\n // Don't trigger if clicking add to cart button\r\n if ((e.target as Element).closest('.aicommerce-add-to-cart')) return;\r\n\r\n const productId = card.getAttribute('data-product-id');\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (product) {\r\n if (resolvedConfig.onProductClick) {\r\n resolvedConfig.onProductClick(product);\r\n } else if (product.url) {\r\n // Default behavior: open product URL in new tab\r\n window.open(product.url, '_blank', 'noopener,noreferrer');\r\n }\r\n }\r\n });\r\n });\r\n\r\n // Add to Cart buttons\r\n const addToCartBtns = container.querySelectorAll('.aicommerce-add-to-cart');\r\n addToCartBtns.forEach(btn => {\r\n btn.addEventListener('click', async (e) => {\r\n e.stopPropagation(); // Prevent product card click\r\n\r\n const button = btn as HTMLButtonElement;\r\n const productCard = button.closest('.aicommerce-product-card');\r\n const productId = productCard?.getAttribute('data-product-id');\r\n const variantId = productCard?.getAttribute('data-variant-id');\r\n\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (!product) return;\r\n\r\n // Show loading state\r\n const originalText = button.innerHTML;\r\n button.disabled = true;\r\n button.innerHTML = `\r\n <svg class=\"aicommerce-spinner\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-dasharray=\"32\" stroke-dashoffset=\"32\"/>\r\n </svg>\r\n Adding...\r\n `;\r\n\r\n try {\r\n if (resolvedConfig.onAddToCart) {\r\n // Custom callback\r\n await resolvedConfig.onAddToCart(product);\r\n } else if (variantId && (window as any).Shopify) {\r\n // Shopify Ajax Cart API\r\n await addToShopifyCart(variantId);\r\n } else if (product.url) {\r\n // Fallback: open product page\r\n window.open(product.url, '_blank', 'noopener,noreferrer');\r\n }\r\n\r\n // Success state\r\n button.innerHTML = `\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n Added!\r\n `;\r\n setTimeout(() => {\r\n button.innerHTML = originalText;\r\n button.disabled = false;\r\n }, 2000);\r\n } catch (error) {\r\n console.error('[AI Commerce] Add to cart failed:', error);\r\n button.innerHTML = originalText;\r\n button.disabled = false;\r\n }\r\n });\r\n });\r\n\r\n // Product Sliders (Drag to Scroll)\r\n const sliders = container.querySelectorAll('.aicommerce-products') as NodeListOf<HTMLElement>;\r\n sliders.forEach(slider => {\r\n let isDown = false;\r\n let startX = 0;\r\n let scrollLeft = 0;\r\n\r\n slider.addEventListener('mousedown', (e) => {\r\n isDown = true;\r\n slider.style.cursor = 'grabbing';\r\n startX = e.pageX - slider.offsetLeft;\r\n scrollLeft = slider.scrollLeft;\r\n });\r\n slider.addEventListener('mouseleave', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mouseup', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mousemove', (e) => {\r\n if (!isDown) return;\r\n e.preventDefault();\r\n const x = e.pageX - slider.offsetLeft;\r\n const walk = (x - startX) * 2; // scroll-fast\r\n slider.scrollLeft = scrollLeft - walk;\r\n });\r\n });\r\n\r\n // Audio Players\r\n const audioPlayers = container.querySelectorAll('.aicommerce-audio-player');\r\n audioPlayers.forEach(player => {\r\n const audio = player.querySelector('audio');\r\n const btn = player.querySelector('.aicommerce-audio-btn');\r\n const bars = player.querySelectorAll('.aicommerce-waveform-bar');\r\n const timeDisplay = player.querySelector('.aicommerce-current-time');\r\n\r\n if (!audio || !btn) return;\r\n\r\n // Toggle Play\r\n btn.addEventListener('click', () => {\r\n const isPlaying = !audio.paused;\r\n\r\n if (!isPlaying) {\r\n // Pause all others\r\n container?.querySelectorAll('audio').forEach((a: HTMLAudioElement) => {\r\n if (a !== audio && !a.paused) {\r\n a.pause();\r\n const parent = a.closest('.aicommerce-audio-player');\r\n const otherBtn = parent?.querySelector('.aicommerce-audio-btn');\r\n if (otherBtn) otherBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.play();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect></svg>`;\r\n } else {\r\n audio.pause();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.addEventListener('timeupdate', () => {\r\n if (timeDisplay) timeDisplay.textContent = formatTime(audio.currentTime);\r\n\r\n if (audio.duration) {\r\n const progress = (audio.currentTime / audio.duration) * 100;\r\n bars.forEach((bar, i) => {\r\n const barPos = (i / bars.length) * 100;\r\n if (barPos <= progress) {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,1)' : 'var(--aic-primary)';\r\n } else {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)';\r\n }\r\n });\r\n }\r\n });\r\n\r\n audio.addEventListener('ended', () => {\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n });\r\n\r\n const waveform = player.querySelector('.aicommerce-waveform-bars');\r\n if (waveform) {\r\n waveform.addEventListener('click', (e: any) => {\r\n const rect = waveform.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const percent = x / rect.width;\r\n if (audio.duration) {\r\n audio.currentTime = percent * audio.duration;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handle microphone button click\r\n */\r\n async function handleMicClick(): Promise<void> {\r\n if (state.isRecording) {\r\n // Stop recording\r\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\r\n mediaRecorder.stop();\r\n }\r\n } else {\r\n // Start recording\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\r\n audioChunks = [];\r\n\r\n mediaRecorder = new MediaRecorder(stream, {\r\n mimeType: MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\r\n });\r\n\r\n mediaRecorder.ondataavailable = (e) => {\r\n if (e.data.size > 0) {\r\n audioChunks.push(e.data);\r\n }\r\n };\r\n\r\n mediaRecorder.onstop = async () => {\r\n // Stop all tracks\r\n stream.getTracks().forEach(track => track.stop());\r\n\r\n if (audioChunks.length > 0) {\r\n const audioBlob = new Blob(audioChunks, { type: mediaRecorder?.mimeType || 'audio/webm' });\r\n await handleAudioSend(audioBlob);\r\n }\r\n\r\n state.isRecording = false;\r\n render();\r\n };\r\n\r\n mediaRecorder.start();\r\n state.isRecording = true;\r\n render();\r\n } catch (error) {\r\n console.error('Failed to start recording:', error);\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Unable to access microphone. Please check your permissions.',\r\n });\r\n render();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending audio message\r\n */\r\n async function handleAudioSend(audioBlob: Blob): Promise<ChatResponse> {\r\n // Create audio URL for playback\r\n const audioUrl = URL.createObjectURL(audioBlob);\r\n\r\n // Analyze audio for waveform\r\n let waveformBars: number[] = Array(40).fill(10);\r\n let audioDuration = 0;\r\n\r\n try {\r\n waveformBars = await analyzeAudio(audioBlob);\r\n\r\n // Get duration\r\n const audio = new Audio(audioUrl);\r\n await new Promise<void>((resolve) => {\r\n audio.onloadedmetadata = () => {\r\n audioDuration = audio.duration;\r\n resolve();\r\n };\r\n audio.onerror = () => resolve();\r\n });\r\n } catch (e) {\r\n console.error(\"Audio analysis failed\", e);\r\n }\r\n\r\n // Add user message with audio\r\n state.messages.push({\r\n role: 'user',\r\n content: 'Voice message',\r\n audioUrl,\r\n audioDuration,\r\n waveformBars\r\n });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chatWithAudio(audioBlob);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage('Voice message', response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error processing your voice message. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Helpers\r\n */\r\n function isArabic(text: string): boolean {\r\n return /[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/.test(text);\r\n }\r\n\r\n function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n }\r\n\r\n async function analyzeAudio(blob: Blob): Promise<number[]> {\r\n try {\r\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\r\n const arrayBuffer = await blob.arrayBuffer();\r\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\r\n const channelData = audioBuffer.getChannelData(0);\r\n\r\n const bars = 40;\r\n const step = Math.floor(channelData.length / bars);\r\n const calculatedBars = [];\r\n\r\n for (let i = 0; i < bars; i++) {\r\n const start = i * step;\r\n const end = start + step;\r\n let sum = 0;\r\n for (let j = start; j < end; j++) {\r\n if (channelData[j]) sum += channelData[j] * channelData[j];\r\n }\r\n const rms = Math.sqrt(sum / step);\r\n const height = Math.min(100, Math.max(10, rms * 400));\r\n calculatedBars.push(height);\r\n }\r\n return calculatedBars;\r\n } catch (e) {\r\n console.error(\"Analysis error\", e);\r\n return Array.from({ length: 40 }, () => 20 + Math.random() * 60);\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending a message\r\n */\r\n async function handleSend(message: string): Promise<ChatResponse> {\r\n // Add user message\r\n state.messages.push({ role: 'user', content: message });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chat(message);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage(message, response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Open the widget\r\n */\r\n function open(): void {\r\n state.isOpen = true;\r\n render();\r\n resolvedConfig.onOpen?.();\r\n\r\n // Focus input\r\n setTimeout(() => {\r\n const input = container?.querySelector('.aicommerce-input') as HTMLInputElement;\r\n input?.focus();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the widget\r\n */\r\n function close(): void {\r\n state.isOpen = false;\r\n render();\r\n resolvedConfig.onClose?.();\r\n }\r\n\r\n /**\r\n * Toggle the widget\r\n */\r\n function toggle(): void {\r\n if (state.isOpen) {\r\n close();\r\n } else {\r\n open();\r\n }\r\n }\r\n\r\n /**\r\n * Destroy the widget\r\n */\r\n function destroy(): void {\r\n if (container) {\r\n container.remove();\r\n container = null;\r\n }\r\n if (styleElement) {\r\n styleElement.remove();\r\n styleElement = null;\r\n }\r\n }\r\n\r\n /**\r\n * Update configuration\r\n */\r\n function updateConfig(newConfig: Partial<WidgetConfig>): void {\r\n Object.assign(resolvedConfig, newConfig);\r\n\r\n if (newConfig.primaryColor) {\r\n const styles = createWidgetStyles(resolvedConfig);\r\n if (styleElement) {\r\n styleElement.textContent = styles;\r\n }\r\n }\r\n\r\n render();\r\n }\r\n\r\n // Utility functions\r\n function escapeHtml(text: string): string {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n }\r\n\r\n function formatPrice(price: number, currency?: string): string {\r\n const symbols: Record<string, string> = {\r\n USD: '$', EUR: '€', GBP: '£', MAD: 'DH',\r\n SAR: 'SAR', AED: 'AED', JPY: '¥', CNY: '¥',\r\n };\r\n const symbol = symbols[currency || 'USD'] || currency || '$';\r\n return `${price.toFixed(2)} ${symbol}`;\r\n }\r\n\r\n // Initialize and return instance\r\n initialize();\r\n\r\n return {\r\n open,\r\n close,\r\n toggle,\r\n destroy,\r\n sendMessage: handleSend,\r\n updateConfig,\r\n };\r\n}\r\n\r\n/**\r\n * Global widget initialization for script tag usage\r\n */\r\nexport const AICommerceWidget = {\r\n init: createWidget,\r\n VERSION: '1.0.0',\r\n};\r\n\r\n// Auto-attach to window for UMD builds\r\nif (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).AICommerceWidget = AICommerceWidget;\r\n}\r\n","/**\r\n * AI Commerce SDK\r\n * \r\n * AI-powered product recommendations for e-commerce\r\n * \r\n * @packageDocumentation\r\n * @module @yassirbenmoussa/aicommerce-sdk\r\n * \r\n * @example\r\n * ```typescript\r\n * // npm usage - Client API\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop');\r\n * console.log(response.products);\r\n * ```\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Widget usage -->\r\n * <script src=\"https://cdn.aicommerce.dev/widget.min.js\"></script>\r\n * <script>\r\n * AICommerceWidget.init({\r\n * apiKey: 'your-api-key',\r\n * position: 'bottom-right',\r\n * theme: 'auto'\r\n * });\r\n * </script>\r\n * ```\r\n */\r\n\r\n// Export main client\r\nexport { AICommerce, AICommerceError } from './client';\r\n\r\n// Export widget\r\nexport { createWidget, AICommerceWidget } from './widget';\r\n\r\n// Export all types\r\nexport type {\r\n // Client types\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Product,\r\n Session,\r\n APIError,\r\n EventType,\r\n EventCallback,\r\n // Widget types\r\n StoreConfig,\r\n WidgetConfig,\r\n WidgetInstance,\r\n} from './types';\r\n\r\n// Version\r\nexport const VERSION = '1.0.0';\r\n\r\n// For UMD builds, attach to window\r\nif (typeof window !== 'undefined') {\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerce = require('./client').AICommerce;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceError = require('./client').AICommerceError;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceWidget = require('./widget').AICommerceWidget;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/widget-styles.ts","../src/widget.ts","../src/index.ts"],"names":["AICommerce","AICommerceError","AICommerceWidget"],"mappings":"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AAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,EA6a9C,MAAA,GAAS,gBAAgB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAA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","file":"index.cjs","sourcesContent":["import type {\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Session,\r\n APIError,\r\n Product,\r\n} from './types';\r\n\r\n/**\r\n * AI Commerce SDK Client\r\n * \r\n * @example\r\n * ```typescript\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop under $1000');\r\n * console.log(response.products);\r\n * ```\r\n */\r\nexport class AICommerce {\r\n private readonly apiKey: string;\r\n private readonly storeId: string | undefined;\r\n private readonly baseUrl: string;\r\n private readonly timeout: number;\r\n private sessionToken: string | null = null;\r\n\r\n constructor(config: AICommerceConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('AICommerce: apiKey is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.storeId = config.storeId;\r\n this.baseUrl = this.normalizeUrl(config.baseUrl || this.detectBaseUrl());\r\n this.timeout = config.timeout || 30000;\r\n }\r\n\r\n /**\r\n * Detect the base URL based on environment\r\n */\r\n private detectBaseUrl(): string {\r\n // Check for data attribute on script tag (set by widget loader)\r\n if (typeof window !== 'undefined') {\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || 'https://api.aicommerce.dev';\r\n }\r\n }\r\n // Default to production API\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Normalize URL (remove trailing slash)\r\n */\r\n private normalizeUrl(url: string): string {\r\n return url.replace(/\\/$/, '');\r\n }\r\n\r\n /**\r\n * Make an API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n ...(this.storeId && { 'x-store-id': this.storeId }),\r\n ...(this.sessionToken && { 'X-Session-Token': this.sessionToken }),\r\n ...options.headers,\r\n },\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n const error: APIError = {\r\n code: errorData.code || 'UNKNOWN_ERROR',\r\n message: errorData.message || errorData.error || `HTTP ${response.status}`,\r\n status: response.status,\r\n };\r\n throw new AICommerceError(error.message, error.code, error.status);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n if (error instanceof AICommerceError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new AICommerceError('Request timeout', 'TIMEOUT', 408);\r\n }\r\n\r\n throw new AICommerceError(\r\n error instanceof Error ? error.message : 'Unknown error',\r\n 'NETWORK_ERROR',\r\n 0\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send a chat message and get product recommendations\r\n * \r\n * @param message - The user's message or full ChatRequest object\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Simple usage\r\n * const response = await client.chat('I need running shoes');\r\n * \r\n * // With context\r\n * const response = await client.chat('I need running shoes', {\r\n * budget: { max: 150 },\r\n * preferences: ['comfortable', 'lightweight']\r\n * });\r\n * ```\r\n */\r\n async chat(\r\n message: string | ChatRequest,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n const request: ChatRequest = typeof message === 'string'\r\n ? { message, context, sessionToken: this.sessionToken || undefined }\r\n : { ...message, sessionToken: message.sessionToken || this.sessionToken || undefined };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send an audio message and get product recommendations\r\n * \r\n * @param audioBlob - Audio blob (from MediaRecorder or file input)\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Record audio using MediaRecorder\r\n * const mediaRecorder = new MediaRecorder(stream);\r\n * const chunks: Blob[] = [];\r\n * mediaRecorder.ondataavailable = (e) => chunks.push(e.data);\r\n * mediaRecorder.onstop = async () => {\r\n * const audioBlob = new Blob(chunks, { type: 'audio/webm' });\r\n * const response = await client.chatWithAudio(audioBlob);\r\n * console.log(response.reply);\r\n * };\r\n * ```\r\n */\r\n async chatWithAudio(\r\n audioBlob: Blob,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n // Convert blob to base64\r\n const arrayBuffer = await audioBlob.arrayBuffer();\r\n const base64 = btoa(\r\n new Uint8Array(arrayBuffer).reduce(\r\n (data, byte) => data + String.fromCharCode(byte),\r\n ''\r\n )\r\n );\r\n\r\n const request: ChatRequest = {\r\n audioBase64: base64,\r\n audioMimeType: audioBlob.type || 'audio/webm',\r\n context,\r\n sessionToken: this.sessionToken || undefined,\r\n };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Create a new chat session\r\n * \r\n * @returns Session information with token\r\n */\r\n async createSession(): Promise<Session> {\r\n const response = await this.request<{ session: Session }>('/api/v1/chat/session', {\r\n method: 'POST',\r\n });\r\n\r\n this.sessionToken = response.session.token;\r\n return response.session;\r\n }\r\n\r\n /**\r\n * Clear the current session\r\n */\r\n clearSession(): void {\r\n this.sessionToken = null;\r\n }\r\n\r\n /**\r\n * Get the current session token\r\n */\r\n getSessionToken(): string | null {\r\n return this.sessionToken;\r\n }\r\n\r\n /**\r\n * Set a session token (for restoring sessions)\r\n */\r\n setSessionToken(token: string): void {\r\n this.sessionToken = token;\r\n }\r\n\r\n // ============================================\r\n // Products API\r\n // ============================================\r\n\r\n /**\r\n * Products API namespace\r\n */\r\n readonly products = {\r\n /**\r\n * Create a new product\r\n */\r\n create: async (product: CreateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify(product),\r\n });\r\n },\r\n\r\n /**\r\n * Batch upsert products (create or update)\r\n */\r\n batchUpsert: async (products: CreateProductInput[]): Promise<BatchUpsertResponse> => {\r\n return this.request<BatchUpsertResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify({ products }),\r\n });\r\n },\r\n\r\n /**\r\n * List products with pagination\r\n */\r\n list: async (options?: ListProductsOptions): Promise<ListProductsResponse> => {\r\n const params = new URLSearchParams();\r\n if (options?.page) params.set('page', String(options.page));\r\n if (options?.perPage) params.set('perPage', String(options.perPage));\r\n if (options?.search) params.set('search', options.search);\r\n if (options?.categoryId) params.set('categoryId', options.categoryId);\r\n if (options?.isActive !== undefined) params.set('isActive', String(options.isActive));\r\n\r\n const query = params.toString();\r\n return this.request<ListProductsResponse>(`/api/v1/products${query ? `?${query}` : ''}`);\r\n },\r\n\r\n /**\r\n * Get a single product by ID\r\n */\r\n get: async (productId: string): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`);\r\n },\r\n\r\n /**\r\n * Update a product\r\n */\r\n update: async (productId: string, data: UpdateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`, {\r\n method: 'PUT',\r\n body: JSON.stringify(data),\r\n });\r\n },\r\n\r\n /**\r\n * Delete a product\r\n */\r\n delete: async (productId: string): Promise<{ success: boolean; deleted: boolean }> => {\r\n return this.request<{ success: boolean; deleted: boolean }>(`/api/v1/products/${productId}`, {\r\n method: 'DELETE',\r\n });\r\n },\r\n };\r\n\r\n // ============================================\r\n // Upload API\r\n // ============================================\r\n\r\n /**\r\n * Upload an image file\r\n * \r\n * @example\r\n * ```typescript\r\n * // Upload from File input\r\n * const file = document.querySelector('input[type=\"file\"]').files[0];\r\n * const result = await client.upload(file);\r\n * console.log(result.url);\r\n * \r\n * // Upload and associate with product\r\n * const result = await client.upload(file, { productId: 'prod_123', isPrimary: true });\r\n * ```\r\n */\r\n async upload(file: File | Blob, options?: UploadOptions): Promise<UploadResponse> {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n\r\n if (options?.folder) formData.append('folder', options.folder);\r\n if (options?.productId) formData.append('productId', options.productId);\r\n if (options?.isPrimary) formData.append('isPrimary', 'true');\r\n\r\n const url = `${this.baseUrl}/api/v1/upload`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'X-API-Key': this.apiKey,\r\n },\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n throw new AICommerceError(\r\n errorData.message || errorData.error || `HTTP ${response.status}`,\r\n errorData.code || 'UPLOAD_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n /**\r\n * Static method for one-off chat requests\r\n * \r\n * @example\r\n * ```typescript\r\n * const response = await AICommerce.quickChat({\r\n * apiKey: 'your-api-key',\r\n * message: 'I need a laptop'\r\n * });\r\n * ```\r\n */\r\n static async quickChat(options: {\r\n apiKey: string;\r\n message: string;\r\n baseUrl?: string;\r\n context?: ChatContext;\r\n }): Promise<ChatResponse> {\r\n const client = new AICommerce({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl,\r\n });\r\n return client.chat(options.message, options.context);\r\n }\r\n}\r\n\r\n// ============================================\r\n// Product Types\r\n// ============================================\r\n\r\nexport interface CreateProductInput {\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n sku?: string;\r\n barcode?: string;\r\n price: number;\r\n compareAtPrice?: number;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string;\r\n externalId?: string;\r\n variantId?: string; // Shopify variant ID for add-to-cart\r\n categoryId?: string;\r\n images?: Array<{ url: string; alt?: string; isPrimary?: boolean }>;\r\n}\r\n\r\nexport interface UpdateProductInput {\r\n name?: string;\r\n slug?: string;\r\n description?: string | null;\r\n sku?: string | null;\r\n barcode?: string | null;\r\n price?: number;\r\n compareAtPrice?: number | null;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string | null;\r\n variantId?: string | null; // Shopify variant ID for add-to-cart\r\n categoryId?: string | null;\r\n}\r\n\r\nexport interface ProductResponse {\r\n success: boolean;\r\n product: Product;\r\n}\r\n\r\nexport interface BatchUpsertResponse {\r\n success: boolean;\r\n processed: number;\r\n errors: number;\r\n results: Array<{ id: string; slug: string; status: 'created' | 'updated' }>;\r\n errorDetails?: Array<{ slug: string; error: string }>;\r\n}\r\n\r\nexport interface ListProductsOptions {\r\n page?: number;\r\n perPage?: number;\r\n search?: string;\r\n categoryId?: string;\r\n isActive?: boolean;\r\n}\r\n\r\nexport interface ListProductsResponse {\r\n success: boolean;\r\n data: Product[];\r\n total: number;\r\n page: number;\r\n perPage: number;\r\n totalPages: number;\r\n}\r\n\r\nexport interface UploadOptions {\r\n folder?: string;\r\n productId?: string;\r\n isPrimary?: boolean;\r\n}\r\n\r\nexport interface UploadResponse {\r\n success: boolean;\r\n url: string;\r\n key: string;\r\n size: number;\r\n contentType: string;\r\n productImage?: {\r\n id: string;\r\n url: string;\r\n alt: string | null;\r\n isPrimary: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Custom error class for AI Commerce SDK\r\n */\r\nexport class AICommerceError extends Error {\r\n readonly code: string;\r\n readonly status: number;\r\n\r\n constructor(message: string, code: string, status: number) {\r\n super(message);\r\n this.name = 'AICommerceError';\r\n this.code = code;\r\n this.status = status;\r\n\r\n // Maintain proper prototype chain\r\n Object.setPrototypeOf(this, AICommerceError.prototype);\r\n }\r\n}\r\n","/**\r\n * Widget Styles (CSS-in-JS)\r\n * \r\n * Generates scoped CSS for the AI Commerce widget\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport type { WidgetConfig } from './types';\r\n\r\ntype ResolvedConfig = Required<Omit<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>> & Pick<WidgetConfig, 'storeId' | 'container'>;\r\n\r\n/**\r\n * Convert hex to RGB\r\n */\r\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : { r: 99, g: 102, b: 241 }; // Default indigo\r\n}\r\n\r\n/**\r\n * Create widget styles\r\n */\r\nexport function createWidgetStyles(config: ResolvedConfig): string {\r\n const primary = config.primaryColor;\r\n const rgb = hexToRgb(primary);\r\n const isLeft = config.position === 'bottom-left';\r\n\r\n return `\r\n/* AI Commerce Widget Styles */\r\n#aicommerce-widget {\r\n --aic-primary: ${primary};\r\n --aic-primary-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};\r\n --aic-primary-light: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.1);\r\n --aic-primary-dark: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.9);\r\n --aic-bg: #ffffff;\r\n --aic-bg-secondary: #f8fafc;\r\n --aic-text: #1e293b;\r\n --aic-text-secondary: #64748b;\r\n --aic-border: #e2e8f0;\r\n --aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\r\n --aic-radius: 16px;\r\n --aic-z-index: ${config.zIndex};\r\n \r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n position: fixed;\r\n bottom: 20px;\r\n ${isLeft ? 'left: 20px;' : 'right: 20px;'}\r\n z-index: var(--aic-z-index);\r\n}\r\n\r\n/* Dark theme */\r\n#aicommerce-widget.aicommerce-theme-dark,\r\n@media (prefers-color-scheme: dark) {\r\n #aicommerce-widget.aicommerce-theme-auto {\r\n --aic-bg: #1e293b;\r\n --aic-bg-secondary: #0f172a;\r\n --aic-text: #f1f5f9;\r\n --aic-text-secondary: #94a3b8;\r\n --aic-border: #334155;\r\n }\r\n}\r\n\r\n/* Launcher Button */\r\n.aicommerce-launcher {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n border: none;\r\n cursor: pointer;\r\n box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n animation: aic-pulse 2s infinite;\r\n}\r\n\r\n.aicommerce-launcher:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 30px rgba(var(--aic-primary-rgb), 0.5);\r\n}\r\n\r\n.aicommerce-launcher-icon {\r\n font-size: 24px;\r\n}\r\n\r\n.aicommerce-hidden {\r\n display: none !important;\r\n}\r\n\r\n@keyframes aic-pulse {\r\n 0%, 100% { box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4); }\r\n 50% { box-shadow: 0 4px 30px rgba(var(--aic-primary-rgb), 0.6); }\r\n}\r\n\r\n/* Chat Window */\r\n.aicommerce-chat {\r\n position: absolute;\r\n bottom: 0;\r\n ${isLeft ? 'left: 0;' : 'right: 0;'}\r\n width: 380px;\r\n max-width: calc(100vw - 40px);\r\n height: 600px;\r\n max-height: calc(100vh - 100px);\r\n background: var(--aic-bg);\r\n border-radius: var(--aic-radius);\r\n box-shadow: var(--aic-shadow);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n transform-origin: bottom ${isLeft ? 'left' : 'right'};\r\n}\r\n\r\n.aicommerce-chat.aicommerce-closed {\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n}\r\n\r\n.aicommerce-chat.aicommerce-open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n}\r\n\r\n/* Header */\r\n.aicommerce-header {\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n color: white;\r\n padding: 16px 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n}\r\n\r\n.aicommerce-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 20px;\r\n overflow: hidden;\r\n}\r\n\r\n.aicommerce-avatar img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-header-text {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.aicommerce-bot-name {\r\n font-weight: 600;\r\n font-size: 16px;\r\n}\r\n\r\n.aicommerce-status {\r\n font-size: 12px;\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-close {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n transition: background 0.2s;\r\n}\r\n\r\n.aicommerce-close:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Messages */\r\n.aicommerce-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n background: var(--aic-bg-secondary);\r\n}\r\n\r\n.aicommerce-message {\r\n max-width: 85%;\r\n animation: aic-slide-in 0.3s ease-out;\r\n}\r\n\r\n.aicommerce-message.aicommerce-user {\r\n align-self: flex-end;\r\n}\r\n\r\n.aicommerce-message.aicommerce-assistant {\r\n align-self: flex-start;\r\n}\r\n\r\n.aicommerce-message-content {\r\n padding: 12px 16px;\r\n border-radius: 16px;\r\n line-height: 1.5;\r\n}\r\n\r\n.aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.aicommerce-assistant .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n color: var(--aic-text);\r\n border-bottom-left-radius: 4px;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n@keyframes aic-slide-in {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n\r\n/* Typing Indicator */\r\n.aicommerce-typing {\r\n display: flex;\r\n gap: 4px;\r\n padding: 12px 16px;\r\n background: var(--aic-bg);\r\n border-radius: 16px;\r\n width: fit-content;\r\n}\r\n\r\n.aicommerce-typing span {\r\n width: 8px;\r\n height: 8px;\r\n background: var(--aic-text-secondary);\r\n border-radius: 50%;\r\n animation: aic-bounce 1.4s infinite ease-in-out;\r\n}\r\n\r\n.aicommerce-typing span:nth-child(1) { animation-delay: -0.32s; }\r\n.aicommerce-typing span:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes aic-bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}\r\n\r\n/* Product Cards */\r\n.aicommerce-products {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 12px;\r\n overflow-x: auto;\r\n padding-bottom: 16px;\r\n width: 100%;\r\n max-width: 100%;\r\n cursor: grab;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n scrollbar-width: none; /* Firefox */\r\n}\r\n.aicommerce-products::-webkit-scrollbar {\r\n display: none; /* Chrome/Safari */\r\n}\r\n\r\n.aicommerce-product-card {\r\n flex-shrink: 0;\r\n width: 280px;\r\n background: var(--aic-bg);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.aicommerce-product-card:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\r\n}\r\n\r\n.aicommerce-product-image {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-product-placeholder {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n background: var(--aic-bg-secondary);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 32px;\r\n}\r\n\r\n.aicommerce-product-info {\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.aicommerce-product-name {\r\n font-weight: 500;\r\n font-size: 13px;\r\n color: var(--aic-text);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.aicommerce-product-price {\r\n font-weight: 600;\r\n font-size: 14px;\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-product-desc {\r\n font-size: 12px;\r\n color: var(--aic-text-secondary);\r\n line-height: 1.4;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n margin-top: 4px;\r\n}\r\n\r\n/* Audio Player */\r\n.aicommerce-audio-player {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n min-width: 240px;\r\n padding: 4px 0;\r\n}\r\n\r\n.aicommerce-audio-btn {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n background: rgba(255, 255, 255, 0.25);\r\n color: white;\r\n flex-shrink: 0;\r\n padding: 0;\r\n}\r\n\r\n.aicommerce-audio-btn:hover {\r\n background: rgba(255, 255, 255, 0.35);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-audio-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n/* Invert colors for assistant (since background is white/gray) */\r\n.aicommerce-assistant .aicommerce-audio-btn {\r\n background: var(--aic-primary);\r\n color: white;\r\n}\r\n.aicommerce-assistant .aicommerce-audio-btn:hover {\r\n background: var(--aic-primary-dark);\r\n}\r\n\r\n.aicommerce-audio-waveform {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n min-width: 0; /* Prevent overflow */\r\n}\r\n\r\n.aicommerce-waveform-bars {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n height: 24px;\r\n cursor: pointer;\r\n width: 100%;\r\n}\r\n\r\n.aicommerce-waveform-bar {\r\n width: 3px;\r\n border-radius: 2px;\r\n min-height: 3px;\r\n transition: background-color 0.1s;\r\n flex-shrink: 0;\r\n}\r\n\r\n.aicommerce-audio-time {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 11px;\r\n font-weight: 500;\r\n}\r\n\r\n.aicommerce-user .aicommerce-audio-time {\r\n color: rgba(255, 255, 255, 0.8);\r\n}\r\n.aicommerce-assistant .aicommerce-audio-time {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* RTL Support */\r\n.aicommerce-rtl {\r\n direction: rtl;\r\n text-align: right;\r\n}\r\n.aicommerce-ltr {\r\n direction: ltr;\r\n text-align: left;\r\n}\r\n\r\n/* Input Area */\r\n.aicommerce-input-container {\r\n padding: 16px 20px;\r\n background: var(--aic-bg);\r\n border-top: 1px solid var(--aic-border);\r\n display: flex;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-input {\r\n flex: 1;\r\n padding: 12px 16px;\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n background: var(--aic-bg-secondary);\r\n color: var(--aic-text);\r\n font-size: 14px;\r\n outline: none;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-input:focus {\r\n border-color: var(--aic-primary);\r\n box-shadow: 0 0 0 3px var(--aic-primary-light);\r\n}\r\n\r\n.aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-send {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-send:hover:not(:disabled) {\r\n background: var(--aic-primary-dark);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-send:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n/* Microphone Button */\r\n.aicommerce-mic {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-bg-secondary);\r\n border: 1px solid var(--aic-border);\r\n color: var(--aic-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-mic:hover:not(:disabled) {\r\n background: var(--aic-primary-light);\r\n border-color: var(--aic-primary);\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-mic.aicommerce-recording {\r\n background: #ef4444;\r\n border-color: #ef4444;\r\n color: white;\r\n animation: aic-recording-pulse 1s infinite;\r\n}\r\n\r\n.aicommerce-mic:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n@keyframes aic-recording-pulse {\r\n 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }\r\n 50% { transform: scale(1.05); box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }\r\n}\r\n\r\n/* Mobile Responsive */\r\n@media (max-width: 420px) {\r\n #aicommerce-widget {\r\n bottom: 16px;\r\n ${isLeft ? 'left: 16px;' : 'right: 16px;'}\r\n }\r\n \r\n .aicommerce-chat {\r\n width: calc(100vw - 32px);\r\n height: calc(100vh - 100px);\r\n border-radius: 12px;\r\n }\r\n \r\n .aicommerce-launcher {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n}\r\n\r\n/* Scrollbar */\r\n.aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb {\r\n background: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background: var(--aic-text-secondary);\r\n}\r\n\r\n/* ============================================\r\n Embedded Mode Styles - ChatGPT Style\r\n ============================================ */\r\n\r\n/* Embedded container - starts small, grows to max-height, then scrolls */\r\n#aicommerce-widget.aicommerce-embedded {\r\n position: relative;\r\n bottom: auto;\r\n left: auto;\r\n right: auto;\r\n width: 100%;\r\n height: auto;\r\n min-height: 80px;\r\n max-height: var(--aic-max-height, 600px);\r\n display: flex;\r\n flex-direction: column;\r\n background: transparent;\r\n}\r\n\r\n/* Embedded mode: hide launcher button */\r\n.aicommerce-embedded .aicommerce-launcher {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: hide the header completely */\r\n.aicommerce-embedded .aicommerce-header {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: hide close button */\r\n.aicommerce-embedded .aicommerce-close {\r\n display: none !important;\r\n}\r\n\r\n/* Embedded mode: chat container grows with content */\r\n.aicommerce-embedded .aicommerce-chat {\r\n position: relative;\r\n width: 100%;\r\n height: auto;\r\n max-height: 100%;\r\n max-width: 100%;\r\n border-radius: 0;\r\n background: transparent;\r\n box-shadow: none;\r\n transform: none !important;\r\n opacity: 1 !important;\r\n pointer-events: auto !important;\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n/* Embedded mode: no open/close animations */\r\n.aicommerce-embedded .aicommerce-chat.aicommerce-closed {\r\n opacity: 1 !important;\r\n transform: none !important;\r\n pointer-events: auto !important;\r\n}\r\n\r\n/* Embedded mode: messages area - scrollable when content overflows */\r\n.aicommerce-embedded .aicommerce-messages {\r\n flex: 1 1 auto;\r\n min-height: 0;\r\n max-height: calc(var(--aic-max-height, 600px) - 100px);\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-start;\r\n overflow-y: auto;\r\n padding: 16px;\r\n max-width: 700px;\r\n margin: 0 auto;\r\n width: 100%;\r\n background: transparent;\r\n gap: 12px;\r\n scrollbar-width: thin;\r\n scrollbar-color: var(--aic-border) transparent;\r\n}\r\n\r\n/* Embedded mode: custom scrollbar for webkit browsers */\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb {\r\n background-color: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background-color: var(--aic-text-secondary);\r\n}\r\n\r\n/* Embedded mode: messages have different styling */\r\n.aicommerce-embedded .aicommerce-message {\r\n max-width: 100%;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-color: var(--aic-primary);\r\n}\r\n\r\n/* Embedded mode: input container wrapper - always at bottom */\r\n.aicommerce-embedded .aicommerce-input-wrapper {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n padding: 16px;\r\n flex-shrink: 0;\r\n}\r\n\r\n/* Embedded mode: input container styled like ChatGPT */\r\n.aicommerce-embedded .aicommerce-input-container {\r\n width: 100%;\r\n max-width: 700px;\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n padding: 8px 12px;\r\n display: flex;\r\n align-items: flex-end;\r\n gap: 8px;\r\n}\r\n\r\n/* Embedded mode: textarea field styling - auto-grow */\r\n.aicommerce-embedded .aicommerce-input {\r\n flex: 1;\r\n min-width: 0;\r\n border: none;\r\n background: transparent;\r\n padding: 8px 4px;\r\n font-size: 16px;\r\n font-family: inherit;\r\n color: var(--aic-text);\r\n outline: none;\r\n resize: none;\r\n min-height: 24px;\r\n max-height: 150px;\r\n line-height: 1.5;\r\n overflow-y: auto;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* Embedded mode: buttons styling - smaller, no overflow */\r\n.aicommerce-embedded .aicommerce-mic,\r\n.aicommerce-embedded .aicommerce-send {\r\n flex-shrink: 0;\r\n width: 36px;\r\n height: 36px;\r\n min-width: 36px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n color: white;\r\n border: none;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic:hover,\r\n.aicommerce-embedded .aicommerce-send:hover {\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic {\r\n background: transparent;\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-mic:hover {\r\n background: rgba(0, 0, 0, 0.05);\r\n color: var(--aic-text);\r\n}\r\n\r\n/* Embedded mode: product cards styling - horizontal scroll like widget mode */\r\n.aicommerce-embedded .aicommerce-products {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n gap: 12px;\r\n margin-top: 12px;\r\n overflow-x: auto;\r\n padding-bottom: 8px;\r\n cursor: grab;\r\n scrollbar-width: none;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-products::-webkit-scrollbar {\r\n display: none;\r\n}\r\n\r\n.aicommerce-embedded .aicommerce-product-card {\r\n flex-shrink: 0;\r\n width: 180px;\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n}\r\n\r\n/* Embedded mode: typing indicator */\r\n.aicommerce-embedded .aicommerce-typing {\r\n background: var(--aic-bg);\r\n border: 1px solid var(--aic-border);\r\n border-radius: 12px;\r\n padding: 12px 16px;\r\n}\r\n\r\n/* Embedded mode responsive - mobile fixes */\r\n@media (max-width: 640px) {\r\n .aicommerce-embedded .aicommerce-input-container {\r\n padding: 6px 10px;\r\n gap: 6px;\r\n border-radius: 20px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-mic,\r\n .aicommerce-embedded .aicommerce-send {\r\n width: 32px;\r\n height: 32px;\r\n min-width: 32px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-mic svg,\r\n .aicommerce-embedded .aicommerce-send svg {\r\n width: 16px;\r\n height: 16px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-input {\r\n font-size: 16px;\r\n padding: 6px 4px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-messages {\r\n padding: 12px;\r\n }\r\n \r\n .aicommerce-embedded .aicommerce-input-wrapper {\r\n padding: 12px;\r\n }\r\n}\r\n\r\n/* ============================================\r\n Add to Cart Button Styles\r\n ============================================ */\r\n\r\n.aicommerce-add-to-cart {\r\n width: 100%;\r\n padding: 8px 12px;\r\n background: var(--aic-primary);\r\n color: white;\r\n border: none;\r\n border-radius: 6px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n margin-top: 8px;\r\n transition: all 0.2s;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n}\r\n\r\n.aicommerce-add-to-cart:hover {\r\n opacity: 0.9;\r\n transform: translateY(-1px);\r\n}\r\n\r\n.aicommerce-add-to-cart:active {\r\n transform: translateY(0);\r\n}\r\n\r\n.aicommerce-add-to-cart:disabled {\r\n opacity: 0.7;\r\n cursor: not-allowed;\r\n transform: none;\r\n}\r\n\r\n.aicommerce-add-to-cart svg {\r\n flex-shrink: 0;\r\n}\r\n\r\n/* Spinner animation for loading state */\r\n@keyframes aicommerce-spin {\r\n to { transform: rotate(360deg); }\r\n}\r\n\r\n.aicommerce-spinner {\r\n animation: aicommerce-spin 1s linear infinite;\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Inject styles into the document\r\n */\r\nexport function injectStyles(css: string): HTMLStyleElement {\r\n const style = document.createElement('style');\r\n style.id = 'aicommerce-widget-styles';\r\n style.textContent = css;\r\n\r\n // Remove existing styles\r\n const existing = document.getElementById('aicommerce-widget-styles');\r\n if (existing) {\r\n existing.remove();\r\n }\r\n\r\n document.head.appendChild(style);\r\n return style;\r\n}\r\n","/**\r\n * AI Commerce Chat Widget\r\n * \r\n * Embeddable chat widget for e-commerce stores\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport { AICommerce } from './client';\r\nimport type {\r\n WidgetConfig,\r\n WidgetInstance,\r\n WidgetDisplayMode,\r\n StoreConfig,\r\n Product,\r\n ChatResponse\r\n} from './types';\r\nimport { createWidgetStyles, injectStyles } from './widget-styles';\r\n\r\n// Widget state\r\ninterface WidgetState {\r\n isOpen: boolean;\r\n isLoading: boolean;\r\n isRecording: boolean;\r\n messages: Array<{\r\n role: 'user' | 'assistant';\r\n content: string;\r\n products?: Product[];\r\n audioUrl?: string; // Voice message URL\r\n audioDuration?: number;\r\n waveformBars?: number[];\r\n }>;\r\n storeConfig: StoreConfig | null;\r\n}\r\n\r\n/**\r\n * Create and initialize the AI Commerce chat widget\r\n */\r\nexport function createWidget(config: WidgetConfig): WidgetInstance {\r\n // Validate config\r\n if (!config.apiKey) {\r\n throw new Error('AICommerceWidget: apiKey is required');\r\n }\r\n\r\n // Initialize client\r\n const client = new AICommerce({\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl,\r\n });\r\n\r\n // Widget state\r\n const state: WidgetState = {\r\n isOpen: false,\r\n isLoading: true,\r\n isRecording: false,\r\n messages: [],\r\n storeConfig: null,\r\n };\r\n\r\n // Audio recording state\r\n let mediaRecorder: MediaRecorder | null = null;\r\n let audioChunks: Blob[] = [];\r\n\r\n // DOM elements\r\n let container: HTMLDivElement | null = null;\r\n let launcher: HTMLButtonElement | null = null;\r\n let chatWindow: HTMLDivElement | null = null;\r\n let styleElement: HTMLStyleElement | null = null;\r\n\r\n // Resolved config (merged with store config)\r\n let resolvedConfig: Required<Omit<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>> &\r\n Pick<WidgetConfig, 'storeId' | 'container' | 'onOpen' | 'onClose' | 'onProductClick' | 'onAddToCart' | 'onMessage' | 'addToCartText'>;\r\n\r\n /**\r\n * Fetch store configuration\r\n */\r\n async function fetchStoreConfig(): Promise<StoreConfig | null> {\r\n try {\r\n const baseUrl = config.baseUrl || detectBaseUrl();\r\n const response = await fetch(`${baseUrl}/api/v1/store`, {\r\n headers: { 'x-api-key': config.apiKey },\r\n });\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data.store;\r\n } catch (error) {\r\n console.error('Failed to fetch store config:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Detect base URL\r\n */\r\n function detectBaseUrl(): string {\r\n if (typeof window !== 'undefined') {\r\n // Check for data attribute on script tag\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || '';\r\n }\r\n }\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Initialize the widget\r\n */\r\n async function initialize(): Promise<void> {\r\n // Fetch store config\r\n state.storeConfig = await fetchStoreConfig();\r\n\r\n // Determine display mode\r\n const displayMode: WidgetDisplayMode = config.displayMode || 'widget';\r\n const isEmbedded = displayMode === 'embedded';\r\n\r\n // Merge configs\r\n resolvedConfig = {\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl || detectBaseUrl(),\r\n displayMode: displayMode,\r\n container: config.container,\r\n maxHeight: config.maxHeight || '600px',\r\n placeholder: config.placeholder || 'Ask me anything about our products...',\r\n position: config.position || 'bottom-right',\r\n theme: config.theme || 'auto',\r\n primaryColor: config.primaryColor || state.storeConfig?.primaryColor || '#6366f1',\r\n welcomeMessage: config.welcomeMessage || state.storeConfig?.welcomeMessage || 'Hi! How can I help you find the perfect product today?',\r\n botName: config.botName || state.storeConfig?.chatBotName || 'Shopping Assistant',\r\n zIndex: config.zIndex || 9999,\r\n buttonText: config.buttonText || '💬',\r\n hideLauncher: config.hideLauncher || false,\r\n addToCartText: config.addToCartText,\r\n onOpen: config.onOpen,\r\n onClose: config.onClose,\r\n onProductClick: config.onProductClick,\r\n onAddToCart: config.onAddToCart,\r\n onMessage: config.onMessage,\r\n };\r\n\r\n // Inject styles\r\n const styles = createWidgetStyles(resolvedConfig);\r\n styleElement = injectStyles(styles);\r\n\r\n // Create or use container based on display mode\r\n if (isEmbedded) {\r\n // Embedded mode: render into provided container\r\n let targetContainer: HTMLElement | null = null;\r\n\r\n if (typeof config.container === 'string') {\r\n targetContainer = document.querySelector(config.container);\r\n } else if (config.container instanceof HTMLElement) {\r\n targetContainer = config.container;\r\n }\r\n\r\n if (!targetContainer) {\r\n console.error('[AI Commerce] Embedded mode requires a valid container element or selector');\r\n return;\r\n }\r\n\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-embedded aicommerce-theme-${resolvedConfig.theme}`;\r\n container.style.setProperty('--aic-max-height', resolvedConfig.maxHeight);\r\n\r\n targetContainer.appendChild(container);\r\n\r\n // In embedded mode, chat is always open\r\n state.isOpen = true;\r\n } else {\r\n // Widget mode: append to body with fixed positioning\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;\r\n document.body.appendChild(container);\r\n }\r\n\r\n // Render widget\r\n render();\r\n\r\n // For widget mode, add welcome message. For embedded mode, start empty (ChatGPT style)\r\n if (!isEmbedded) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: resolvedConfig.welcomeMessage,\r\n });\r\n }\r\n state.isLoading = false;\r\n render();\r\n }\r\n\r\n /**\r\n * Add product to Shopify cart using Ajax Cart API\r\n */\r\n async function addToShopifyCart(variantId: string, quantity: number = 1): Promise<void> {\r\n // Extract numeric ID from GraphQL ID format (gid://shopify/ProductVariant/12345)\r\n let numericVariantId = variantId;\r\n if (variantId.includes('gid://')) {\r\n const match = variantId.match(/\\/(\\d+)$/);\r\n if (match) {\r\n numericVariantId = match[1];\r\n }\r\n }\r\n\r\n const response = await fetch('/cart/add.js', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n id: numericVariantId,\r\n quantity: quantity,\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error('Failed to add to cart');\r\n }\r\n\r\n // Trigger cart update event for Shopify themes\r\n document.dispatchEvent(new CustomEvent('cart:refresh'));\r\n }\r\n\r\n /**\r\n * Render the widget\r\n */\r\n function render(): void {\r\n if (!container) return;\r\n\r\n const isEmbedded = resolvedConfig.displayMode === 'embedded';\r\n const hasUserMessages = state.messages.some(m => m.role === 'user');\r\n\r\n // Update container class for embedded mode based on message state\r\n if (isEmbedded) {\r\n container.classList.remove('aicommerce-no-messages', 'aicommerce-has-messages');\r\n container.classList.add(hasUserMessages ? 'aicommerce-has-messages' : 'aicommerce-no-messages');\r\n }\r\n\r\n const placeholder = resolvedConfig.placeholder || 'Ask me anything about our products...';\r\n\r\n // Generate input container HTML - use textarea for embedded mode for auto-grow\r\n const inputContainerHtml = `\r\n <div class=\"aicommerce-input-container\">\r\n ${isEmbedded ? `\r\n <textarea \r\n class=\"aicommerce-input\" \r\n placeholder=\"${placeholder}\"\r\n rows=\"1\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n ></textarea>\r\n ` : `\r\n <input \r\n type=\"text\" \r\n class=\"aicommerce-input\" \r\n placeholder=\"${placeholder}\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n />\r\n `}\r\n <button class=\"aicommerce-mic ${state.isRecording ? 'aicommerce-recording' : ''}\" ${state.isLoading ? 'disabled' : ''} aria-label=\"${state.isRecording ? 'Stop recording' : 'Voice input'}\">\r\n ${state.isRecording ? `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/>\r\n </svg>\r\n ` : `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\r\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>\r\n </svg>\r\n `}\r\n </button>\r\n <button class=\"aicommerce-send\" ${state.isLoading || state.isRecording ? 'disabled' : ''} aria-label=\"Send message\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n `;\r\n\r\n const html = `\r\n ${!isEmbedded && !resolvedConfig.hideLauncher ? `\r\n <button class=\"aicommerce-launcher ${state.isOpen ? 'aicommerce-hidden' : ''}\" aria-label=\"Open chat\">\r\n <span class=\"aicommerce-launcher-icon\">${resolvedConfig.buttonText}</span>\r\n </button>\r\n ` : ''}\r\n \r\n <div class=\"aicommerce-chat ${state.isOpen ? 'aicommerce-open' : 'aicommerce-closed'}\">\r\n ${!isEmbedded ? `\r\n <div class=\"aicommerce-header\">\r\n <div class=\"aicommerce-header-info\">\r\n <div class=\"aicommerce-avatar\">\r\n ${state.storeConfig?.logo\r\n ? `<img src=\"${state.storeConfig.logo}\" alt=\"${resolvedConfig.botName}\" />`\r\n : `<span>🤖</span>`\r\n }\r\n </div>\r\n <div class=\"aicommerce-header-text\">\r\n <span class=\"aicommerce-bot-name\">${resolvedConfig.botName}</span>\r\n <span class=\"aicommerce-status\">Online</span>\r\n </div>\r\n </div>\r\n <button class=\"aicommerce-close\" aria-label=\"Close chat\">✕</button>\r\n </div>\r\n ` : ''}\r\n \r\n ${isEmbedded && hasUserMessages ? `\r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\" data-variant-id=\"${product.variantId || ''}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n <button class=\"aicommerce-add-to-cart\" data-product-id=\"${product.id}\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <circle cx=\"9\" cy=\"21\" r=\"1\"/><circle cx=\"20\" cy=\"21\" r=\"1\"/>\r\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"/>\r\n </svg>\r\n ${resolvedConfig.addToCartText || 'Add to Cart'}\r\n </button>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n ` : ''}\r\n \r\n ${!isEmbedded ? `\r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\" data-variant-id=\"${product.variantId || ''}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n <button class=\"aicommerce-add-to-cart\" data-product-id=\"${product.id}\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <circle cx=\"9\" cy=\"21\" r=\"1\"/><circle cx=\"20\" cy=\"21\" r=\"1\"/>\r\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"/>\r\n </svg>\r\n ${resolvedConfig.addToCartText || 'Add to Cart'}\r\n </button>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n ` : ''}\r\n \r\n ${isEmbedded ? `\r\n <div class=\"aicommerce-input-wrapper\">\r\n ${inputContainerHtml}\r\n </div>\r\n ` : inputContainerHtml}\r\n </div>\r\n `;\r\n\r\n container.innerHTML = html;\r\n\r\n // Attach event listeners\r\n attachEventListeners();\r\n\r\n // Scroll to bottom\r\n const messagesEl = container.querySelector('.aicommerce-messages');\r\n if (messagesEl) {\r\n messagesEl.scrollTop = messagesEl.scrollHeight;\r\n }\r\n }\r\n\r\n function renderAudioPlayer(msg: any, index: number, isUser: boolean): string {\r\n return `\r\n <div class=\"aicommerce-audio-player\" data-message-index=\"${index}\">\r\n <button class=\"aicommerce-audio-btn\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>\r\n </button>\r\n <div class=\"aicommerce-audio-waveform\">\r\n <div class=\"aicommerce-waveform-bars\">\r\n ${(msg.waveformBars || Array(40).fill(10)).map((height: number) => `\r\n <div class=\"aicommerce-waveform-bar\" style=\"height: ${height}%; background-color: ${isUser ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)'}\"></div>\r\n `).join('')}\r\n </div>\r\n <div class=\"aicommerce-audio-time\">\r\n <span class=\"aicommerce-current-time\">0:00</span>\r\n <span>${formatTime(msg.audioDuration || 0)}</span>\r\n </div>\r\n </div>\r\n <audio src=\"${msg.audioUrl}\" preload=\"metadata\"></audio>\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Attach event listeners\r\n */\r\n function attachEventListeners(): void {\r\n if (!container) return;\r\n\r\n // Launcher click\r\n const launcherEl = container.querySelector('.aicommerce-launcher');\r\n if (launcherEl) {\r\n launcherEl.addEventListener('click', () => open());\r\n }\r\n\r\n // Close button\r\n const closeEl = container.querySelector('.aicommerce-close');\r\n if (closeEl) {\r\n closeEl.addEventListener('click', () => close());\r\n }\r\n\r\n // Input\r\n const inputEl = container.querySelector('.aicommerce-input') as HTMLInputElement | HTMLTextAreaElement;\r\n const sendEl = container.querySelector('.aicommerce-send');\r\n\r\n if (inputEl) {\r\n // Handle Enter key - for textarea, Shift+Enter adds newline, Enter alone sends\r\n inputEl.addEventListener('keydown', (e: Event) => {\r\n const keyEvent = e as KeyboardEvent;\r\n if (keyEvent.key === 'Enter') {\r\n const isTextarea = inputEl instanceof HTMLTextAreaElement;\r\n // For textarea: Shift+Enter = newline, Enter = send\r\n // For input: Enter = send\r\n if (isTextarea && keyEvent.shiftKey) {\r\n // Allow default behavior (new line)\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n const value = inputEl.value.trim();\r\n if (value) {\r\n handleSend(value);\r\n inputEl.value = '';\r\n // Reset textarea height after sending\r\n if (isTextarea) {\r\n inputEl.style.height = 'auto';\r\n }\r\n }\r\n }\r\n });\r\n\r\n // Auto-grow for textarea\r\n if (inputEl instanceof HTMLTextAreaElement) {\r\n inputEl.addEventListener('input', () => {\r\n inputEl.style.height = 'auto';\r\n inputEl.style.height = Math.min(inputEl.scrollHeight, 150) + 'px';\r\n });\r\n }\r\n }\r\n\r\n if (sendEl && inputEl) {\r\n sendEl.addEventListener('click', () => {\r\n const value = inputEl.value.trim();\r\n if (value) {\r\n handleSend(value);\r\n inputEl.value = '';\r\n // Reset textarea height after sending\r\n if (inputEl instanceof HTMLTextAreaElement) {\r\n inputEl.style.height = 'auto';\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Microphone button\r\n const micEl = container.querySelector('.aicommerce-mic');\r\n if (micEl) {\r\n micEl.addEventListener('click', () => handleMicClick());\r\n }\r\n\r\n // Product clicks\r\n const productCards = container.querySelectorAll('.aicommerce-product-card');\r\n productCards.forEach(card => {\r\n card.addEventListener('click', (e) => {\r\n // Don't trigger if clicking add to cart button\r\n if ((e.target as Element).closest('.aicommerce-add-to-cart')) return;\r\n\r\n const productId = card.getAttribute('data-product-id');\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (product) {\r\n if (resolvedConfig.onProductClick) {\r\n resolvedConfig.onProductClick(product);\r\n } else if (product.url) {\r\n // Default behavior: open product URL in new tab\r\n window.open(product.url, '_blank', 'noopener,noreferrer');\r\n }\r\n }\r\n });\r\n });\r\n\r\n // Add to Cart buttons\r\n const addToCartBtns = container.querySelectorAll('.aicommerce-add-to-cart');\r\n addToCartBtns.forEach(btn => {\r\n btn.addEventListener('click', async (e) => {\r\n e.stopPropagation(); // Prevent product card click\r\n\r\n const button = btn as HTMLButtonElement;\r\n const productCard = button.closest('.aicommerce-product-card');\r\n const productId = productCard?.getAttribute('data-product-id');\r\n const variantId = productCard?.getAttribute('data-variant-id');\r\n\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (!product) return;\r\n\r\n // Show loading state\r\n const originalText = button.innerHTML;\r\n button.disabled = true;\r\n button.innerHTML = `\r\n <svg class=\"aicommerce-spinner\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-dasharray=\"32\" stroke-dashoffset=\"32\"/>\r\n </svg>\r\n Adding...\r\n `;\r\n\r\n try {\r\n if (resolvedConfig.onAddToCart) {\r\n // Custom callback\r\n await resolvedConfig.onAddToCart(product);\r\n } else if (variantId && (window as any).Shopify) {\r\n // Shopify Ajax Cart API\r\n await addToShopifyCart(variantId);\r\n } else if (product.url) {\r\n // Fallback: open product page\r\n window.open(product.url, '_blank', 'noopener,noreferrer');\r\n }\r\n\r\n // Success state\r\n button.innerHTML = `\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n Added!\r\n `;\r\n setTimeout(() => {\r\n button.innerHTML = originalText;\r\n button.disabled = false;\r\n }, 2000);\r\n } catch (error) {\r\n console.error('[AI Commerce] Add to cart failed:', error);\r\n button.innerHTML = originalText;\r\n button.disabled = false;\r\n }\r\n });\r\n });\r\n\r\n // Product Sliders (Drag to Scroll)\r\n const sliders = container.querySelectorAll('.aicommerce-products') as NodeListOf<HTMLElement>;\r\n sliders.forEach(slider => {\r\n let isDown = false;\r\n let startX = 0;\r\n let scrollLeft = 0;\r\n\r\n slider.addEventListener('mousedown', (e) => {\r\n isDown = true;\r\n slider.style.cursor = 'grabbing';\r\n startX = e.pageX - slider.offsetLeft;\r\n scrollLeft = slider.scrollLeft;\r\n });\r\n slider.addEventListener('mouseleave', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mouseup', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mousemove', (e) => {\r\n if (!isDown) return;\r\n e.preventDefault();\r\n const x = e.pageX - slider.offsetLeft;\r\n const walk = (x - startX) * 2; // scroll-fast\r\n slider.scrollLeft = scrollLeft - walk;\r\n });\r\n });\r\n\r\n // Audio Players\r\n const audioPlayers = container.querySelectorAll('.aicommerce-audio-player');\r\n audioPlayers.forEach(player => {\r\n const audio = player.querySelector('audio');\r\n const btn = player.querySelector('.aicommerce-audio-btn');\r\n const bars = player.querySelectorAll('.aicommerce-waveform-bar');\r\n const timeDisplay = player.querySelector('.aicommerce-current-time');\r\n\r\n if (!audio || !btn) return;\r\n\r\n // Toggle Play\r\n btn.addEventListener('click', () => {\r\n const isPlaying = !audio.paused;\r\n\r\n if (!isPlaying) {\r\n // Pause all others\r\n container?.querySelectorAll('audio').forEach((a: HTMLAudioElement) => {\r\n if (a !== audio && !a.paused) {\r\n a.pause();\r\n const parent = a.closest('.aicommerce-audio-player');\r\n const otherBtn = parent?.querySelector('.aicommerce-audio-btn');\r\n if (otherBtn) otherBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.play();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect></svg>`;\r\n } else {\r\n audio.pause();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.addEventListener('timeupdate', () => {\r\n if (timeDisplay) timeDisplay.textContent = formatTime(audio.currentTime);\r\n\r\n if (audio.duration) {\r\n const progress = (audio.currentTime / audio.duration) * 100;\r\n bars.forEach((bar, i) => {\r\n const barPos = (i / bars.length) * 100;\r\n if (barPos <= progress) {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,1)' : 'var(--aic-primary)';\r\n } else {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)';\r\n }\r\n });\r\n }\r\n });\r\n\r\n audio.addEventListener('ended', () => {\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n });\r\n\r\n const waveform = player.querySelector('.aicommerce-waveform-bars');\r\n if (waveform) {\r\n waveform.addEventListener('click', (e: any) => {\r\n const rect = waveform.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const percent = x / rect.width;\r\n if (audio.duration) {\r\n audio.currentTime = percent * audio.duration;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handle microphone button click\r\n */\r\n async function handleMicClick(): Promise<void> {\r\n if (state.isRecording) {\r\n // Stop recording\r\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\r\n mediaRecorder.stop();\r\n }\r\n } else {\r\n // Start recording\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\r\n audioChunks = [];\r\n\r\n mediaRecorder = new MediaRecorder(stream, {\r\n mimeType: MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\r\n });\r\n\r\n mediaRecorder.ondataavailable = (e) => {\r\n if (e.data.size > 0) {\r\n audioChunks.push(e.data);\r\n }\r\n };\r\n\r\n mediaRecorder.onstop = async () => {\r\n // Stop all tracks\r\n stream.getTracks().forEach(track => track.stop());\r\n\r\n if (audioChunks.length > 0) {\r\n const audioBlob = new Blob(audioChunks, { type: mediaRecorder?.mimeType || 'audio/webm' });\r\n await handleAudioSend(audioBlob);\r\n }\r\n\r\n state.isRecording = false;\r\n render();\r\n };\r\n\r\n mediaRecorder.start();\r\n state.isRecording = true;\r\n render();\r\n } catch (error) {\r\n console.error('Failed to start recording:', error);\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Unable to access microphone. Please check your permissions.',\r\n });\r\n render();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending audio message\r\n */\r\n async function handleAudioSend(audioBlob: Blob): Promise<ChatResponse> {\r\n // Create audio URL for playback\r\n const audioUrl = URL.createObjectURL(audioBlob);\r\n\r\n // Analyze audio for waveform\r\n let waveformBars: number[] = Array(40).fill(10);\r\n let audioDuration = 0;\r\n\r\n try {\r\n waveformBars = await analyzeAudio(audioBlob);\r\n\r\n // Get duration\r\n const audio = new Audio(audioUrl);\r\n await new Promise<void>((resolve) => {\r\n audio.onloadedmetadata = () => {\r\n audioDuration = audio.duration;\r\n resolve();\r\n };\r\n audio.onerror = () => resolve();\r\n });\r\n } catch (e) {\r\n console.error(\"Audio analysis failed\", e);\r\n }\r\n\r\n // Add user message with audio\r\n state.messages.push({\r\n role: 'user',\r\n content: 'Voice message',\r\n audioUrl,\r\n audioDuration,\r\n waveformBars\r\n });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chatWithAudio(audioBlob);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage('Voice message', response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error processing your voice message. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Helpers\r\n */\r\n function isArabic(text: string): boolean {\r\n return /[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/.test(text);\r\n }\r\n\r\n function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n }\r\n\r\n async function analyzeAudio(blob: Blob): Promise<number[]> {\r\n try {\r\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\r\n const arrayBuffer = await blob.arrayBuffer();\r\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\r\n const channelData = audioBuffer.getChannelData(0);\r\n\r\n const bars = 40;\r\n const step = Math.floor(channelData.length / bars);\r\n const calculatedBars = [];\r\n\r\n for (let i = 0; i < bars; i++) {\r\n const start = i * step;\r\n const end = start + step;\r\n let sum = 0;\r\n for (let j = start; j < end; j++) {\r\n if (channelData[j]) sum += channelData[j] * channelData[j];\r\n }\r\n const rms = Math.sqrt(sum / step);\r\n const height = Math.min(100, Math.max(10, rms * 400));\r\n calculatedBars.push(height);\r\n }\r\n return calculatedBars;\r\n } catch (e) {\r\n console.error(\"Analysis error\", e);\r\n return Array.from({ length: 40 }, () => 20 + Math.random() * 60);\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending a message\r\n */\r\n async function handleSend(message: string): Promise<ChatResponse> {\r\n // Add user message\r\n state.messages.push({ role: 'user', content: message });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chat(message);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage(message, response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Open the widget\r\n */\r\n function open(): void {\r\n state.isOpen = true;\r\n render();\r\n resolvedConfig.onOpen?.();\r\n\r\n // Focus input\r\n setTimeout(() => {\r\n const input = container?.querySelector('.aicommerce-input') as HTMLInputElement;\r\n input?.focus();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the widget\r\n */\r\n function close(): void {\r\n state.isOpen = false;\r\n render();\r\n resolvedConfig.onClose?.();\r\n }\r\n\r\n /**\r\n * Toggle the widget\r\n */\r\n function toggle(): void {\r\n if (state.isOpen) {\r\n close();\r\n } else {\r\n open();\r\n }\r\n }\r\n\r\n /**\r\n * Destroy the widget\r\n */\r\n function destroy(): void {\r\n if (container) {\r\n container.remove();\r\n container = null;\r\n }\r\n if (styleElement) {\r\n styleElement.remove();\r\n styleElement = null;\r\n }\r\n }\r\n\r\n /**\r\n * Update configuration\r\n */\r\n function updateConfig(newConfig: Partial<WidgetConfig>): void {\r\n Object.assign(resolvedConfig, newConfig);\r\n\r\n if (newConfig.primaryColor) {\r\n const styles = createWidgetStyles(resolvedConfig);\r\n if (styleElement) {\r\n styleElement.textContent = styles;\r\n }\r\n }\r\n\r\n render();\r\n }\r\n\r\n // Utility functions\r\n function escapeHtml(text: string): string {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n }\r\n\r\n function formatPrice(price: number, currency?: string): string {\r\n const symbols: Record<string, string> = {\r\n USD: '$', EUR: '€', GBP: '£', MAD: 'DH',\r\n SAR: 'SAR', AED: 'AED', JPY: '¥', CNY: '¥',\r\n };\r\n const symbol = symbols[currency || 'USD'] || currency || '$';\r\n return `${price.toFixed(2)} ${symbol}`;\r\n }\r\n\r\n // Initialize and return instance\r\n initialize();\r\n\r\n return {\r\n open,\r\n close,\r\n toggle,\r\n destroy,\r\n sendMessage: handleSend,\r\n updateConfig,\r\n };\r\n}\r\n\r\n/**\r\n * Global widget initialization for script tag usage\r\n */\r\nexport const AICommerceWidget = {\r\n init: createWidget,\r\n VERSION: '1.0.0',\r\n};\r\n\r\n// Auto-attach to window for UMD builds\r\nif (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).AICommerceWidget = AICommerceWidget;\r\n}\r\n","/**\r\n * AI Commerce SDK\r\n * \r\n * AI-powered product recommendations for e-commerce\r\n * \r\n * @packageDocumentation\r\n * @module @yassirbenmoussa/aicommerce-sdk\r\n * \r\n * @example\r\n * ```typescript\r\n * // npm usage - Client API\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop');\r\n * console.log(response.products);\r\n * ```\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Widget usage -->\r\n * <script src=\"https://cdn.aicommerce.dev/widget.min.js\"></script>\r\n * <script>\r\n * AICommerceWidget.init({\r\n * apiKey: 'your-api-key',\r\n * position: 'bottom-right',\r\n * theme: 'auto'\r\n * });\r\n * </script>\r\n * ```\r\n */\r\n\r\n// Export main client\r\nexport { AICommerce, AICommerceError } from './client';\r\n\r\n// Export widget\r\nexport { createWidget, AICommerceWidget } from './widget';\r\n\r\n// Export all types\r\nexport type {\r\n // Client types\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Product,\r\n Session,\r\n APIError,\r\n EventType,\r\n EventCallback,\r\n // Widget types\r\n StoreConfig,\r\n WidgetConfig,\r\n WidgetInstance,\r\n} from './types';\r\n\r\n// Version\r\nexport const VERSION = '1.0.0';\r\n\r\n// For UMD builds, attach to window\r\nif (typeof window !== 'undefined') {\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerce = require('./client').AICommerce;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceError = require('./client').AICommerceError;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceWidget = require('./widget').AICommerceWidget;\r\n}\r\n"]}
|