import { Meta, Story, Canvas, Controls, Source } from '@storybook/blocks';
import * as TableChatStories from './TableChat.stories';

<Meta of={TableChatStories} title="Documentation/TableChat" />

# Table Chat Feature

The Table Chat feature is a comprehensive real-time messaging system integrated with the Table component. It provides a complete chat experience with channels, direct messaging, rich text editing, file sharing, and advanced message management capabilities.

## Overview

The Table Chat feature consists of several interconnected components that work together to provide a seamless messaging experience:

- **TableChatSidePanel**: Main container orchestrating the entire chat interface
- **TableChatRightSection**: Message display and interaction management
- **ChatInput**: Rich text editor with advanced formatting capabilities
- **ChatHeader**: Participant management and search functionality
- **useTableChat**: Core hook managing WebSocket connections and API interactions

## Architecture

```mermaid
graph TD
    A[Table Component] --> B[TableChatSidePanel]
    B --> C[TableChatChannelHeader]
    B --> D[TableChatRightSection]
    D --> E[ChatHeader]
    D --> F[Message List]
    D --> G[ChatInput]
    B --> H[useTableChat Hook]
    H --> I[WebSocket Connection]
    H --> J[API Services]
    H --> K[Real-time Updates]
```

## Core Components

### TableChatSidePanel

The main container component that orchestrates the entire chat interface.

**Props:**
```typescript
interface TableChatSidePanelProps {
  isOpen: boolean;                    // Controls panel visibility
  handleClose: () => void;           // Panel close handler
  chatConfiguration: ChatConfiguration; // Complete chat configuration
}
```

**Key Methods:**

#### `handleChatClick(chatId: string, selectedChatData: ChatObject)`
- **Purpose**: Handles chat selection and opens the message view
- **Parameters**:
  - `chatId`: Unique identifier for the chat
  - `selectedChatData`: Complete chat object with metadata
- **Flow**: Sets loading state → calls external handler → loads messages
- **Returns**: `Promise<void>`

#### `fetchChatList(currentActiveChannelInfo: ChannelInfo)`
- **Purpose**: Loads chat list for a selected channel
- **Parameters**:
  - `currentActiveChannelInfo`: Channel object with id and metadata
- **Returns**: `Promise<ChatObject[]>`
- **Flow**: Calls `loadChatList` from configuration → updates state

#### `fetchChannelList()`
- **Purpose**: Loads available channels for the user
- **Returns**: `Promise<ChannelObject[]>`
- **Flow**: Calls `loadChannelsList` from configuration → updates state

#### `handleDeleteChat()`
- **Purpose**: Handles batch deletion of selected chats
- **Returns**: `Promise<void>`
- **Flow**: Validates selection → calls delete API → updates UI → handles cleanup

#### `clearnupLocalStates()`
- **Purpose**: Resets all local state when panel closes
- **Returns**: `void`
- **Called**: When panel closes or navigation changes

### useTableChat Hook

The core hook managing WebSocket connections, API interactions, and real-time updates.

**Parameters:**
```typescript
interface UseTableChatParams {
  selectedRows: any[];              // Selected table rows
  uniqueRowId: string;             // Unique identifier field
  channelName: string;             // Channel name field
  objectType?: string;             // Object type (default: "promo")
  maxReconnectAttempts?: number;   // Max WebSocket reconnection attempts (default: 3)
  appCode?: string;                // Application code (default: "promosmart")
}
```

