# Chat API Documentation

## Обзор

Система чата является комплексным решением для обмена сообщениями в CRM системе, поддерживающим множественные провайдеры (WhatsApp, Telegram, Messenger и др.), персональные и групповые чаты, а также интеграцию с сущностями системы.

## Архитектура

### Компоненты системы

1. **Backend (NestJS)**
   - REST API для управления чатами
   - WebSocket для real-time сообщений
   - Интеграция с внешними провайдерами

2. **Frontend (React/TypeScript)**
   - Веб-интерфейс для управления чатами
   - Модальные окна и встроенные компоненты

3. **Android приложение**
   - Мобильный клиент для Android устройств
   - Полная функциональность чата

4. **База данных**
   - PostgreSQL с TypeORM
   - Комплексная схема для чатов, сообщений, пользователей

## Backend API

### Детальная спецификация API

#### MultichatController (`/chat`)
Основной контроллер для общих операций с чатами.

```typescript
@ApiTags('multichat')
@Controller('chat')
@JwtAuthorized()
export class MultichatController {
  // Получение количества непрочитанных сообщений
  @Get('unseen-count')
  async getUnseenCount(): Promise<number>

  // Обновление статуса сообщений для всех чатов
  @Put('status/:status')
  async updateMessagesStatus()
}
```

##### GET /chat/unseen-count
**Описание:** Получить общее количество непрочитанных сообщений для текущего пользователя.

**Аутентификация:** JWT токен обязательна

**Параметры:** Нет

**Ответ:**
```json
{
  "statusCode": 200,
  "data": 5
}
```

##### PUT /chat/status/{status}
**Описание:** Обновить статус всех сообщений во всех чатах пользователя.

**Аутентификация:** JWT токен обязательна

**Параметры пути:**
- `status` (string): Новый статус (received/seen)

**Тело запроса:**
```json
{
  "accountId": 1,
  "user": {...},
  "status": "seen"
}
```

**Ответ:**
```json
{
  "statusCode": 200,
  "message": "Messages status updated"
}
```

#### ChatController (`/chat/chats`)
Контроллер для операций с конкретными чатами.

**Создание чатов:**
- `POST /personal` - персональный чат
- `POST /group` - групповой чат
- `POST /external` - внешний чат

**Получение чатов:**
- `GET /` - список чатов с пагинацией
- `GET /find` - простой поиск
- `GET /find/full` - полный поиск с дополнительными данными
- `GET /find/full/personal` - поиск по имени пользователя
- `GET /find/full/by-message-content` - поиск по содержимому сообщений
- `GET /:chatId` - получение конкретного чата

**Управление чатами:**
- `PATCH /group/:chatId` - обновление группового чата
- `DELETE /:chatId` - удаление чата
- `PUT /:chatId/pin/:messageId` - закрепление сообщения
- `PUT /:chatId/unpin/:messageId` - открепление сообщения
- `PUT /:chatId/status/:status` - обновление статуса сообщений в чате

**Дополнительные операции:**
- `POST /:chatId/contact` - создание контакта и лида

#### ChatMessageController (`/chat/chats/:chatId/messages`)
Контроллер для работы с сообщениями в чате.

**Операции с сообщениями:**
- `POST /` - отправка сообщения
- `GET /` - получение списка сообщений
- `GET /:messageId` - получение конкретного сообщения
- `PUT /:messageId` - редактирование сообщения
- `DELETE /:messageId` - удаление сообщения

**Статусы сообщений:**
- `POST /status/:status` - обновление статуса нескольких сообщений
- `PUT /:messageId/status/:status` - обновление статуса одного сообщения

**Реакции:**
- `PUT /:messageId/react/:reaction` - добавление реакции
- `PUT /:messageId/unreact/:reactionId` - удаление реакции

#### ChatProviderController (`/chat/providers`)
Контроллер для работы с провайдерами чатов.

```typescript
@ApiTags('multichat/providers')
@Controller('chat/providers')
@JwtAuthorized()
export class ChatProviderController {
  @Get()
  async findMany(): Promise<ChatProviderDto[]>
}
```

### Модели данных

