# 🔷 WebChat - Embedded Chat

## 📦 Quick Start

### 1. Add the widget to your website

```html
<div id="webchat-component"></div>

<script src="https://your-cdn.com/webchat-bundle.min.umd.cjs"></script>
<script>
WebChat.initialize({
    title: "Customer Support",
    placeholder: "Ask us anything...",
    primaryColor: "#667eea"
});
</script>
```

### 2. That's it! 🎉

The chatbot button will appear in the bottom-right corner of your page. CSS is automatically injected!

## ⚙️ Configuration Options

```typescript
interface WebChatConfig {
  title?: string;                       // Chat window title
  placeholder?: string;                 // Input placeholder text
  primaryColor?: string;                // Primary theme color
  apiKey?: string;                      // Your chatbot UID (required for API)
  position?: 'bottom-right' | 'bottom-left'; // Widget position
  initialMessage?: string;              // Custom initial bot message
  closeButtonIcon?: 'default' | 'text' | 'custom'; // Close button type
  closeButtonText?: string;             // Text for close button (when type is 'text')
  closeButtonCustomIcon?: string;       // Custom icon SVG or URL (when type is 'custom')
  marginBottom?: number;                // Distance from bottom edge in pixels (default: 16)
  marginSide?: number;                  // Distance from left/right edge in pixels (default: 16)
  mobile?: WebChatPositionConfig;       // Mobile-specific position settings
  desktop?: WebChatPositionConfig;      // Desktop-specific position settings
  whatsapp?: {                          // Integrated WhatsApp Options
    phoneNumber: string;                // WhatsApp phone number
    message?: string;                   // Optional default message text
    active?: boolean;                   // Enable or disable the button (default: true)
    color?: string;                     // Customize the internal WhatsApp button color
  };
}

interface WebChatPositionConfig {
  position?: 'bottom-right' | 'bottom-left';
  marginBottom?: number;
  marginSide?: number;
}
```

Example:
```js
WebChat.initialize({
    title: "Chat Assistant",
    placeholder: "Type your message...",
    primaryColor: "#007bff",
    apiKey: "your-chatbot-uid",        // Chatbot UID from admin panel
    position: "bottom-right",
    initialMessage: "Hi! 👋 I'm your virtual assistant. How can I help you today?",
    closeButtonIcon: "default", // or "text" or "custom"
    marginBottom: 20,           // Distance from bottom edge (default: 16px)
    marginSide: 20,             // Distance from side edge (default: 16px)
    // Device-specific overrides
    mobile: {
        position: "bottom-left",
        marginBottom: 80,
        marginSide: 15
    },
    desktop: {
        position: "bottom-right", 
        marginBottom: 30,
        marginSide: 30
    },
    whatsapp: {                        // Adds a dual-button menu for WhatsApp & WebChat
        phoneNumber: "YOUR_PHONE_NUMBER",
        message: "Hello! I need help...",
        active: true,
        color: "#25D366"
    }
});
```

# 💬 WhatsApp Button

If you simply want a floating WhatsApp action button with no WebChat, you can use `WhatsAppButtonAPI`, which isolates itself in the Shadow DOM to avoid CSS conflicts.

## 📦 Installation and Basic Usage

```html
<!-- Load the script -->
<script src="path/to/webchat.js"></script>
<script>
  WhatsAppButtonAPI.initialize({
    phoneNumber: "1234567890",
    message: "Hola, me gustaría tener más información.",
    color: "#25D366",
    position: "bottom-right",
    marginBottom: 20,
    marginSide: 20,
    active: true,
    size: 48, // Button dimension in px
    
    // Customize device-specific positioning
    desktop: {
      position: "bottom-right",
      marginBottom: 30,
      marginSide: 30
    },
    mobile: {
      position: "bottom-right",
      marginBottom: 80,
      marginSide: 15
    }
  });
</script>
```

# 💬 EmbedChat - Embedded Chat

EmbedChat allows you to integrate a complete chat system directly into any element of your web page, with full control over size, position, and style.