**Returns:**
```typescript
interface UseTableChatReturn {
  // Chat state
  isChatOpen: boolean;
  currentTopicId: string | null;
  isWebSocketConnected: boolean;
  realTimeMessages: MessageObject[];
  currentUserId: number | null;
  
  // Chat actions
  handleChatClick: () => Promise<void>;
  handleChatClose: () => Promise<void>;
  
  // API methods
  createTopicAPI: (payload: CreateTopicPayload) => Promise<ApiResponse>;
  deleteTopicAPI: (topicId: string) => Promise<ApiResponse>;
  fetchAllTopicsAPI: () => Promise<ChannelObject[]>;
  fetchChatsByObjectIdAPI: (objectType: string, objectId: string) => Promise<ChatObject[]>;
  createMessageAPI: (payload: CreateMessagePayload) => Promise<MessageObject>;
  updateMessageAPI: (messageId: string, payload: UpdateMessagePayload) => Promise<MessageObject>;
  deleteMessageAPI: (messageId: string) => Promise<boolean>;
  searchMessagesAPI: (topicId: string, queryParams: SearchParams) => Promise<MessageObject[]>;
  
  // WebSocket methods
  joinTopicWithWebSocket: (topicId: string) => Promise<void>;
  leaveCurrentTopic: () => Promise<void>;
  markTopicAsDeleted: (topicId: string) => void;
  handleRealTimeMessageUpdate: (newMessage: MessageObject, additionalProps?: any) => void;
  
  // Direct chat methods
  loadChatListFromSelectedRows: (selectedRows: any[], uniqueRowId: string, objectType: string) => Promise<ChatObject[]>;
  chatListForDirectAccess: ChatObject[];
  setChatListForDirectAccess: (chats: ChatObject[]) => void;
  hasDirectChatList: boolean;
  setHasDirectChatList: (hasDirect: boolean) => void;
  clearDirectChatListWithDisconnect: () => void;
}
```

**Key Methods:**

#### `createTopicAPI(payload: CreateTopicPayload)`
- **Purpose**: Creates a new chat topic
- **Parameters**:
  - `payload`: Topic creation data
- **Returns**: `Promise<ApiResponse>`
- **Flow**: Calls API → sets currentTopicId → enables WebSocket connection

#### `joinTopicWithWebSocket(topicId: string)`
- **Purpose**: Connects to a specific topic via WebSocket
- **Parameters**:
  - `topicId`: Topic identifier to connect to
- **Returns**: `Promise<void>`
- **Flow**: Disconnects previous connection → sets new topic → establishes WebSocket

#### `handleRealTimeMessageUpdate(newMessage: MessageObject, additionalProps?: any)`
- **Purpose**: Handles real-time message updates
- **Parameters**:
  - `newMessage`: New or updated message object
  - `additionalProps`: Additional properties to merge
- **Returns**: `void`
- **Flow**: Validates topic → updates message state → triggers UI update

#### `getCombinedMessages(topicId: string, page: number)`
- **Purpose**: Combines API messages with real-time messages
- **Parameters**:
  - `topicId`: Topic identifier
  - `page`: Page number for pagination
- **Returns**: `Promise<{messages: MessageObject[], noMoreData: boolean}>`
- **Flow**: Fetches API messages → merges with real-time → deduplicates → sorts chronologically

### TableChatRightSection

Manages message display, real-time updates, and user interactions.

**Props:**
```typescript
interface TableChatRightSectionProps {
  chatId: string;                   // Current chat identifier
  title: string;                    // Chat title
  CreatedBy: string;                // Creator information
  messageConfig: MessageConfig;     // Message configuration
  inputChatConfig: InputConfig;     // Input configuration
  chatHeaderConfig: HeaderConfig;   // Header configuration
  showParticipantsList?: boolean;   // Show participants list
  showPinnedChat?: boolean;         // Show pinned chat
  showSearch?: boolean;             // Show search functionality
  showActionBtn?: boolean;          // Show action buttons
  handleToast: (isOpen: boolean, message: string, variant: string) => void;
}
```

**Key Methods:**

#### `fetchMoreMessages(page: number)`
- **Purpose**: Implements infinite scroll pagination
- **Parameters**:
  - `page`: Page number to load
- **Returns**: `Promise<MessageObject[]>`
- **Features**: Handles both old format (array) and new format (object with metadata)