#### Chat (Чат)
```typescript
export class ChatDto {
  id: number;                    // ID чата
  providerId: number;           // ID провайдера
  createdBy: number;            // ID создателя
  externalId: string | null;    // Внешний ID
  type: ChatType;               // Тип чата (PERSONAL/GROUP)
  title: string | null;         // Название
  entityId: number | null;      // ID связанной сущности
  createdAt: string;            // Дата создания
  users: ChatUserDto[];         // Пользователи чата
  pinnedMessages: ChatMessageDto[]; // Закрепленные сообщения
  lastMessage: ChatMessageDto | null; // Последнее сообщение
  unseenCount: number;          // Количество непрочитанных
  updatedAt: string;            // Дата обновления
  entityInfo: EntityInfoDto | null; // Информация о сущности
  hasAccess?: boolean | null;   // Доступ пользователя
}
```

#### ChatMessage (Сообщение)
```typescript
export class ChatMessageDto {
  id: number;                    // ID сообщения
  chatId: number;               // ID чата
  chatUserId: number;           // ID пользователя чата
  text: string | null;          // Текст сообщения
  replyToId: number | null;     // ID сообщения-ответа
  createdAt: string;            // Дата создания
  files: ChatMessageFileDto[];  // Прикрепленные файлы
  reactions: ChatMessageReactionDto[]; // Реакции
  status: ChatMessageStatus;    // Статус для текущего пользователя
}
```

#### ChatUser (Пользователь чата)
```typescript
export class ChatUserDto {
  id: number;                    // ID в чате
  chatId: number;               // ID чата
  userId: number | null;        // ID пользователя системы
  role: ChatUserRole;           // Роль в чате
  name: string | null;          // Имя
  avatarUrl: string | null;     // URL аватара
}
```

#### ChatProvider (Провайдер)
```typescript
export class ChatProviderDto {
  id: number;                    // ID провайдера
  type: ChatProviderType;       // Тип провайдера
  title: string;                // Название
  status: ChatProviderStatus;   // Статус
  transport: ChatProviderTransport; // Транспорт
  unseenCount: number;          // Непрочитанные сообщения
}
```

### Статусы и типы

#### ChatType
```typescript
export enum ChatType {
  PERSONAL = 'personal',  // Персональный чат между двумя пользователями
  GROUP = 'group'         // Групповой чат с множеством участников
}
```

#### ChatMessageStatus
```typescript
export enum ChatMessageStatus {
  RECEIVED = 'received',  // Сообщение получено
  SEEN = 'seen'           // Сообщение просмотрено
}
```

#### ChatProviderType
```typescript
export enum ChatProviderType {
  Amwork = 'amwork',      // Внутренняя система Amwork
  Twilio = 'twilio',     // Twilio WhatsApp
  Facebook = 'facebook', // Facebook Messenger
  Wazzup = 'wazzup'      // Wazzup WhatsApp
}
```

#### ChatProviderTransport
```typescript
export enum ChatProviderTransport {
  Amwork = 'amwork',      // Внутренняя система
  Whatsapp = 'whatsapp', // WhatsApp
  Messenger = 'messenger', // Facebook Messenger
  Telegram = 'telegram', // Telegram
  Instagram = 'instagram', // Instagram
  Vk = 'vk',             // VKontakte
  Avito = 'avito'        // Avito
}
```

#### ChatProviderStatus
```typescript
export enum ChatProviderStatus {
  Draft = 'draft',       // Черновик настройки
  Active = 'active',     // Активен
  Inactive = 'inactive', // Неактивен
  Deleted = 'deleted'    // Удален
}
```

#### ChatUserRole
```typescript
export enum ChatUserRole {
  OWNER = 'owner',       // Владелец чата
  ADMIN = 'admin',       // Администратор
  SUPERVISOR = 'supervisor', // Супервайзер
  USER = 'user',         // Обычный пользователь
  EXTERNAL = 'external'  // Внешний пользователь
}
```

### DTOs для создания чатов

#### CreatePersonalChatDto
```typescript
export class CreatePersonalChatDto {
  @ApiProperty({ description: 'Provider ID' })
  @IsNumber()
  providerId: number;

  @ApiProperty({ description: 'User ID of chat companion' })
  @IsNumber()
  companionId: number;
}
```