## 📦 Installation and Basic Usage

### Direct HTML
```html
<!-- Element to embed the chat -->
<div id="my-chat-embed"></div>

<!-- Load the script -->
<script src="path/to/webchat.js"></script>
<script>
  EmbedChat.initialize({
    elementId: "my-chat-embed",
    apiKey: "your-api-key",
    title: "Chat Assistant",
    width: 400,
    height: 500
  });
</script>
```

### JavaScript/TypeScript
```javascript
import { EmbedChatAPI } from './webchat';

const chatInstance = EmbedChatAPI.initialize({
  elementId: "my-chat-embed",
  apiKey: "your-api-key",
  title: "Chat Assistant",
  width: 400,
  height: 500
});
```

## ⚙️ Complete Configuration

### Required Properties
```javascript
EmbedChatAPI.initialize({
  // REQUIRED
  elementId: "my-chat-embed",              // ID of the HTML element to embed the chat
  apiKey: "your-api-key",                  // API key of the service
})
```

### Content Properties
```javascript
EmbedChatAPI.initialize({
  // Texts and content
  title: "Chat Assistant",        // Title shown in the header
  placeholder: "Type your message...",    // Input placeholder text
  initialMessage: "Hello! 👋 I'm your chat assistant. How can I help you today?", // First message from the bot
  footerText: "Powered by NotChatBot", // Footer text (optional)
  avatar: "https://example.com/avatar.jpg", // Bot avatar URL
})
```

### Size Properties
```javascript
EmbedChatAPI.initialize({
  // Main dimensions
  width: 400,                        // Width: number (px) or string ("100%", "50vw")
  height: 500,                       // Height: number (px) or string ("100%", "80vh")
  
  // Size limits
  maxWidth: 600,                     // Maximum width
  maxHeight: "90vh",                 // Maximum height (accepts CSS units)
  minWidth: 280,                     // Minimum width (default: 280px)
  minHeight: 300,                    // Minimum height (default: 300px)
})
```

### Appearance Properties
```javascript
EmbedChatAPI.initialize({
  // Colors
  primaryColor: "#3b82f6",           // Primary color (header, buttons, etc.)
  textColor: "#333333",              // Message text color
  bubbleUserColor: "#3b82f6",        // User message bubble background
  chatBackground: "#ffffff",         // Chat background color
  footerColor: "#f3f4f6",            // Footer background color
  
  // Borders
  borderRadius: 12,                  // Border radius: number (px) or string
  border: "2px solid #3b82f6",       // Custom border (CSS border)
  boxShadow: "0 10px 30px rgba(0,0,0,0.2)", // Custom shadow
  
  chatTransparent: false,            // If true, chat background is transparent
})
```

### Section Control Properties
```javascript
EmbedChatAPI.initialize({
  showHeader: true,                  // Show/hide header (default: true)
  showFooter: true,                  // Show/hide footer (default: true if footerText is provided)
})
```

### Input Configuration
```javascript
EmbedChatAPI.initialize({
  input: {
    backgroundColor: "#ffffff",      // Input area background color
    inputBorder: "2px solid #e5e7eb", // Input field border
    inputBorderRadius: "8px",        // Input border radius
    iconColor: "#3b82f6"             // Send icon color
  }
})
```

### Custom CSS
```javascript
EmbedChatAPI.initialize({
  customCSS: `
    #notchatbot-embed-chat {
      /* Your custom styles here */
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    }
  `
})
```

### Size Control
```javascript
EmbedChatAPI.initialize({
  elementId: "mi-chat",
  
  // Main sizes
  width: 400,           // Number (px) or string ("100%", "50vw")
  height: 500,          // Number (px) or string ("100%", "80vh")
  
  // Size limits
  maxWidth: 600,        // Maximum size
  maxHeight: "90vh",    // Can use CSS units
  minWidth: 280,        // Minimum size
  minHeight: 300,
  
  // More
  width: "100%",        // Occupies the entire width of the container
  height: "50vh",       // 50% of the window height
  maxWidth: "500px",    // Maximum 500px
})
```