#### `handleSend(payload: SendMessagePayload)`
- **Purpose**: Sends new messages or updates existing ones
- **Parameters**:
  - `payload`: Message content and metadata
- **Returns**: `Promise<void>`
- **Flow**: Validates content → calls send handler → updates UI → handles real-time sync

#### `handleUpdateMessage(updatedContent: UpdateMessagePayload)`
- **Purpose**: Updates existing messages
- **Parameters**:
  - `updatedContent`: New message content
- **Returns**: `Promise<void>`
- **Flow**: Calls update API → handles real-time vs API message sync

#### `handleMessageDelete(messageId: string)`
- **Purpose**: Deletes messages with proper state management
- **Parameters**:
  - `messageId`: ID of message to delete
- **Returns**: `Promise<void>`
- **Flow**: Determines message type → calls delete handler → updates local state

#### `handleSearchMessage(searchValue: string, chatId: string)`
- **Purpose**: Searches messages within the chat
- **Parameters**:
  - `searchValue`: Search query
  - `chatId`: Chat to search in
- **Returns**: `Promise<MessageObject[]>`

#### `groupMessagesByDate(messages: MessageObject[])`
- **Purpose**: Groups messages by date for display
- **Parameters**:
  - `messages`: Array of message objects
- **Returns**: `Array<MessageObject | DateSeparator>`

### ChatInput

Rich text editor with advanced formatting and interaction capabilities.

**Props:**
```typescript
interface ChatInputProps {
  placeholder: string;              // Input placeholder text
  value: string;                    // Current input value
  onChange: (value: string) => void; // Value change handler
  onSend: (payload: SendMessagePayload) => Promise<void>; // Message send handler
  messageConfig: MessageConfig;     // Configuration for mentions, etc.
  isEditMode?: boolean;             // Whether in edit mode
  chatId: string;                   // Current chat ID
  selectedQuickAction?: QuickAction; // Selected quick action
  onQuickActionSelect?: (action: QuickAction) => void;
}
```

**Key Methods:**

#### `handleSend()`
- **Purpose**: Processes and sends messages
- **Returns**: `Promise<void>`
- **Flow**: Validates content → extracts mentions → calls send handler → clears input

#### `getMentionedUsers()`
- **Purpose**: Extracts mentioned users from rich text content
- **Returns**: `MentionedUser[]`
- **Flow**: Parses HTML content → extracts mention spans → returns user objects

#### `handleInputChange(htmlContent: string)`
- **Purpose**: Handles rich text content changes
- **Parameters**:
  - `htmlContent`: HTML content from editor
- **Returns**: `void`
- **Flow**: Updates state → calls onChange callback

#### `handleEmojiClick(emoji: EmojiObject)`
- **Purpose**: Inserts emoji into the editor
- **Parameters**:
  - `emoji`: Emoji object or string
- **Returns**: `void`

#### `handleFileUpload(file: File)`
- **Purpose**: Handles file upload with progress tracking
- **Parameters**:
  - `file`: File object to upload
- **Returns**: `Promise<void>`

### ChatHeader

Header component with participant management and search functionality.

**Props:**
```typescript
interface ChatHeaderProps {
  title: string;                    // Chat title
  chatId: string;                   // Chat identifier
  chatHeaderConfig: HeaderConfig;   // Header configuration
  participants: ParticipantObject[]; // Current participants
  onPinnedClick?: (chatId: string) => Promise<MessageObject[]>;
}
```

**Key Methods:**

#### `fetchOptionsForRadio(radioValue: string)`
- **Purpose**: Loads participant options based on selection type
- **Parameters**:
  - `radioValue`: "existing" or "new" participants
- **Returns**: `Promise<ParticipantObject[]>`

#### `handleRadioButtonChange(value: string)`
- **Purpose**: Handles participant type selection
- **Parameters**:
  - `value`: Selected radio button value
- **Returns**: `void`
- **Flow**: Updates state → fetches new options