**Пример запроса:**
```json
{
  "providerId": 1,
  "companionId": 123
}
```

#### CreateGroupChatDto
```typescript
export class CreateGroupChatDto {
  @ApiProperty({ description: 'Provider ID' })
  @IsNumber()
  providerId: number;

  @ApiProperty({ description: 'Chat title' })
  @IsString()
  title: string;

  @ApiProperty({ description: 'User IDs of chat participants', type: [Number] })
  @IsArray()
  participantIds: number[];

  @ApiPropertyOptional({ description: 'Entity ID associated with the chat', nullable: true })
  @IsOptional()
  @IsNumber()
  entityId?: number | null;
}
```

**Пример запроса:**
```json
{
  "providerId": 1,
  "title": "Проект Alpha",
  "participantIds": [123, 456, 789],
  "entityId": 1001
}
```

### DTOs для сообщений

#### SendChatMessageDto
```typescript
export class SendChatMessageDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  replyToId?: number | null;

  @ApiProperty()
  @IsString()
  text: string;

  @ApiPropertyOptional({ nullable: true })
  @IsOptional()
  @IsArray()
  fileIds?: string[] | null;
}
```

**Пример запроса:**
```json
{
  "text": "Привет, как дела?",
  "replyToId": 123,
  "fileIds": ["file_123", "file_456"]
}
```

## База данных

### Основные таблицы

#### chat
```sql
CREATE TABLE public.chat (
    id integer NOT NULL,
    provider_id integer NOT NULL,
    created_by integer,
    external_id character varying,
    type character varying NOT NULL,
    title character varying,
    entity_id integer,
    account_id integer NOT NULL,
    created_at timestamp without time zone NOT NULL
);
```

#### chat_message
```sql
CREATE TABLE public.chat_message (
    id integer NOT NULL,
    chat_id integer NOT NULL,
    chat_user_id integer NOT NULL,
    external_id character varying,
    text text,
    account_id integer NOT NULL,
    created_at timestamp without time zone NOT NULL,
    reply_to_id integer
);
```

#### chat_user
```sql
CREATE TABLE public.chat_user (
    id integer NOT NULL,
    chat_id integer NOT NULL,
    user_id integer,
    role character varying NOT NULL,
    account_id integer NOT NULL
);
```

#### chat_provider
```sql
CREATE TABLE public.chat_provider (
    id integer NOT NULL,
    created_by integer,
    type character varying NOT NULL,
    title character varying NOT NULL,
    account_id integer NOT NULL,
    created_at timestamp without time zone NOT NULL,
    status character varying NOT NULL,
    transport character varying NOT NULL
);
```

#### chat_message_reaction
```sql
CREATE TABLE public.chat_message_reaction (
    id integer NOT NULL,
    message_id integer NOT NULL,
    chat_user_id integer NOT NULL,
    reaction character varying NOT NULL,
    account_id integer NOT NULL,
    created_at timestamp without time zone NOT NULL
);
```

#### chat_message_user_status
```sql
CREATE TABLE public.chat_message_user_status (
    chat_id integer NOT NULL,
    message_id integer NOT NULL,
    chat_user_id integer NOT NULL,
    status character varying NOT NULL,
    account_id integer NOT NULL,
    created_at timestamp without time zone NOT NULL
);
```

## Frontend

### Архитектура компонентов

Система чата построена на базе React с использованием контекстов для управления состоянием и кастомных хуков для работы с API.

#### MultichatProvider
Контекст-провайдер для глобального управления состоянием чата в приложении.

**Ключевые свойства:**
```typescript
interface MultichatContextValue {
  // Видимость модальных окон
  opened: boolean;
  pageOpened: boolean;
  hide: () => void;
  toggle: () => void;

  // Активный чат
  activeChatId: number | null;
  activeProviderId: number | null;
  setActiveChatId: (id: number | null) => void;
  setActiveProviderId: (id: number | null) => void;

  // Управление сообщениями
  editMessageId: number | null;
  replyToId: number | null;
  setEditMessageId: (id: number | null) => void;
  setReplyToId: (id: number | null) => void;

  // Навигация
  show: (params: { activeChatId?: number; activeProviderId?: number }) => void;
  openPage: (returnUrl?: string) => void;
  closePage: () => void;
}
```