### Visual Customization
```javascript
EmbedChatAPI.initialize({
  elementId: "mi-chat",
  
  // Borders and effects
  borderRadius: 12,                 // Border radius in px
  border: "2px solid #3b82f6",     // Custom border
  boxShadow: "0 10px 30px rgba(0,0,0,0.2)", // Custom shadow
  
  // Section control
  showHeader: true,                 // Show/hide header (default: true)
  showFooter: true,                 // Show/hide footer (default: true if footerText is provided)
  
  // 🆕 Custom CSS
  customCSS: `
    #notchatbot-embed-chat {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
      border-radius: 20px !important;
    }
  `
})
```

## 📋 Complete Property Reference

### EmbedChatConfig Configuration Table

| Property | Type | Required | Default | Description |
|-----------|------|-----------|---------|-------------|
| `elementId` | `string` | ✅ | - | ID of the HTML element where the chat will be mounted |
| `apiKey` | `string` | ✅ | - | API key for the chat service |
| `title` | `string` | ❌ | `"Chat"` | Title shown in the chat header |
| `placeholder` | `string` | ❌ | `"Type your message..."` | Input field placeholder text |
| `primaryColor` | `string` | ❌ | `"#3b82f6"` | Primary color (header, buttons, links) |
| `avatar` | `string` | ❌ | - | Bot avatar URL (optional) |
| `initialMessage` | `string` | ❌ | - | First message shown by the bot |
| `footerText` | `string` | ❌ | - | Footer text (if provided, it is shown) |
| `width` | `string \| number` | ❌ | `"100%"` | Chat width (px or CSS units) |
| `height` | `string \| number` | ❌ | `400` | Chat height (px or CSS units) |
| `maxWidth` | `string \| number` | ❌ | `"100%"` | Maximum chat width |
| `maxHeight` | `string \| number` | ❌ | `"100vh"` | Maximum chat height |
| `minWidth` | `string \| number` | ❌ | `280` | Minimum chat width |
| `minHeight` | `string \| number` | ❌ | `300` | Minimum chat height |
| `showHeader` | `boolean` | ❌ | `true` | Show/hide the header |
| `showFooter` | `boolean` | ❌ | `true` | Show/hide the footer (if footerText is provided) |
| `borderRadius` | `string \| number` | ❌ | `12` | Container border radius |
| `border` | `string` | ❌ | `"1px solid #e5e7eb"` | Container border (CSS border) |
| `boxShadow` | `string` | ❌ | `"0 10px 25px..."` | Container shadow |
| `chatTransparent` | `boolean` | ❌ | `false` | If true, chat background is transparent |
| `chatBackground` | `string` | ❌ | `"#ffffff"` | Chat background color |
| `textColor` | `string` | ❌ | - | Message text color |
| `bubbleUserColor` | `string` | ❌ | - | User message bubble background color |
| `footerColor` | `string` | ❌ | - | Footer background color |
| `input` | `EmbedChatInputConfig` | ❌ | - | Input-specific configuration |
| `customCSS` | `string` | ❌ | - | Custom CSS for the chat |

---

## 🛠️ Dynamic Control via API and Events

WebChat exposes a global API and custom events to dynamically control the position, padding, and visibility of the widget from anywhere in your app or from the browser console.

### WebChat Global Methods

```js
window.openWebChat();           // Open the floating chat
window.closeWebChat();          // Close the floating chat
window.toggleWebChat();         // Toggle open/close
window.unmountWebChat();        // Unmount the floating chat
window.mountWebChat();          // Mount the floating chat if it was unmounted
window.hideWebChat();           // Hide the chat (display: none)
window.showWebChat();           // Show the chat if it was hidden
window.injectWebChatCSS(css);   // Inject custom CSS into the shadow DOM
window.removeWebChatCSS();      // Remove custom CSS
window.setWebChatPosition(obj); // Change position/padding dynamically
```