#### `handleMessageSearchChange(e: ChangeEvent<HTMLInputElement>)`
- **Purpose**: Handles message search with debouncing
- **Parameters**:
  - `e`: Input event
- **Returns**: `void`
- **Flow**: Updates search value → calls debounced search

#### `handleParticipantsClick()`
- **Purpose**: Opens participant management interface
- **Returns**: `Promise<void>`
- **Flow**: Calls external handler → loads participant data

## Configuration Structure

### ChatConfiguration Object

The main configuration object that controls all chat functionality:

```typescript
interface ChatConfiguration {
  // Message-related configuration
  messageChatConfig: {
    // Real-time messaging
    realTimeMessages: MessageObject[];
    isWebSocketConnected: boolean;
    currentTopicId: string | null;
    currentUserId: number | null;
    onRealTimeMessageUpdate: (newMessage: MessageObject) => void;
    
    // Message actions
    onMessageReply: (messageId: string, message: MessageObject) => void;
    onMessageBookmark: (messageId: string, message: MessageObject) => void;
    onMessagePin: (messageId: string, isPinned: boolean, item: MessageObject, selectedChannelInfo: ChannelInfo, selectedChatInfo: ChatObject) => Promise<boolean>;
    onMessageUpdate: (messageId: string, updatedData: UpdateMessagePayload) => Promise<MessageObject>;
    onMessageDelete: (messageId: string) => Promise<boolean>;
    onThreadClick: (messageId: string, message: MessageObject) => void;
    
    // Data loading
    loadThreadMessages: (parentMessageId: string) => Promise<MessageObject[]>;
    loadPinnedMsg: () => Promise<MessageObject[]>;
    onSearchMessage: (searchValue: string, chatId: string) => Promise<MessageObject[]>;
    
    // Configuration
    messageConfig: {
      showActions: boolean;
      priorityOptions: PriorityOption[];
      quickActionProps: QuickAction[];
      isMsgFormat: boolean;
    };
    
    // Topic management
    leaveCurrentTopic: () => Promise<void>;
    markTopicAsDeleted: (topicId: string) => void;
  };
  
  // Header configuration
  headerChatConfig: {
    // Participant management
    participants: ParticipantObject[];
    loadParticipants: (radioValue: string, selectedChannelInfo: ChannelInfo, selectedChatInfo: ChatObject) => Promise<ParticipantObject[]>;
    loadParticipantsAvatar: (selectedRadioOption: string, chatId: string) => Promise<ParticipantObject[]>;
    onParticipantAdd: (participant: ParticipantObject, selectedRadioOption: string, chatId: string) => Promise<ApiResponse>;
    onParticipantRemove: (participant: ParticipantObject) => Promise<ApiResponse>;
    
    // Search and actions
    onSearchChange: (value: string, radioValue: string, chatId: string) => Promise<ParticipantObject[]>;
    onPinnedClick: (chatId: string) => Promise<MessageObject[]>;
    onNotificationSettingChange: (settings: NotificationSettings) => Promise<ApiResponse>;
    
    // Chat actions
    onChatClick: (chatId: string, channelId: string) => Promise<void>;
    
    // Header settings
    headerConfig: {
      showSearch: boolean;
      showParticipants: boolean;
      showPinned: boolean;
      showNotifications: boolean;
      selectedRadioOptionMenu: string;
      maxAvatars: number;
      radioOptions: RadioOption[];
      searchConfig: SearchConfig;
    };
  };
  
  // Input configuration
  inputChatConfig: {
    onSend: (payload: SendMessagePayload, chatId: string) => Promise<MessageObject>;
    onAttachFile: (file: File) => void;
    onImageUpload: (image: File) => void;
    onEmojiSelect: (emoji: EmojiObject) => void;
    inputConfig: {
      placeholder: string;
      maxLength: number;
      showFormatting: boolean;
      showEmojiPicker: boolean;
      showAttachments: boolean;
      allowedFileTypes: string[];
      quickActions: QuickAction[];
    };
  };
  
  // Left panel configuration
  leftPanel: {
    leftHeaderPanel: {
      showAddChat: boolean;
    };
    leftChatPanel: {
      showCheckbox: boolean;
    };
    rightHeaderPanel: {
      showParticipants: boolean;
      showPinnedChat: boolean;
      showChatSearch: boolean;
      showActionBtn: boolean;
    };
    loadChannelsList: () => Promise<ChannelObject[]>;
    loadChatList: (selectedChannelInfo: ChannelInfo) => Promise<ChatObject[]>;
    handleChatName: (formData: CreateChatFormData, selectedChannel: ChannelInfo) => Promise<CreateChatResponse>;
    deleteChat: (topicId: string) => Promise<ApiResponse>;
    directChatList: ChatObject[];
    hasDirectChatList: boolean;
    clearDirectChatList: () => void;
  };
  
  // Right panel configuration
  rightPanel: {
    loadMessages: (chatId: string, selectChat: ChatObject, page: number) => Promise<MessageObject[] | {messages: MessageObject[], noMoreData: boolean}>;
    loadOlderMessages: (channelId: string) => Promise<MessageObject[]>;
    messagesClearedTrigger: number;
  };
}
```