**Использование:**
```tsx
const { show, opened, activeChatId } = useMultichatContext();

// Открыть чат
show({ activeChatId: 123, activeProviderId: 1 });

// Проверить видимость
if (opened) {
  // Показать модальное окно
}
```

#### MultichatModal
Модальное окно для отображения интерфейса чата в модальном режиме.

**Особенности:**
- Перетаскиваемое и изменяемое по размеру
- Адаптивный дизайн
- Сохранение позиции и размера
- Интеграция с основным UI

**Props:**
```typescript
interface MultichatModalProps {
  children?: ReactNode;
  modalBounds?: DraggableResizableControlBounds;
  setModalBounds?: (bounds: DraggableResizableControlBounds) => void;
}
```

#### MultichatControl
Основной контейнер управления чатом с боковой панелью и областью сообщений.

**Структура:**
```
MultichatControl
├── MultichatControlHeader (при модальном просмотре)
├── ChatsSidebar
│   ├── ChatList
│   ├── CreateAmworkChatButton
│   └── ProviderSelector
└── ChatMessagesPanel
    ├── ChatMessagesPanelHeader
    ├── ChatMessagesList
    └── SendChatMessageBlock
```

#### ChatMessagesPanel
Компонент для отображения и управления сообщениями в чате.

**Ключевые функции:**
- Ленивая загрузка сообщений
- Автоматическая прокрутка к новым сообщениям
- Отметка сообщений как прочитанные
- Обработка реакций и ответов

**Props:**
```typescript
interface ChatMessagesPanelProps {
  activeChatId: number;
  mobileView?: boolean;
  providers?: ChatProvider[];
  activeProvider?: ChatProvider;
  modalWidth?: string;
  onBack?: () => void;
}
```

#### SendChatMessageBlock
Компонент для отправки сообщений с поддержкой различных типов контента.

**Возможности:**
- Текстовые сообщения
- Файловые вложения (drag & drop)
- Ответы на сообщения
- Редактирование сообщений
- Отправка через Enter или кнопку

**Состояния:**
- Обычное сообщение
- Ответ на сообщение
- Редактирование сообщения
- Отправка файла

### Кастомные хуки

#### useGetChat
Получение данных о конкретном чате.

```typescript
const { data: chat, isLoading, error } = useGetChat(chatId);
```

#### useGetChatMessages
Получение сообщений чата с пагинацией.

```typescript
const {
  data: messages,
  hasNextPage,
  fetchNextPage,
  isLoading
} = useGetChatMessages(chatId);
```

#### useSendChatMessage
Отправка сообщений в чат.

```typescript
const { mutateAsync: sendMessage, isPending } = useSendChatMessage({
  chatId,
  providerId
});

// Отправка
await sendMessage({
  text: "Привет!",
  fileIds: ["file_123"]
});
```

#### useCreateGroupChat
Создание группового чата.

```typescript
const { mutateAsync: createChat } = useCreateGroupChat();

// Создание
const newChat = await createChat({
  providerId: 1,
  title: "Новый проект",
  participantIds: [123, 456]
});
```

### API интеграция

#### ChatApi
Основной API клиент для работы с чатами:

```typescript
export const chatApi = {
  // Получение чатов
  getChats: (params: CursorPagingQuery) =>
    api.get('/chat/chats', { params }),

  getChat: (chatId: number) =>
    api.get(`/chat/chats/${chatId}`),

  // Создание чатов
  createPersonalChat: (data: CreatePersonalChatDto) =>
    api.post('/chat/chats/personal', data),

  createGroupChat: (data: CreateGroupChatDto) =>
    api.post('/chat/chats/group', data),

  createExternalChat: (data: CreateExternalChatDto) =>
    api.post('/chat/chats/external', data),

  // Поиск чатов
  findChats: (params: { filter: ChatFindFilterDto; paging: PagingQuery }) =>
    api.get('/chat/chats/find', { params }),

  findChatsFull: (params: { filter: ChatFindFilterDto; paging: PagingQuery }) =>
    api.get('/chat/chats/find/full', { params }),

  // Сообщения
  getChatMessages: (chatId: number, params: ChatMessagesFilterDto & PagingQuery) =>
    api.get(`/chat/chats/${chatId}/messages`, { params }),

  sendMessage: (chatId: number, data: SendChatMessageDto) =>
    api.post(`/chat/chats/${chatId}/messages`, data),

  updateMessage: (chatId: number, messageId: number, data: SendChatMessageDto) =>
    api.put(`/chat/chats/${chatId}/messages/${messageId}`, data),

  deleteMessage: (chatId: number, messageId: number) =>
    api.delete(`/chat/chats/${chatId}/messages/${messageId}`),

  // Статусы
  markAllChatMessagesAsRead: (chatId: number) =>
    api.put(`/chat/chats/${chatId}/status/read`),

  updateMessageStatus: (chatId: number, messageId: number, status: ChatMessageStatus) =>
    api.put(`/chat/chats/${chatId}/messages/${messageId}/status/${status}`),

  // Реакции
  reactToMessage: (chatId: number, messageId: number, reaction: string) =>
    api.put(`/chat/chats/${chatId}/messages/${messageId}/react/${reaction}`),

  unreactToMessage: (chatId: number, messageId: number, reactionId: number) =>
    api.put(`/chat/chats/${chatId}/messages/${messageId}/unreact/${reactionId}`),

  // Управление чатами
  updateGroupChat: (chatId: number, data: UpdateGroupChatDto) =>
    api.patch(`/chat/chats/group/${chatId}`, data),

  deleteChat: (chatId: number) =>
    api.delete(`/chat/chats/${chatId}`),

  pinMessage: (chatId: number, messageId: number) =>
    api.put(`/chat/chats/${chatId}/pin/${messageId}`),

  unpinMessage: (chatId: number, messageId: number) =>
    api.put(`/chat/chats/${chatId}/unpin/${messageId}`),

  // Провайдеры
  getChatProviders: () =>
    api.get('/chat/providers'),

  // Счетчики
  getUnseenCount: () =>
    api.get('/chat/unseen-count'),
};
```

### React Query интеграция

Система использует React Query для кеширования и синхронизации данных:

```typescript
// Ключи запросов
export const MULTICHAT_QUERY_KEYS = {
  chats: ['multichat', 'chats'] as const,
  chat: (chatId: number) => ['multichat', 'chats', chatId] as const,
  chatMessages: (chatId: number) => ['multichat', 'chats', chatId, 'messages'] as const,
  chatProviders: ['multichat', 'providers'] as const,
  unseenCount: ['multichat', 'unseen-count'] as const,
} as const;

// Инвалидация кеша
queryClient.invalidateQueries({ queryKey: MULTICHAT_QUERY_KEYS.chats });
```

### Стилизация

Компоненты используют styled-components с поддержкой тем:

```typescript
const Root = styled.div`
  background-color: var(--graphite-graphite-20);
  border-radius: 8px;

  ${p => p.$mobileView && css`
    width: calc(100vw - var(--sidebar-width));
  `}
`;
```

### Обработка событий

Система поддерживает real-time обновления через WebSocket события:

```typescript
// Обработчик событий чата
const chatEventHandler = {
  subscribe: (context: MultichatContextValue) => {
    // Подписка на события
  },

  unsubscribe: () => {
    // Отписка от событий
  }
};
```

## Android приложение

### Архитектура

Приложение построено на базе **MVVM** архитектуры с использованием **Android Architecture Components**:

- **Activities/Fragments** - представление данных
- **ViewModels** - бизнес-логика и управление состоянием
- **Repositories** - абстракция доступа к данным
- **Retrofit** - HTTP клиент для API
- **Room** - локальная база данных (опционально)
- **WorkManager** - фоновая синхронизация

### Основные Activity

#### ChatActivity
Основная активность для отображения чата с полным жизненным циклом управления.

**Жизненный цикл:**
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityChatBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // Инициализация ViewModel
    viewModel.initialize(serverUrl, token, apiKey, chatId)

    // Настройка UI компонентов
    setupViews()
    observeViewModel()
    observeAddressBook()
}