### EmbedChat Global Methods

```js
window.unmountEmbedChat(elementId); // Unmount the EmbedChat instance for the given elementId
window.mountEmbedChat(elementId);   // Mount the EmbedChat instance again (with the last used config)
```

- `window.unmountEmbedChat(elementId)`: Unmounts the EmbedChat instance from the specified element. The last configuration is saved.
- `window.mountEmbedChat(elementId)`: Remounts the EmbedChat instance in the specified element using the last configuration used for that element. If no config was previously used, a warning is shown in the console.

#### Example

```js
window.unmountEmbedChat('embed-small'); // Unmounts the chat from the element with id 'embed-small'
window.mountEmbedChat('embed-small');   // Remounts the chat in the same element with the last config
```

### WhatsApp Global Methods

You can programatically show, hide, or destroy the standalone WhatsApp button from the Global window object.

```js
window.WhatsAppButton.initialize(config); // Initializes the standalone widget
window.hideWhatsApp();                    // Hides WhatsApp button (display: none)
window.showWhatsApp();                    // Unhides it
window.unmountWhatsApp();                 // Removes from DOM entirely
```

---

### Listen to lifecycle & message events (🆕)

We emit **custom browser events** so you can capture interactions and feed them into Google Tag Manager, Google Analytics, Meta Pixel, or any other analytics tool.

| Widget | Event name | Fired when | `detail` payload |
|--------|------------|------------|------------------|
| WebChat | `notchatbot-webchat-open` | The floating chat is opened | `{ conversationId }` |
| WebChat | `notchatbot-webchat-closed` | The floating chat is closed | `{ conversationId }` |
| WebChat | `notchatbot-webchat-message-sent` | The user sends one or more messages | `{ messages: Message[] }` |
| WebChat | `notchatbot-webchat-message-received` | A message is received from the server | `{ message: Message, role: 'assistant' \| 'employee' }` |
| WebChat | `notchatbot-webchat-button-click` | The round chat widget activator button is clicked | N/A |
| WebChat | `notchatbot-chatbubble-popover-click` | The initial presentation chat bubble is clicked | N/A |
| WebChat | `notchatbot-webchat-menu-whatsapp-click` | The WhatsApp button inside the WebChat multi-option menu is clicked | N/A |
| WebChat | `notchatbot-webchat-menu-webchat-click` | The standard Webchat button inside the multi-option menu is clicked | N/A |
| WhatsApp | `notchatbot-whatsapp-button-click` | The standalone WhatsApp widget is clicked | N/A |
| EmbedChat | `notchatbot-embedchat-message-sent` | The user sends a message | `{ message: Message }` |
| EmbedChat | `notchatbot-embedchat-message-received` | A message is received | `{ message: Message, role: 'assistant' \| 'employee' }` |

`Message` follows the same interface used internally by the widget (id, text, sender, timestamp, etc.).

#### Quick example
```js
window.addEventListener('notchatbot-webchat-open',  e => console.log('WebChat opened', e.detail));
window.addEventListener('notchatbot-webchat-closed',  e => console.log('WebChat closed', e.detail));
window.addEventListener('notchatbot-webchat-message-sent', e => console.log('Sent', e.detail.messages));
window.addEventListener('notchatbot-webchat-message-received', e => {
  const { role, message } = e.detail;
  console.log('Received', role, message);
});
```

#### Google Tag Manager / Google Analytics (GA4)
**NEW:** All the events listed above are automatically pushed to the **dataLayer** simultaneously, alongside the window events! This means you can just create a trigger in GTM for `notchatbot-webchat-message-sent` or `notchatbot-whatsapp-button-click` right out of the box, without writing manual JS event listeners. 

If you prefer firing custom data structures or if you need the message contents cleanly mapped, you can still listen to the `window` events and push to dataLayer manually:
```js
window.addEventListener('notchatbot-webchat-message-sent', e => {
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'webchat_message_sent',
    messages: e.detail.messages,
    conversationId: e.detail.messages[0]?.conversationId || null
  });
});
```
Then in GTM, add a **Custom Event** trigger called `webchat_message_sent` (or `notchatbot-webchat-message-sent` natively) and link it to a GA4 event tag.