## Data Structures

### MessageObject
```typescript
interface MessageObject {
  id: string;              // Unique message identifier
  author: "user" | "assistant" | "system"; // Message author type
  authorName: string;      // Display name
  content: string;         // HTML content
  timestamp: string;       // Display timestamp
  date: string;           // ISO date string
  priority: "low" | "medium" | "high"; // Message priority
  isPinned: boolean;      // Pin status
  deleted: boolean;       // Deletion status
  edited: boolean;        // Edit status
  showActions: boolean;   // Show action buttons
  showReplyBadge: boolean; // Show reply badge
  replyText?: string;     // Reply text
  otherProps: {
    sender_id: number;    // Sender's user ID
    created_at: string;   // Creation timestamp
    updated_at?: string;  // Update timestamp
    isRealTime?: boolean; // Real-time message flag
    topic_id: string;     // Topic identifier
    sender_name: string;  // Sender name
  };
}
```

### ChatObject
```typescript
interface ChatObject {
  id: string;             // Unique chat identifier
  title: string;          // Chat display name
  subtitle: string;       // Chat description/preview
  user: string;           // Last message author
  text: string;           // Last message preview
  time: string;           // Last activity time
  isChecked: boolean;     // Selection status
  isPinned: boolean;      // Pin status
  unreadCount: number;    // Unread message count
  messageCount: number;   // Total message count
  timestamp: string;      // Formatted timestamp
  otherProps: {
    object_ids: string[]; // Related object IDs
    object_type: string;  // Object type ("deal", etc.)
    topic_id: string;     // Topic identifier
    created_by_user: string; // Creator name
    is_pinned: boolean;   // Pin status
    unread_count: number; // Unread count
    message_count: number; // Message count
    created_at: string;   // Creation timestamp
  };
}
```

### ChannelObject
```typescript
interface ChannelObject {
  id: string;             // Unique channel identifier
  title: string;          // Channel name
  time: string;           // Last activity
  unreadCount: number;    // Unread messages
  objectType: string;     // Object type
}
```

### ParticipantObject
```typescript
interface ParticipantObject {
  id: string | number;    // Unique participant identifier
  label: string;          // Display name
  value: string | number; // Value for selection
  role?: string;          // Participant role
  url?: string;           // Avatar URL
  status?: "online" | "offline"; // Online status
  isPinned?: boolean;     // Pin status
  otherProps?: {
    user_name: string;    // User name
    user_code: string | number; // User code
    email: string;        // Email address
    user_image?: string;  // User image URL
  };
}
```

## Advanced Features