override fun onResume() {
    super.onResume()
    viewModel.setChatActive(true) // Активация чата
}

override fun onPause() {
    super.onPause()
    viewModel.setChatActive(false) // Деактивация чата
}
```

**Основные функции:**
- Отображение списка сообщений с `RecyclerView`
- Отправка текстовых сообщений
- Отправка файлов через `FilePicker`
- Ответы на сообщения с визуальным индикатором
- Автоматическая отметка сообщений как прочитанные при прокрутке
- Управление прикрепленными файлами

**Ключевые компоненты:**
- `MessageAdapter` - адаптер для `RecyclerView` с поддержкой разных типов сообщений
- `ChatViewModel` - управление состоянием чата и бизнес-логикой
- `NotificationHelper` - обработка push-уведомлений
- `BackgroundSyncWorker` - фоновая синхронизация

#### MainActivity
Главная активность с навигацией и списком чатов.

**Особенности:**
- `BottomNavigationView` для переключения разделов
- `SwipeRefreshLayout` для обновления списка чатов
- `FloatingActionButton` для создания новых чатов
- Управление жизненным циклом всех чатов

#### CreateChatActivity
Активность для создания новых чатов с пошаговым мастером.

**Этапы создания:**
1. Выбор типа чата (персональный/групповой)
2. Выбор участников через `UserSelectionActivity`
3. Настройка параметров чата
4. Создание и переход к чату

### ViewModels

#### ChatViewModel
Управляет состоянием конкретного чата и сообщениями.

**Состояния:**
```kotlin
sealed class ChatState {
    object Loading : ChatState()
    data class Success(val chat: Chat) : ChatState()
    data class Error(val message: String) : ChatState()
}

sealed class MessagesState {
    object Loading : MessagesState()
    data class Success(val messages: List<ChatMessage>) : MessagesState()
    data class Error(val message: String) : MessagesState()
}

sealed class SendMessageState {
    object Loading : SendMessageState()
    object Success : SendMessageState()
    data class Error(val message: String) : SendMessageState()
}
```

**Ключевые методы:**
```kotlin
// Загрузка данных чата
fun refreshChat()

// Загрузка сообщений
fun refreshMessages()

// Отправка сообщения
fun sendMessage(text: String, replyToMessage: ChatMessage?, fileIds: List<String>? = null)

// Отправка файла
fun sendFileMessage(uri: Uri, contentResolver: ContentResolver)

// Отметка как прочитанное
fun markMessagesAsRead()

// Управление активностью чата
fun setChatActive(active: Boolean)
```

#### MainViewModel
Глобальная ViewModel для управления приложением.

**Функции:**
- Управление списком чатов
- Кеширование данных пользователей (адресная книга)
- Синхронизация состояния между активностями
- Управление подключением к серверу

**Ключевые методы:**
```kotlin
// Получение имени пользователя
fun getUserName(userId: Long): String

// Получение URL аватара
fun getUserAvatarUrl(userId: Long): String?

// Уведомление об обновлении чата
fun notifyChatUpdated(chatId: Long)

// Управление адресной книгой
fun refreshAddressBook()
```

### Репозитории

#### ChatRepository
Репозиторий для работы с API чатов с поддержкой кеширования.

**Основные методы:**
```kotlin
suspend fun getChats(): Result<List<Chat>>
suspend fun getChat(chatId: Long): Result<Chat>
suspend fun getMessages(chatId: Long, limit: Int = 50, offset: Long? = null): Result<List<ChatMessage>>
suspend fun sendMessage(chatId: Long, message: SendChatMessageDto): Result<ChatMessage>
suspend fun uploadFile(uri: Uri, contentResolver: ContentResolver): Result<List<UploadedFile>>
suspend fun markAsRead(chatId: Long): Result<Unit>
suspend fun updateMessageStatus(chatId: Long, messageId: Long, status: ChatMessageStatus): Result<Unit>
```

**Обработка ошибок:**
```kotlin
sealed class Result<T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Failure<T>(val exception: Throwable) : Result<T>()
}
```

### Модели данных

#### ChatRequests.kt
DTO для запросов к API:

```kotlin
data class CreatePersonalChatRequest(
    val providerId: Long,
    val companionId: Long
)