#### Meta / Facebook Pixel
```js
window.addEventListener('notchatbot-webchat-open', () => {
  if (window.fbq) {
    fbq('trackCustom', 'WebChatOpened');
  }
});

window.addEventListener('notchatbot-webchat-message-received', e => {
  if (window.fbq) {
    fbq('trackCustom', 'WebChatMessageReceived', {
      role: e.detail.role
    });
  }
});
```
These events make it easy to measure engagement and conversions driven by the chat widget without modifying its source code.

### Change position and padding dynamically (WebChat)

#### 1. Change position and margin globally (flat)
```js
window.setWebChatPosition({
  position: 'bottom-left',
  marginBottom: 40,
  marginSide: 30
});
```

#### 2. Change only for mobile
```js
window.setWebChatPosition({
  mobile: {
    position: 'bottom-right',
    marginBottom: 100,
    marginSide: 20
  }
});
```

#### 3. Change only for desktop
```js
window.setWebChatPosition({
  desktop: {
    position: 'bottom-left',
    marginBottom: 60,
    marginSide: 40
  }
});
```

#### 4. Change using device format
```js
window.setWebChatPosition({
  device: 'mobile',
  marginBottom: 120,
  marginSide: 15
});
```

### Use custom events (addCustomPadding and open/close control)

You can dispatch events to change padding/margin or open/close the chat from anywhere in your app:

#### 1. Open, close, or toggle the floating WebChat
```js
window.dispatchEvent(new CustomEvent('openWebChatbot'));
window.dispatchEvent(new CustomEvent('closeWebChatbot'));
window.dispatchEvent(new CustomEvent('toggleWebChatbot'));
```

#### 2. Change padding for both devices (flat)
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { y: 100, x: 30 } }));
```

#### 3. Change only for mobile
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'mobile', marginBottom: 120, marginSide: 20 } }));
```

#### 4. Change only for desktop
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'desktop', marginBottom: 60, marginSide: 40 } }));
```

#### 5. Change using nested object
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: {
  mobile: { marginBottom: 90, marginSide: 10 },
  desktop: { marginBottom: 50, marginSide: 30 }
}}));
```

### Accepted object formats

- **Flat:** `{ marginBottom, marginSide, position }` (applies to both if no override in mobile/desktop)
- **By device:** `{ device: 'mobile'|'desktop', marginBottom, marginSide }`
- **Nested:** `{ mobile: { ... }, desktop: { ... } }`
- **Alias:** `{ y, x }` (`y` → marginBottom, `x` → marginSide)

You can combine these formats as needed.

### Inject and remove custom CSS in WebChat

You can inject hot CSS into the floating WebChat using the global API:

```js
// Change the header background color
window.injectWebChatCSS(`
  #notchatbot-webchat-header {
    background: #111 !important;
    color: #fff !important;
  }
`);

// Hide the floating button
window.injectWebChatCSS(`#notchatbot-webchat-button { display: none !important; }`);

// Change the chat window width
window.injectWebChatCSS(`#notchatbot-webchat-window { width: 500px !important; }`);

// Change the floating button color
window.injectWebChatCSS(`#notchatbot-webchat-button { background: #f59e0b !important; }`);

// Remove all custom styles
window.removeWebChatCSS();
```

#### Internal element IDs for WebChat

You can use these IDs to select and style specific parts of the widget:

- `#notchatbot-webchat-button` — Floating chat button
- `#notchatbot-webchat-header` — Chat window header
- `#notchatbot-webchat-window` — Main chat window

Example to change the header and button color:

```js
window.injectWebChatCSS(`
  #notchatbot-webchat-header { background: #222 !important; color: #fff !important; }
  #notchatbot-webchat-button { background: #f59e0b !important; }
`);
```

You can combine these selectors to fully customize the widget.

---