### 1. Infinite Scroll Implementation

The chat uses a custom `useInfiniteScroll` hook that:

- Triggers loading when scrolling near the top (for older messages)
- Handles loading states and error conditions
- Supports both array and object response formats
- Prevents duplicate message loading

```typescript
interface UseInfiniteScrollOptions {
  threshold?: number;        // Intersection threshold (default: 0.1)
  rootMargin?: string;       // Root margin (default: "200px 0px 0px 0px")
  enabled?: boolean;         // Enable/disable infinite scroll
}

interface UseInfiniteScrollReturn {
  loadMore: () => void;      // Function to load more data
  isLoadingMore: boolean;    // Loading state
  hasMore: boolean;          // Whether more data is available
  error: string | null;      // Error state
  reset: () => void;         // Reset function
}
```

### 2. Real-time Synchronization

Real-time updates are handled through:

- WebSocket connection status monitoring
- Message deduplication by ID
- Optimistic updates with rollback support
- Proper chronological ordering

```typescript
interface WebSocketMessage {
  type: "new_message" | "message_created" | "message_updated" | "message_update" | "message_deleted" | "message_delete" | "messages_cleared";
  action?: "message_updated" | "message_deleted" | "messages_cleared";
  message: MessageObject;
  topic_id?: string;
}
```

### 3. Rich Text Editor Features

The MentionEditor component provides:

- @mention autocomplete with user search
- Text formatting (bold, italic, links, etc.)
- Emoji picker integration
- File and image upload with preview
- HTML content validation

```typescript
interface MentionEditorProps {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  maxLength?: number;
  showFormatting?: boolean;
  showEmojiPicker?: boolean;
  showAttachments?: boolean;
  allowedFileTypes?: string[];
  onMentionSearch?: (query: string) => Promise<ParticipantObject[]>;
  onFileUpload?: (file: File) => Promise<string>;
  onEmojiSelect?: (emoji: EmojiObject) => void;
}
```

### 4. Search Functionality

Two types of search are supported:

1. **Message Search**: Search within chat messages
2. **Participant Search**: Search and filter participants

Both support debouncing and async loading states.

```typescript
interface SearchConfig {
  placeholder: string;
  debounceMs: number;
  minChars: number;
  showAdvancedSearch?: boolean;
}
```

### 5. Message Highlighting & Auto-Scroll

The chat feature includes intelligent message highlighting and auto-scrolling capabilities for improved user experience:

#### Features:

1. **Direct Message Highlighting via Config**
   - Set `selectedMessageId` in config to highlight a specific message on page load
   - Automatically searches across multiple pages if message is not in current view
   - Highlights only once per chat session (prevents re-highlighting on state changes)

2. **Pinned Message Highlighting**
   - Click any pinned message to highlight it in the main chat area
   - Supports re-highlighting the same message multiple times
   - Pinned panel remains open for easy navigation between messages

3. **Smart Page Loading**
   - Tracks current page state to prevent duplicate API calls
   - Only loads the next unloaded page when searching for messages
   - Example: If on page 1, searching loads page 2 only (skips if already loaded)

4. **Visual Animation**
   - 1.5-second scale animation with pulsing border effect
   - Smooth scroll to message position with configurable behavior
   - Configurable highlight duration and colors

#### Configuration:

```typescript
interface MessageHighlightConfig {
  // Message ID to highlight (one-time highlight on load)
  selectedMessageId: string | null;
  
  // Search configuration
  maxSearchPages: number;           // Max pages to search (default: 3)
  highlightDuration: number;        // Duration in ms (default: 3000)
  
  // Scroll behavior
  scrollBehavior: "smooth" | "auto"; // Scroll animation (default: "smooth")
  scrollBlock: "start" | "center" | "end"; // Scroll alignment (default: "center")
  
  // Visual customization
  highlightColor: string | null;    // Custom border color (default: primary color)
}
```