data class CreateGroupChatRequest(
    val providerId: Long,
    val title: String,
    val participantIds: List<Long>,
    val entityId: Long? = null
)

data class UpdateGroupChatRequest(
    val title: String? = null,
    val participantIds: List<Long>? = null
)
```

#### ChatModels.kt
Основные модели данных приложения:

```kotlin
data class Chat(
    val id: Long,
    val providerId: Long,
    val type: String,
    val title: String?,
    val users: List<ChatUserItem>,
    val lastMessage: ChatMessage?,
    val unseenCount: Int,
    val createdAt: String
)

data class ChatMessage(
    val id: Long,
    val chatId: Long,
    val chatUserId: Long,
    val text: String?,
    val replyToId: Long?,
    val files: List<ChatMessageFile>,
    val reactions: List<ChatMessageReaction>,
    val status: ChatMessageStatus,
    val createdAt: String
)

data class ChatUserItem(
    val id: Long,
    val userId: Long?,
    val name: String?,
    val avatarUrl: String?
)
```

### UI Компоненты

#### MessageAdapter
Адаптер для отображения сообщений в `RecyclerView`.

**Типы ViewHolder:**
- `TextMessageViewHolder` - текстовые сообщения
- `FileMessageViewHolder` - сообщения с файлами
- `ReplyMessageViewHolder` - ответы на сообщения
- `SystemMessageViewHolder` - системные сообщения

**Особенности:**
- Поддержка разных типов сообщений через `getItemViewType()`
- Оптимизация производительности с `DiffUtil`
- Обработка кликов и долгого нажатия
- Анимации для новых сообщений

#### MessageAdapter.kt
```kotlin
class MessageAdapter(
    private val getUserName: (Long) -> String,
    private val chatUsers: List<ChatUserItem>?,
    private val onScrollToMessage: (Long) -> Unit,
    private val onReplyToMessage: (ChatMessage) -> Unit,
    private val serverUrl: String,
    private val token: String?,
    private val apiKey: String?
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private val messages = mutableListOf<ChatMessage>()

    fun submitList(newMessages: List<ChatMessage>) {
        val diffResult = DiffUtil.calculateDiff(MessageDiffCallback(messages, newMessages))
        messages.clear()
        messages.addAll(newMessages)
        diffResult.dispatchUpdatesTo(this)
    }
}
```

### Background Sync

#### BackgroundSyncWorker
Worker для фоновой синхронизации данных.

**Функции:**
- Периодическая проверка новых сообщений
- Обновление уведомлений
- Синхронизация аватаров пользователей
- Обработка оффлайн режима

**Конфигурация:**
```kotlin
val syncWork = PeriodicWorkRequestBuilder<BackgroundSyncWorker>(
    15, TimeUnit.MINUTES // Синхронизация каждые 15 минут
)
.addConstraints(
    Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()
)
.build()
```

### Уведомления

#### NotificationHelper
Управление push-уведомлениями и локальными уведомлениями.

**Функции:**
- Создание уведомлений о новых сообщениях
- Группировка уведомлений по чатам
- Кастомные звуки и вибрация
- Deep linking в конкретные чаты

```kotlin
fun showMessageNotification(
    chatId: Long,
    message: ChatMessage,
    senderName: String,
    chatTitle: String
) {
    val intent = Intent(context, ChatActivity::class.java).apply {
        putExtra("chat_id", chatId)
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }

    val pendingIntent = PendingIntent.getActivity(
        context, chatId.toInt(), intent, PendingIntent.FLAG_IMMUTABLE
    )

    val notification = NotificationCompat.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentTitle(chatTitle)
        .setContentText("$senderName: ${message.text}")
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)
        .build()

    notificationManager.notify(chatId.toInt(), notification)
}
```

### Работа с файлами

#### File Handling
Обработка загрузки и отображения файлов.

**Поддерживаемые операции:**
- Выбор файлов через `Intent.ACTION_GET_CONTENT`
- Загрузка файлов на сервер
- Отображение превью изображений
- Скачивание файлов
- Управление разрешениями на хранение

```kotlin
private fun uploadFileAndSendMessage(message: String) {
    selectedFileUri?.let { uri ->
        lifecycleScope.launch {
            try {
                val result = ChatRepository(apiClient).uploadFile(uri, contentResolver)
                result.fold(
                    onSuccess = { files ->
                        viewModel.sendMessage(message, replyingToMessage, files.map { it.id })
                        clearFileSelection()
                    },
                    onFailure = { error ->
                        Toast.makeText(this@ChatActivity, "Upload failed: ${error.message}", Toast.LENGTH_SHORT).show()
                    }
                )
            } catch (e: Exception) {
                Toast.makeText(this@ChatActivity, "Error: ${e.message}", Toast.LENGTH_SHORT).show()
            }
        }
    }
}
```

### Темизация и локализация

**Поддержка тем:**
- Светлая тема
- Темная тема
- Системная тема

**Локализация:**
- Русский язык
- Английский язык
- Поддержка RTL для арабского и иврита

### Производительность

**Оптимизации:**
- ViewBinding вместо findViewById
- DiffUtil для RecyclerView
- Кеширование изображений с Glide
- Пейджинг для больших списков
- Background threading для тяжелых операций

## Интеграция с внешними провайдерами

### Поддерживаемые провайдеры

1. **Facebook Messenger**
   - Требует: `page_id`, `page_access_token`, `user_access_token`
   - Транспорт: `messenger`

2. **Telegram**
   - Интеграция через Telegram API

3. **WhatsApp (Twilio)**
   - Требует: `account_sid`, `auth_token`, `phone_number`
   - Транспорт: `whatsapp`

4. **Whazzup**
   - Требует: `api_key`, `channel_id`, `plain_id`
   - Транспорт: `whatsapp`

### Настройка провайдеров

Провайдеры настраиваются через интерфейс интеграций в разделе "Settings > Integrations".

## Безопасность

### Аутентификация
- JWT токены для API запросов
- Проверка прав доступа на уровне аккаунта
- Валидация принадлежности пользователя к чату

### Авторизация
- Проверка доступа к чатам
- Ролевая модель для групповых чатов
- Ограничение действий с сообщениями

## Real-time обновления

### WebSocket
- Автоматическое обновление сообщений
- Статусы прочтения в реальном времени
- Уведомления о новых сообщениях

### Background Sync (Android)
- `BackgroundSyncWorker` для синхронизации в фоне
- Обновление уведомлений
- Синхронизация аватаров пользователей

## Файловые вложения

### Поддерживаемые форматы
- Изображения, документы, видео, аудио
- Максимальный размер файла настраивается

### Загрузка файлов
- Backend: хранение в файловом хранилище
- Frontend: drag & drop, выбор файла
- Android: выбор из галереи/файлового менеджера

### Безопасность файлов
- Валидация MIME типов
- Сканирование на вирусы (опционально)
- Ограничение доступа по ссылкам

## Поиск и фильтрация

### Поиск чатов
- По имени пользователя (персональные чаты)
- По содержимому сообщений
- По связанным сущностям
- Фильтрация по провайдеру

### Полнотекстовый поиск
- Индексы в базе данных
- Поиск по тексту сообщений
- Поддержка регулярных выражений

## Мониторинг и логирование

### Метрики
- Количество активных чатов
- Статистика сообщений
- Производительность API

### Логи
- Детальное логирование API запросов
- Ошибки интеграции с провайдерами
- Аудит действий пользователей

## Расширение системы

### Добавление нового провайдера
1. Создать конфигурацию провайдера в базе данных
2. Реализовать интеграцию в `ChatProviderService`
3. Добавить DTO для настроек
4. Создать миграцию для новой таблицы провайдера
5. Обновить UI для настройки

### Кастомизация UI
- Темизация компонентов
- Кастомные аватары
- Дополнительные поля в сообщениях

## Заключение

Система чата предоставляет полнофункциональное решение для коммуникации в CRM, поддерживая множественные каналы связи, real-time обновления и интеграцию с бизнес-логикой системы. Архитектура обеспечивает масштабируемость, безопасность и гибкость для будущих расширений.