#### Usage Example:

```jsx
const chatConfiguration = {
  messageChatConfig: {
    // Highlight specific message on load (searches pages 1-3)
    selectedMessageId: "msg-123",
    
    // Configuration
    maxSearchPages: 3,
    highlightDuration: 3000,
    scrollBehavior: "smooth",
    scrollBlock: "center",
    highlightColor: "#0066FF",
  }
};
```

#### How It Works:

1. **Config-based Highlighting:**
   - Set `selectedMessageId` in configuration
   - On component mount, checks if message exists in loaded messages
   - If not found, sequentially loads pages 2, 3, etc. until found or max pages reached
   - Scrolls to message and applies highlight animation
   - Tracks highlight to prevent re-triggering (once per chat session)

2. **Pinned Message Highlighting:**
   - User clicks pinned message in PinnedPanel
   - Same search logic applies if message not in current view
   - Can re-highlight same message multiple times (useful for referencing)
   - Panel stays open for easy navigation

3. **Efficient Page Management:**
   - Infinite scroll tracks current page (e.g., page 2)
   - When searching for message, starts from next page (page 3)
   - Updates infinite scroll page state after manual load
   - Prevents duplicate API calls for already-loaded pages

### 6. State Management

The chat feature uses a combination of:

- Local React state for UI interactions
- Memoized configurations to prevent re-renders
- External state management through configuration callbacks
- Cleanup functions for proper resource management

## Usage Examples

### Basic Integration

```jsx
import { Table } from "impact-ui-v3";
import useTableChat from "./customHooks/useTableChat";

function MyComponent() {
  const [selectedRows, setSelectedRows] = useState([]);
  
  const {
    isChatOpen,
    handleChatClick,
    handleChatClose,
    chatConfiguration
  } = useTableChat({
    selectedRows,
    uniqueRowId: "id",
    channelName: "name",
    objectType: "deal"
  });

  return (
    <Table
      isChatEnabled={true}
      isChatOpen={isChatOpen}
      handleChatClick={handleChatClick}
      handleChatClose={handleChatClose}
      chatConfiguration={chatConfiguration}
      // ... other table props
    />
  );
}
```

### Custom Message Handler

```jsx
const chatConfiguration = {
  messageChatConfig: {
    onMessageUpdate: async (messageId, updatedData) => {
      // Custom update logic
      const response = await api.updateMessage(messageId, updatedData);
      return response.data;
    },
    onMessageDelete: async (messageId) => {
      // Custom delete logic
      const response = await api.deleteMessage(messageId);
      return response.success;
    },
  },
};
```

### Real-time Integration

```jsx
const chatConfiguration = {
  messageChatConfig: {
    realTimeMessages: webSocketMessages,
    isWebSocketConnected: wsConnection.readyState === WebSocket.OPEN,
    onRealTimeMessageUpdate: (newMessage) => {
      setWebSocketMessages((prev) => [...prev, newMessage]);
    },
  },
};
```

### Custom Input Configuration

```jsx
const chatConfiguration = {
  inputChatConfig: {
    onSend: async (payload, chatId) => {
      // Custom send logic
      const response = await api.sendMessage({
        topic_id: chatId,
        content: payload.content,
        tagged_users: payload.mentionedUsers,
        priority: payload.priority
      });
      return response.data;
    },
    inputConfig: {
      placeholder: "Type your message with @mentions...",
      maxLength: 5000,
      showFormatting: true,
      showEmojiPicker: true,
      showAttachments: true,
      allowedFileTypes: ["image/*", "application/pdf"],
      quickActions: [
        { label: "Request Review", action: "request_review" },
        { label: "Schedule Meeting", action: "schedule_meeting" }
      ]
    }
  }
};
```

## Best Practices

### 1. Performance

- Use memoized configurations to prevent unnecessary re-renders
- Implement proper cleanup in useEffect hooks
- Debounce search and input handlers
- Use React.memo for expensive components

```jsx
const memoizedMessageConfig = useMemo(() => ({
  ...chatConfiguration.messageChatConfig,
  realTimeMessages,
  isWebSocketConnected,
  currentTopicId,
  onRealTimeMessageUpdate,
  currentUserId,
}), [
  chatConfiguration.messageChatConfig,
  realTimeMessages,
  isWebSocketConnected,
  currentTopicId,
  onRealTimeMessageUpdate,
  currentUserId,
]);
```

### 2. Error Handling

- Always wrap async operations in try-catch blocks
- Provide user feedback for failed operations
- Implement retry mechanisms for critical operations

```jsx
const handleSend = async (payload) => {
  try {
    setLoading(true);
    const response = await onSend(payload, chatId);
    // Handle success
  } catch (error) {
    console.error("Error sending message:", error);
    handleToast(true, "Failed to send message", "error");
  } finally {
    setLoading(false);
  }
};
```

### 3. State Management

- Keep local state minimal and focused
- Use external handlers for persistent data
- Implement proper cleanup when components unmount

```jsx
useEffect(() => {
  return () => {
    // Cleanup WebSocket connections
    if (isWebSocketConnected) {
      disconnectWebSocket();
    }
    // Clear timeouts
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }
  };
}, []);
```

### 4. Accessibility

- Provide proper ARIA labels for interactive elements
- Ensure keyboard navigation support
- Use semantic HTML structures

```jsx
<button
  aria-label="Send message"
  aria-describedby="message-input"
  onClick={handleSend}
  disabled={!messageContent.trim()}
>
  Send
</button>
```

### 5. Real-time Updates

- Handle message deduplication properly
- Implement proper chronological ordering
- Provide visual feedback for connection status

```jsx
const handleRealTimeMessageUpdate = useCallback((newMessage) => {
  setRealTimeMessages((prev) => {
    // Deduplicate by ID
    const exists = prev.some(msg => msg.id === newMessage.id);
    if (exists) {
      return prev.map(msg => 
        msg.id === newMessage.id ? newMessage : msg
      );
    }
    return [...prev, newMessage];
  });
}, []);
```

## Troubleshooting

### Common Issues

1. **Messages not updating in real-time**:
   - Check WebSocket connection status
   - Verify `currentTopicId` matches active chat
   - Ensure `onRealTimeMessageUpdate` is properly configured

2. **Infinite scroll not working**:
   - Check `loadMessages` function implementation
   - Verify page parameter handling
   - Ensure proper return format (array or object with messages)

3. **Mentions not working**:
   - Verify `loadParticipantsAvatar` function
   - Check `chatId` parameter passing
   - Ensure participant data format is correct

4. **File upload issues**:
   - Check file type restrictions
   - Verify upload handler implementation
   - Ensure proper error handling

### Debug Tools

Enable debug logging by setting:

```javascript
window.CHAT_DEBUG = true;
```

This will provide detailed console logs for:

- Message state changes
- API calls and responses
- Real-time update processing
- Component lifecycle events

## Stories

### Basic Chat Examples

<Canvas of={TableChatStories.BasicChatFeature} />

<Canvas of={TableChatStories.DirectMessaging} />

<Canvas of={TableChatStories.RealTimeChat} />

<Canvas of={TableChatStories.RichTextChat} />

<Canvas of={TableChatStories.SearchEnabledChat} />

<Canvas of={TableChatStories.CustomMessageTypes} />

<Canvas of={TableChatStories.EmptyStateChat} />

### Message Highlighting Examples

<Canvas of={TableChatStories.MessageHighlightingPage1} />

<Canvas of={TableChatStories.MessageHighlightingPage2} />

<Canvas of={TableChatStories.PinnedMessageHighlighting} />

<Canvas of={TableChatStories.CombinedHighlighting} />

<Canvas of={TableChatStories.CustomHighlightConfiguration} />
