'use client';

import { useRef } from 'react';
import { useRouter } from 'next/navigation';
import {
  ArrowLeft,
  FileDown,
  Printer,
  Table2,
  Smartphone,
  CheckCircle2,
  XCircle,
  AlertTriangle,
  Zap,
  Shield,
  Server,
  Send,
  Link2,
  Layers,
  ArrowRight,
  QrCode,
  Database,
  Globe,
  Lock,
  RefreshCw,
  Wifi,
} from 'lucide-react';
import { cn } from '@/lib/cn';

const LAST_UPDATE = '21 февраля 2026';

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: АНАЛИЗ ПРОБЛЕМЫ
   ═══════════════════════════════════════════════════════════════ */

interface GapItem {
  channel: string;
  icon: string;
  currentApproach: string;
  problem: string;
  writeFirst: boolean;
  ownNumber: boolean;
  clientExperience: string;
}

const currentGaps: GapItem[] = [
  {
    channel: 'WhatsApp',
    icon: '💬',
    currentApproach: 'Meta Cloud API (WhatsApp Business API)',
    problem: 'Требует верификации бизнеса Meta (2-4 недели), HSM-шаблоны для первого сообщения (24-часовое окно), per-conversation pricing от Meta',
    writeFirst: true,
    ownNumber: false,
    clientExperience: 'Клиент видит «бизнес-аккаунт» с логотипом, а не живой номер телефона клуба',
  },
  {
    channel: 'Telegram',
    icon: '✈️',
    currentApproach: 'Telegram Bot API',
    problem: 'Клиент обязан сам нажать /start у бота. Клуб НЕ МОЖЕТ написать первым. Бот не выглядит как живой контакт — клиенты игнорируют',
    writeFirst: false,
    ownNumber: false,
    clientExperience: 'Клиент видит бота «@FitClubBot», а не номер телефона клуба +7(XXX)...',
  },
  {
    channel: 'VK',
    icon: '🔵',
    currentApproach: 'VK Community API (сообщения сообщества)',
    problem: 'Сообщения идут от имени группы/сообщества. Клиент должен подписаться на сообщество и разрешить сообщения',
    writeFirst: false,
    ownNumber: false,
    clientExperience: 'Клиент видит сообщение от «Фитнес-клуб X» (группа), а не от номера телефона',
  },
  {
    channel: 'MAX (ex-OK)',
    icon: '🟡',
    currentApproach: 'MAX Bot API',
    problem: 'Аналогично Telegram Bot API — только бот, клиент должен сам начать диалог',
    writeFirst: false,
    ownNumber: false,
    clientExperience: 'Бот, малая аудитория, низкая конверсия',
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: АНАЛИЗ WHAPI.CLOUD
   ═══════════════════════════════════════════════════════════════ */

interface WhapiFeature {
  feature: string;
  description: string;
  ourAnalog: string;
  complexity: 'low' | 'medium' | 'high';
}

const whapiAnalysis: WhapiFeature[] = [
  {
    feature: 'QR-авторизация (Linked Device)',
    description: 'Подключение реального WhatsApp-номера через сканирование QR-кода. Используется протокол WhatsApp Multi-Device (MD)',
    ourAnalog: 'Baileys (TypeScript) / whatsmeow (Go) — open-source библиотеки для WhatsApp Web Multi-Device протокола',
    complexity: 'medium',
  },
  {
    feature: 'Отправка первым (Outbound)',
    description: 'Отправка сообщений любому номеру без HSM-шаблонов. Сообщение приходит от реального номера клуба',
    ourAnalog: 'Baileys: sendMessage(jid, { text }) — прямая отправка без ограничений Meta',
    complexity: 'low',
  },
  {
    feature: 'Приём входящих (Inbound)',
    description: 'Webhook при входящем сообщении. Real-time delivery через WebSocket',
    ourAnalog: 'Baileys: ev.on("messages.upsert") → webhook → Unified Inbox',
    complexity: 'low',
  },
  {
    feature: 'Медиа (фото, видео, документы)',
    description: 'Отправка и приём изображений, видео, PDF, аудио, стикеров',
    ourAnalog: 'Baileys: sendMessage с mediaMessage (image, video, document, audio, sticker)',
    complexity: 'low',
  },
  {
    feature: 'Статусы доставки',
    description: 'Отслеживание: sent → delivered → read. Webhook-уведомления',
    ourAnalog: 'Baileys: ev.on("messages.update") → статус ACK (sent/delivered/read)',
    complexity: 'low',
  },
  {
    feature: 'Мульти-номер (несколько клубов)',
    description: 'Каждый клуб подключает свой номер. Изолированные сессии. До 100+ номеров на инстансе',
    ourAnalog: 'Один инстанс Gateway = один номер. Оркестратор: Docker-контейнер per-club или namespace-изоляция',
    complexity: 'high',
  },
  {
    feature: 'Персистентная сессия',
    description: 'Сессия сохраняется между перезагрузками. Не нужно повторно сканировать QR',
    ourAnalog: 'Baileys: useMultiFileAuthState() — сохранение creds + keys в файловой системе / Redis / PostgreSQL',
    complexity: 'medium',
  },
  {
    feature: 'REST API + Webhooks',
    description: 'HTTP-based API для отправки. Webhooks для входящих. Bearer-токен авторизация',
    ourAnalog: 'NestJS REST-контроллер + BullMQ очередь + WebSocket Gateway',
    complexity: 'medium',
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: АРХИТЕКТУРА РЕШЕНИЯ
   ═══════════════════════════════════════════════════════════════ */

interface ChannelSolution {
  channel: string;
  icon: string;
  library: string;
  protocol: string;
  writeFirst: boolean;
  ownNumber: boolean;
  authMethod: string;
  features: string[];
  risks: string[];
  license: string;
}

const channelSolutions: ChannelSolution[] = [
  {
    channel: 'WhatsApp',
    icon: '💬',
    library: 'Baileys (TypeScript, MIT)',
    protocol: 'WhatsApp Web Multi-Device (Signal Protocol, Noise Framework)',
    writeFirst: true,
    ownNumber: true,
    authMethod: 'QR-код → Linked Device Session → Persistent Auth State',
    features: [
      'Отправка первым любому номеру (без HSM, без 24ч окна)',
      'Приём входящих сообщений в реальном времени',
      'Медиа: фото, видео, документы, аудио, стикеры',
      'Статусы: sent → delivered → read (ACK)',
      'Контакты и группы (чтение)',
      'Reaction (реакции на сообщения)',
      'Цитирование / ответ на сообщение',
      'Форматирование: bold, italic, strikethrough, monospace',
    ],
    risks: [
      'WhatsApp может заблокировать номер при спам-рассылках (rate limit рекомендация: ≤ 200 msg/день)',
      'Baileys — unofficial API, может сломаться при обновлении протокола WhatsApp',
      'Требуется SIM-карта с WhatsApp на каждый клуб',
      'Нет SLA от WhatsApp — нужен мониторинг сессий',
    ],
    license: 'MIT (Baileys) — свободное использование',
  },
  {
    channel: 'Telegram',
    icon: '✈️',
    library: 'GramJS (TypeScript, MIT) / TDLib (C++, Boost)',
    protocol: 'MTProto 2.0 (Telegram Client API, не Bot API)',
    writeFirst: true,
    ownNumber: true,
    authMethod: 'Номер телефона → SMS/Call код → 2FA пароль → Session',
    features: [
      'Отправка первым по номеру телефона (resolvePhone → sendMessage)',
      'Клиент видит сообщение от реального номера клуба, а не от бота',
      'Приём входящих сообщений (event handler)',
      'Медиа: фото, видео, документы, голосовые',
      'Inline-кнопки (через Bot API гибрид)',
      'Чтение/запись контактов',
      'Статусы: отправлено, прочитано',
    ],
    risks: [
      'Telegram ToS: запрет на спам с userbot. Необходим rate limiting (≤ 30 msg/сек)',
      'Flood wait ошибки при превышении лимитов (420 FLOOD_WAIT_X)',
      'Требуется выделенный номер телефона (SIM) для каждого клуба',
      'При первом сообщении незнакомому контакту: Telegram может запросить captcha у получателя',
      'GramJS — community-maintained, нужен мониторинг совместимости с Telegram updates',
    ],
    license: 'MIT (GramJS) / Boost (TDLib)',
  },
  {
    channel: 'VK',
    icon: '🔵',
    library: 'vk-io (TypeScript, MIT)',
    protocol: 'VK API v5.199 (User Token + Implicit Flow)',
    writeFirst: true,
    ownNumber: true,
    authMethod: 'OAuth 2.0 (Implicit Flow) → User Access Token с правами messages',
    features: [
      'Отправка от имени пользователя (не сообщества)',
      'Клиент видит сообщение от «Иван Менеджер клуба», а не от группы',
      'Приём входящих через Long Poll / Callback API',
      'Медиа: фото, документы, аудио',
      'Клавиатура с кнопками',
    ],
    risks: [
      'VK активно борется со спамом от user-аккаунтов — капча, блокировки',
      'Необходим верифицированный аккаунт VK (привязка телефона)',
      'User Token имеет ограниченный срок действия — нужен refresh',
      'Рекомендуется использовать Community API (группы) как fallback',
    ],
    license: 'MIT (vk-io)',
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: PRISMA-МОДЕЛИ (новые/расширенные)
   ═══════════════════════════════════════════════════════════════ */

interface PrismaModel {
  name: string;
  isNew: boolean;
  fields: { name: string; type: string; description: string }[];
}

const gatewayPrismaModels: PrismaModel[] = [
  {
    name: 'ChannelSession',
    isNew: true,
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'clubId', type: 'String', description: 'Привязка к клубу (multi-tenancy)' },
      { name: 'channel', type: 'MessengerChannel', description: 'WHATSAPP | TELEGRAM | VK' },
      { name: 'phoneNumber', type: 'String', description: 'Номер телефона клуба (привязанный)' },
      { name: 'status', type: 'SessionStatus', description: 'QR_PENDING | CONNECTED | DISCONNECTED | BANNED' },
      { name: 'authState', type: 'Json', description: 'Зашифрованные credentials сессии (Baileys creds / TDLib session)' },
      { name: 'qrCode', type: 'String?', description: 'Текущий QR-код (для WhatsApp) — Base64' },
      { name: 'qrExpiresAt', type: 'DateTime?', description: 'Время истечения QR-кода (60 сек)' },
      { name: 'lastActiveAt', type: 'DateTime?', description: 'Последняя активность сессии' },
      { name: 'errorMessage', type: 'String?', description: 'Ошибка при отключении/бане' },
      { name: 'metadata', type: 'Json?', description: 'Доп. данные (pushName, profilePic URL)' },
      { name: 'createdAt', type: 'DateTime @default(now())', description: 'Дата создания' },
      { name: 'updatedAt', type: 'DateTime @updatedAt', description: 'Дата обновления' },
    ],
  },
  {
    name: 'GatewayInstance',
    isNew: true,
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'sessionId', type: 'String @unique', description: 'FK → ChannelSession' },
      { name: 'containerId', type: 'String?', description: 'Docker container ID (для изоляции)' },
      { name: 'host', type: 'String', description: 'Hostname/IP инстанса шлюза' },
      { name: 'port', type: 'Int', description: 'Порт REST API инстанса' },
      { name: 'healthStatus', type: 'HealthStatus', description: 'HEALTHY | UNHEALTHY | STARTING | STOPPED' },
      { name: 'lastHealthCheck', type: 'DateTime?', description: 'Последний health check' },
      { name: 'memoryMb', type: 'Int?', description: 'Потребление памяти (мониторинг)' },
      { name: 'messagesPerDay', type: 'Int @default(0)', description: 'Счётчик сообщений за день (rate limit)' },
      { name: 'createdAt', type: 'DateTime @default(now())', description: 'Дата создания' },
    ],
  },
  {
    name: 'MessageQueue (расширение)',
    isNew: false,
    fields: [
      { name: 'gatewayInstanceId', type: 'String?', description: 'FK → GatewayInstance (через какой шлюз отправлять)' },
      { name: 'senderPhone', type: 'String?', description: 'Номер телефона отправителя (клуба)' },
      { name: 'recipientPhone', type: 'String', description: 'Номер телефона получателя (клиента)' },
      { name: 'isFirstMessage', type: 'Boolean @default(false)', description: 'Первое сообщение (писать первым)' },
      { name: 'deliveryMethod', type: 'DeliveryMethod', description: 'GATEWAY | BOT_API | BUSINESS_API' },
    ],
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: API ЭНДПОИНТЫ (новые)
   ═══════════════════════════════════════════════════════════════ */

interface ApiEndpoint {
  method: string;
  path: string;
  description: string;
  roles: string;
}

const gatewayApiEndpoints: ApiEndpoint[] = [
  { method: 'POST', path: '/v1/gateway/sessions', description: 'Создать сессию шлюза для канала (инициация подключения номера)', roles: 'club_admin' },
  { method: 'GET', path: '/v1/gateway/sessions', description: 'Список сессий клуба (все подключённые номера)', roles: 'club_admin' },
  { method: 'GET', path: '/v1/gateway/sessions/:id', description: 'Детали сессии (статус, номер, здоровье)', roles: 'club_admin' },
  { method: 'GET', path: '/v1/gateway/sessions/:id/qr', description: 'Получить текущий QR-код для сканирования (WhatsApp)', roles: 'club_admin' },
  { method: 'POST', path: '/v1/gateway/sessions/:id/auth', description: 'Отправить код авторизации (Telegram: SMS-код + 2FA)', roles: 'club_admin' },
  { method: 'DELETE', path: '/v1/gateway/sessions/:id', description: 'Отключить сессию (logout + удаление credentials)', roles: 'club_admin' },
  { method: 'POST', path: '/v1/gateway/sessions/:id/reconnect', description: 'Переподключить сессию (после disconnect)', roles: 'club_admin' },
  { method: 'GET', path: '/v1/gateway/sessions/:id/health', description: 'Health check сессии и инстанса шлюза', roles: 'club_admin, super_admin' },
  { method: 'POST', path: '/v1/messaging/send-first', description: 'Отправить первое сообщение клиенту через шлюз (с номера клуба)', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'GET', path: '/v1/gateway/stats', description: 'Статистика шлюза: сообщения/день, здоровье сессий, rate limits', roles: 'club_admin, super_admin' },
  { method: 'GET', path: '/v1/admin/gateway/instances', description: 'Все инстансы шлюзов (мониторинг платформы)', roles: 'super_admin' },
  { method: 'POST', path: '/v1/admin/gateway/instances/:id/restart', description: 'Перезапуск инстанса шлюза', roles: 'super_admin' },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: ФАЗЫ РЕАЛИЗАЦИИ
   ═══════════════════════════════════════════════════════════════ */

interface PhaseItem {
  phase: string;
  timeline: string;
  deliverables: string[];
  priority: 'P0' | 'P1' | 'P2';
}

const gatewayPhases: PhaseItem[] = [
  {
    phase: 'Фаза 0: WhatsApp Gateway MVP',
    timeline: '3-4 недели',
    priority: 'P0',
    deliverables: [
      'Микросервис wa-gateway на Baileys (TypeScript, NestJS)',
      'QR-авторизация: WebSocket → UI для сканирования',
      'Persistent auth state (PostgreSQL / Redis)',
      'REST API: /send, /status, /webhook (входящие)',
      'Prisma: ChannelSession, GatewayInstance',
      'Docker-контейнер с health check',
      'Интеграция с Unified Inbox (из ТЗ #42)',
      'Rate limiting: ≤ 200 msg/день per-номер',
      'Unit + интеграционные тесты',
    ],
  },
  {
    phase: 'Фаза 1: Telegram Gateway (MTProto)',
    timeline: '2-3 недели',
    priority: 'P0',
    deliverables: [
      'Микросервис tg-gateway на GramJS (TypeScript)',
      'Авторизация: номер → SMS-код → 2FA → Session',
      'Поиск контакта по номеру телефона (resolvePhone)',
      'Отправка первым: текст, медиа, кнопки',
      'Гибрид: Bot API для inline-кнопок + MTProto для отправки первым',
      'Persistent session (TDLib / GramJS StringSession)',
      'Anti-flood: exponential backoff при FLOOD_WAIT',
    ],
  },
  {
    phase: 'Фаза 2: VK + Оркестратор',
    timeline: '2-3 недели',
    priority: 'P1',
    deliverables: [
      'VK: User Token OAuth + отправка от пользователя',
      'Fallback: VK Community API если user-токен недоступен',
      'Оркестратор: управление инстансами (start/stop/restart)',
      'Мониторинг: Prometheus метрики, Grafana дашборд',
      'Автоматический reconnect при disconnect',
      'Алерты: сессия отключена, номер заблокирован',
    ],
  },
  {
    phase: 'Фаза 3: UI + Масштабирование',
    timeline: '2-3 недели',
    priority: 'P1',
    deliverables: [
      'UI в панели админа клуба: подключение номеров (QR-экран)',
      'UI: статус сессий, здоровье шлюзов, статистика',
      'Мобильное приложение: отправка сообщений первым',
      'Горизонтальное масштабирование: Docker Swarm / K8s',
      'Бэкап/восстановление сессий при failover',
      'Документация для DevOps: развёртывание, мониторинг',
    ],
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: СРАВНЕНИЕ ПОДХОДОВ
   ═══════════════════════════════════════════════════════════════ */

interface ComparisonRow {
  criterion: string;
  botApi: string;
  botApiScore: number;
  whapiCloud: string;
  whapiScore: number;
  ownGateway: string;
  ownScore: number;
}

const approachComparison: ComparisonRow[] = [
  {
    criterion: 'Писать первым',
    botApi: 'Только через HSM-шаблоны (WA) / невозможно (TG)',
    botApiScore: 3,
    whapiCloud: 'Да, без ограничений',
    whapiScore: 10,
    ownGateway: 'Да, без ограничений',
    ownScore: 10,
  },
  {
    criterion: 'Номер клуба (не бот)',
    botApi: 'Нет — бот или бизнес-аккаунт',
    botApiScore: 2,
    whapiCloud: 'Да — реальный номер',
    whapiScore: 10,
    ownGateway: 'Да — реальный номер',
    ownScore: 10,
  },
  {
    criterion: 'Стоимость',
    botApi: 'Бесплатно (TG), per-msg (WA Meta)',
    botApiScore: 8,
    whapiCloud: '$29/мес per номер',
    whapiScore: 5,
    ownGateway: 'Стоимость инфраструктуры (~$5-15/мес per номер)',
    ownScore: 7,
  },
  {
    criterion: 'Надёжность / SLA',
    botApi: 'Официальный API — высокая',
    botApiScore: 9,
    whapiCloud: 'Зависит от Whapi (3rd party)',
    whapiScore: 6,
    ownGateway: 'Зависит от нас (мониторинг, reconnect)',
    ownScore: 7,
  },
  {
    criterion: 'Контроль данных',
    botApi: 'Данные у Meta/Telegram',
    botApiScore: 5,
    whapiCloud: 'Данные проходят через Whapi серверы',
    whapiScore: 3,
    ownGateway: 'Полный контроль — данные на нашем сервере',
    ownScore: 10,
  },
  {
    criterion: 'Масштабирование',
    botApi: 'Unlimited (официальный API)',
    botApiScore: 10,
    whapiCloud: 'До 100+ номеров (мульти-аккаунт)',
    whapiScore: 7,
    ownGateway: 'Контейнер per номер — горизонтальное масштабирование',
    ownScore: 8,
  },
  {
    criterion: 'Риск блокировки',
    botApi: 'Минимальный (official)',
    botApiScore: 9,
    whapiCloud: 'Средний (unofficial, rate limit)',
    whapiScore: 5,
    ownGateway: 'Средний (unofficial, rate limit, наш контроль)',
    ownScore: 6,
  },
  {
    criterion: 'Vendor lock-in',
    botApi: 'Привязка к Meta/Telegram API',
    botApiScore: 5,
    whapiCloud: 'Полная зависимость от Whapi.cloud',
    whapiScore: 2,
    ownGateway: 'Нет зависимости — своё решение',
    ownScore: 10,
  },
  {
    criterion: 'Скорость внедрения',
    botApi: 'Быстро (SDK готовы)',
    botApiScore: 9,
    whapiCloud: 'Очень быстро (REST API)',
    whapiScore: 10,
    ownGateway: 'Средняя (разработка шлюза)',
    ownScore: 5,
  },
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: ENV-ПЕРЕМЕННЫЕ
   ═══════════════════════════════════════════════════════════════ */

const envVariables = [
  { group: 'WhatsApp Gateway', vars: [
    { name: 'WA_GATEWAY_HOST', value: 'localhost', desc: 'Host микросервиса wa-gateway' },
    { name: 'WA_GATEWAY_PORT', value: '3100', desc: 'Порт REST API wa-gateway' },
    { name: 'WA_SESSION_STORE', value: 'postgresql', desc: 'Хранилище сессий: postgresql | redis | file' },
    { name: 'WA_MAX_MSG_PER_DAY', value: '200', desc: 'Лимит сообщений/день per-номер (anti-ban)' },
    { name: 'WA_QR_TIMEOUT_SEC', value: '60', desc: 'Timeout QR-кода (секунды)' },
    { name: 'WA_RECONNECT_INTERVAL_MS', value: '5000', desc: 'Интервал попыток реконнекта' },
    { name: 'WA_RECONNECT_MAX_RETRIES', value: '10', desc: 'Макс. попыток реконнекта' },
  ]},
  { group: 'Telegram Gateway', vars: [
    { name: 'TG_GATEWAY_HOST', value: 'localhost', desc: 'Host микросервиса tg-gateway' },
    { name: 'TG_GATEWAY_PORT', value: '3101', desc: 'Порт REST API tg-gateway' },
    { name: 'TG_API_ID', value: '', desc: 'Telegram API ID (my.telegram.org)' },
    { name: 'TG_API_HASH', value: '', desc: 'Telegram API Hash (my.telegram.org)' },
    { name: 'TG_MAX_MSG_PER_SEC', value: '30', desc: 'Лимит сообщений/сек (Telegram flood protection)' },
    { name: 'TG_FLOOD_WAIT_MULTIPLIER', value: '1.5', desc: 'Множитель задержки при FLOOD_WAIT' },
  ]},
  { group: 'Оркестратор', vars: [
    { name: 'GATEWAY_ORCHESTRATOR_MODE', value: 'docker', desc: 'Режим: docker | k8s | process' },
    { name: 'GATEWAY_HEALTH_CHECK_INTERVAL_MS', value: '30000', desc: 'Интервал health check' },
    { name: 'GATEWAY_SESSION_ENCRYPTION_KEY', value: '', desc: 'AES-256 ключ шифрования сессий' },
    { name: 'GATEWAY_WEBHOOK_INTERNAL_URL', value: 'http://api:3000', desc: 'URL для внутренних webhook-ов' },
  ]},
];

/* ═══════════════════════════════════════════════════════════════
   ДАННЫЕ: ГИБРИДНАЯ СТРАТЕГИЯ
   ═══════════════════════════════════════════════════════════════ */

interface HybridRow {
  scenario: string;
  method: string;
  channel: string;
  reason: string;
}

const hybridStrategy: HybridRow[] = [
  { scenario: 'Первое сообщение клиенту', method: 'Gateway (номер клуба)', channel: 'WhatsApp / Telegram', reason: 'Клиент видит сообщение от реального номера, высокий % открытий' },
  { scenario: 'Уведомление о тренировке', method: 'Gateway (номер клуба)', channel: 'WhatsApp / Telegram', reason: 'Выглядит как личное сообщение, не спам' },
  { scenario: 'Массовая рассылка (акции)', method: 'Bot API + HSM шаблон', channel: 'WhatsApp Business API', reason: 'Масштабируемость, соответствие ToS, нет риска бана номера' },
  { scenario: 'Чат-бот (FAQ, запись)', method: 'Bot API', channel: 'Telegram Bot', reason: 'Inline-кнопки, команды, автоответы — функционал только ботов' },
  { scenario: 'Переписка в Unified Inbox', method: 'Gateway (продолжение диалога)', channel: 'Все каналы', reason: 'Менеджер отвечает от номера клуба, клиент не путается' },
  { scenario: 'VK: рассылка подписчикам', method: 'Community API', channel: 'VK', reason: 'User token рискует баном — для рассылок используем группу' },
  { scenario: 'Напоминание об оплате', method: 'Gateway (номер клуба)', channel: 'WhatsApp / Telegram', reason: 'Персональное сообщение от менеджера, не от бота' },
];

/* ═══════════════════════════════════════════════════════════════
   КОМПОНЕНТ СТРАНИЦЫ
   ═══════════════════════════════════════════════════════════════ */

const methodColors = {
  GET: 'bg-green-100 text-green-800',
  POST: 'bg-blue-100 text-blue-800',
  PUT: 'bg-yellow-100 text-yellow-800',
  DELETE: 'bg-red-100 text-red-800',
} as const;

const methodBadge = (method: string) => {
  const color = methodColors[method as keyof typeof methodColors] ?? 'bg-gray-100 text-gray-800';
  return (
    <span className={cn('text-[10px] font-mono font-bold px-1.5 py-0.5 rounded', color)}>
      {method}
    </span>
  );
};

const priorityMap = {
  P0: { bg: 'bg-red-50', text: 'text-red-700' },
  P1: { bg: 'bg-orange-50', text: 'text-orange-700' },
  P2: { bg: 'bg-blue-50', text: 'text-blue-700' },
} as const;

const priorityBadge = (priority: string) => {
  const s = priorityMap[priority as keyof typeof priorityMap] ?? priorityMap.P2;
  return (
    <span className={cn('text-[10px] font-bold px-2 py-0.5 rounded-full', s.bg, s.text)}>
      {priority}
    </span>
  );
};

const complexityMap = {
  low: { bg: 'bg-green-50', text: 'text-green-700', label: 'Простая' },
  medium: { bg: 'bg-yellow-50', text: 'text-yellow-700', label: 'Средняя' },
  high: { bg: 'bg-red-50', text: 'text-red-700', label: 'Сложная' },
} as const;

export default function MessengerOwnNumberGatewayDocument() {
  const router = useRouter();
  const contentRef = useRef<HTMLDivElement>(null);

  const handleDownloadPdf = async () => {
    const el = contentRef.current;
    if (!el) return;
    const html2canvas = (await import('html2canvas-pro')).default;
    const { jsPDF } = await import('jspdf');
    const canvas = await html2canvas(el, { scale: 2, useCORS: true });
    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF('p', 'mm', 'a4');
    const pdfW = pdf.internal.pageSize.getWidth();
    const pdfH = pdf.internal.pageSize.getHeight();
    const imgW = pdfW - 16;
    const imgH = (canvas.height * imgW) / canvas.width;
    let y = 8;
    let page = 0;
    while (y < imgH + 8) {
      if (page > 0) pdf.addPage();
      pdf.addImage(imgData, 'PNG', 8, 8 - y + 8 * (page === 0 ? 0 : 1), imgW, imgH);
      y += pdfH - 16;
      page++;
    }
    pdf.save('messenger-own-number-gateway.pdf');
  };

  const handleDownloadExcel = async () => {
    const XLSX = await import('xlsx');
    const wb = XLSX.utils.book_new();

    // Sheet 1: Current gaps
    const gapData = currentGaps.map((g) => ({
      'Канал': g.channel,
      'Текущий подход': g.currentApproach,
      'Проблема': g.problem,
      'Писать первым': g.writeFirst ? 'Да (с ограничениями)' : 'Нет',
      'Свой номер': g.ownNumber ? 'Да' : 'Нет',
      'Опыт клиента': g.clientExperience,
    }));
    const ws1 = XLSX.utils.json_to_sheet(gapData);
    ws1['!cols'] = [{ wch: 12 }, { wch: 35 }, { wch: 60 }, { wch: 20 }, { wch: 12 }, { wch: 50 }];
    XLSX.utils.book_append_sheet(wb, ws1, 'Текущие проблемы');

    // Sheet 2: Whapi analysis
    const whapiData = whapiAnalysis.map((w) => ({
      'Фича Whapi.cloud': w.feature,
      'Описание': w.description,
      'Наш аналог': w.ourAnalog,
      'Сложность': complexityMap[w.complexity].label,
    }));
    const ws2 = XLSX.utils.json_to_sheet(whapiData);
    ws2['!cols'] = [{ wch: 30 }, { wch: 50 }, { wch: 50 }, { wch: 12 }];
    XLSX.utils.book_append_sheet(wb, ws2, 'Анализ Whapi.cloud');

    // Sheet 3: Approach comparison
    const compData = approachComparison.map((c) => ({
      'Критерий': c.criterion,
      'Bot API': c.botApi,
      'Балл Bot': c.botApiScore,
      'Whapi.cloud': c.whapiCloud,
      'Балл Whapi': c.whapiScore,
      'Свой шлюз': c.ownGateway,
      'Балл шлюз': c.ownScore,
    }));
    const ws3 = XLSX.utils.json_to_sheet(compData);
    ws3['!cols'] = [{ wch: 22 }, { wch: 40 }, { wch: 10 }, { wch: 40 }, { wch: 10 }, { wch: 40 }, { wch: 10 }];
    XLSX.utils.book_append_sheet(wb, ws3, 'Сравнение подходов');

    // Sheet 4: Channel solutions
    const solData = channelSolutions.map((s) => ({
      'Канал': s.channel,
      'Библиотека': s.library,
      'Протокол': s.protocol,
      'Писать первым': s.writeFirst ? 'Да' : 'Нет',
      'Свой номер': s.ownNumber ? 'Да' : 'Нет',
      'Авторизация': s.authMethod,
      'Лицензия': s.license,
    }));
    const ws4 = XLSX.utils.json_to_sheet(solData);
    ws4['!cols'] = [{ wch: 12 }, { wch: 30 }, { wch: 40 }, { wch: 14 }, { wch: 12 }, { wch: 50 }, { wch: 30 }];
    XLSX.utils.book_append_sheet(wb, ws4, 'Решения по каналам');

    // Sheet 5: API endpoints
    const apiData = gatewayApiEndpoints.map((e) => ({
      'Метод': e.method,
      'Путь': e.path,
      'Описание': e.description,
      'Роли': e.roles,
    }));
    const ws5 = XLSX.utils.json_to_sheet(apiData);
    ws5['!cols'] = [{ wch: 8 }, { wch: 45 }, { wch: 55 }, { wch: 35 }];
    XLSX.utils.book_append_sheet(wb, ws5, 'API Endpoints');

    // Sheet 6: Hybrid strategy
    const hybridData = hybridStrategy.map((h) => ({
      'Сценарий': h.scenario,
      'Метод доставки': h.method,
      'Канал': h.channel,
      'Причина': h.reason,
    }));
    const ws6 = XLSX.utils.json_to_sheet(hybridData);
    ws6['!cols'] = [{ wch: 30 }, { wch: 30 }, { wch: 25 }, { wch: 55 }];
    XLSX.utils.book_append_sheet(wb, ws6, 'Гибридная стратегия');

    // Sheet 7: Phases
    const phaseData = gatewayPhases.map((p) => ({
      'Фаза': p.phase,
      'Сроки': p.timeline,
      'Приоритет': p.priority,
      'Результаты': p.deliverables.join('; '),
    }));
    const ws7 = XLSX.utils.json_to_sheet(phaseData);
    ws7['!cols'] = [{ wch: 35 }, { wch: 12 }, { wch: 10 }, { wch: 80 }];
    XLSX.utils.book_append_sheet(wb, ws7, 'Фазы реализации');

    XLSX.writeFile(wb, 'messenger-own-number-gateway.xlsx');
  };

  const botApiTotal = approachComparison.reduce((s, c) => s + c.botApiScore, 0);
  const whapiTotal = approachComparison.reduce((s, c) => s + c.whapiScore, 0);
  const ownTotal = approachComparison.reduce((s, c) => s + c.ownScore, 0);

  return (
    <div>
      <button
        onClick={() => router.push('/documents')}
        className="flex items-center gap-2 text-sm text-muted hover:text-gray-900 mb-6 transition-colors"
      >
        <ArrowLeft className="h-4 w-4" />
        Все документы
      </button>

      <div ref={contentRef} className="bg-card rounded-xl shadow-sm border border-border overflow-hidden">
        {/* Header */}
        <div className="px-8 py-6 border-b border-border">
          <div className="flex items-start justify-between">
            <div className="flex items-center gap-3">
              <div className="bg-emerald-50 p-2.5 rounded-lg">
                <Smartphone className="h-6 w-6 text-emerald-600" />
              </div>
              <div>
                <h1 className="text-xl font-bold text-gray-900">
                  Дополнение к ТЗ #42: Мессенджеры — отправка первым с номера клуба
                </h1>
                <p className="text-sm text-muted mt-1">
                  Дата: {LAST_UPDATE} | Дополняет{' '}
                  <a href="/document/messenger-integrations-tz" className="text-emerald-600 underline hover:text-emerald-800">
                    ТЗ: Интеграция мессенджеров
                  </a>
                  {' '}| Собственный шлюз WhatsApp / Telegram / VK
                </p>
              </div>
            </div>
            <div className="flex gap-2 print:hidden">
              <button
                onClick={() => void handleDownloadPdf()}
                className="flex items-center gap-2 border border-border bg-card text-gray-700 px-4 py-2 rounded-xl text-sm font-medium hover:bg-background transition-colors"
              >
                <FileDown className="h-4 w-4" />
                Скачать PDF
              </button>
              <button
                onClick={() => void handleDownloadExcel()}
                className="flex items-center gap-2 border border-border bg-card text-gray-700 px-4 py-2 rounded-xl text-sm font-medium hover:bg-background transition-colors"
              >
                <Table2 className="h-4 w-4" />
                Скачать Excel
              </button>
              <button
                onClick={() => window.print()}
                className="flex items-center gap-2 border border-border bg-card text-gray-700 px-4 py-2 rounded-xl text-sm font-medium hover:bg-background transition-colors"
              >
                <Printer className="h-4 w-4" />
                Печать
              </button>
            </div>
          </div>
        </div>

        <div className="px-8 py-6 space-y-10">

          {/* ═══════════════ ПРОБЛЕМА ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-red-500" />
              Часть 1: Проблема — текущий ТЗ #42 использует только ботов
            </h2>
            <p className="text-sm text-muted mb-6">
              Во всех 4 каналах (WhatsApp, Telegram, VK, MAX) клуб не может написать первым с реального номера телефона клуба. Клиент видит бота или бизнес-аккаунт.
            </p>

            {/* Gap cards */}
            <div className="space-y-3 mb-6">
              {currentGaps.map((gap) => (
                <div key={gap.channel} className="border border-border rounded-xl p-4">
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <span className="text-xl">{gap.icon}</span>
                      <h4 className="font-semibold text-gray-900">{gap.channel}</h4>
                      <span className="text-[10px] font-mono bg-gray-100 text-gray-600 px-1.5 py-0.5 rounded">
                        {gap.currentApproach}
                      </span>
                    </div>
                    <div className="flex gap-2">
                      <span className={cn(
                        'text-[10px] font-semibold px-2 py-0.5 rounded-full',
                        gap.writeFirst ? 'bg-yellow-50 text-yellow-700' : 'bg-red-50 text-red-700',
                      )}>
                        {gap.writeFirst ? 'Писать первым: с ограничениями' : 'Писать первым: НЕТ'}
                      </span>
                      <span className="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-red-50 text-red-700">
                        Свой номер: НЕТ
                      </span>
                    </div>
                  </div>
                  <p className="text-xs text-red-700 mb-1.5">
                    <strong>Проблема:</strong> {gap.problem}
                  </p>
                  <p className="text-xs text-gray-500">
                    <strong>Что видит клиент:</strong> {gap.clientExperience}
                  </p>
                </div>
              ))}
            </div>

            {/* Key insight */}
            <div className="bg-red-50 rounded-xl p-5 border border-red-100">
              <h3 className="text-sm font-semibold text-red-800 mb-2">Ключевой GAP</h3>
              <p className="text-xs text-red-700 leading-relaxed">
                Фитнес-клубы хотят, чтобы менеджер мог написать клиенту <strong>первым</strong> — например,
                после первого визита, для напоминания о тренировке, при истечении абонемента. При этом сообщение
                должно прийти <strong>от номера телефона клуба</strong> (например, +7 999 123-45-67), а не от бота
                «@FitClubBot» или бизнес-аккаунта WhatsApp Business. Клиент должен видеть сообщение как от живого
                человека — это критически важно для конверсии ответов (личные сообщения открываются в 3-5x чаще ботов).
              </p>
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ АНАЛИЗ WHAPI.CLOUD ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <Globe className="h-5 w-5 text-emerald-600" />
              Часть 2: Анализ Whapi.cloud — эталонное решение
            </h2>
            <p className="text-sm text-muted mb-6">
              Whapi.cloud — SaaS-платформа, которая подключает реальный номер WhatsApp через Multi-Device протокол.
              Цена $29/мес per номер. Мы берём идеи, но строим <strong>своё решение</strong>.
            </p>

            {/* Whapi feature analysis */}
            <table className="w-full text-xs border-collapse mb-6">
              <thead>
                <tr className="bg-gray-50">
                  <th className="text-left px-3 py-2 font-medium text-muted border border-border">Фича Whapi.cloud</th>
                  <th className="text-left px-3 py-2 font-medium text-muted border border-border">Как работает</th>
                  <th className="text-left px-3 py-2 font-medium text-muted border border-border">Наш аналог (своё решение)</th>
                  <th className="text-center px-3 py-2 font-medium text-muted border border-border w-20">Сложность</th>
                </tr>
              </thead>
              <tbody>
                {whapiAnalysis.map((w) => {
                  const c = complexityMap[w.complexity];
                  return (
                    <tr key={w.feature} className="hover:bg-gray-50/50">
                      <td className="px-3 py-2 border border-border text-gray-900 font-medium">{w.feature}</td>
                      <td className="px-3 py-2 border border-border text-gray-600">{w.description}</td>
                      <td className="px-3 py-2 border border-border text-emerald-700 font-mono text-[10px]">{w.ourAnalog}</td>
                      <td className="px-3 py-2 border border-border text-center">
                        <span className={cn('text-[10px] font-semibold px-2 py-0.5 rounded-full', c.bg, c.text)}>
                          {c.label}
                        </span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>

            {/* Why NOT use Whapi */}
            <div className="bg-orange-50 rounded-xl p-5 border border-orange-100 mb-6">
              <h3 className="text-sm font-semibold text-orange-800 mb-2 flex items-center gap-2">
                <AlertTriangle className="h-4 w-4" />
                Почему НЕ использовать Whapi.cloud (или аналоги)
              </h3>
              <ul className="space-y-1">
                {[
                  'Vendor lock-in: полная зависимость от стороннего сервиса ($29/мес × кол-во клубов)',
                  'Данные клиентов проходят через серверы Whapi — нарушение privacy policy',
                  'Нет контроля над rate limiting и anti-ban политикой',
                  'При росте: 100 клубов × $29 = $2,900/мес — своё решение дешевле в 5-10x',
                  'Whapi может закрыться / изменить цены / потерять доступ к протоколу',
                  'Нет поддержки Telegram MTProto и VK User API — только WhatsApp',
                  'Невозможно кастомизировать под специфику фитнес-индустрии',
                ].map((item, i) => (
                  <li key={i} className="flex items-start gap-1.5 text-xs text-orange-800">
                    <XCircle className="h-3 w-3 text-orange-500 shrink-0 mt-0.5" />
                    {item}
                  </li>
                ))}
              </ul>
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ СРАВНЕНИЕ ПОДХОДОВ ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <Layers className="h-5 w-5 text-emerald-600" />
              Часть 3: Сравнение трёх подходов
            </h2>
            <p className="text-sm text-muted mb-6">
              Bot API vs Whapi.cloud vs Свой шлюз — оценка по 9 критериям
            </p>

            {/* Summary scores */}
            <div className="grid grid-cols-3 gap-4 mb-6">
              <div className="bg-gray-50 rounded-xl p-4 text-center border border-border">
                <p className="text-3xl font-bold text-gray-500">{botApiTotal}</p>
                <p className="text-xs text-muted mt-1">Bot API (текущий ТЗ)</p>
                <div className="mt-2 bg-gray-200 rounded-full h-2">
                  <div className="h-2 rounded-full bg-gray-400" style={{ width: `${(botApiTotal / 90) * 100}%` }} />
                </div>
              </div>
              <div className="bg-orange-50 rounded-xl p-4 text-center border border-orange-100">
                <p className="text-3xl font-bold text-orange-600">{whapiTotal}</p>
                <p className="text-xs text-muted mt-1">Whapi.cloud (SaaS)</p>
                <div className="mt-2 bg-orange-100 rounded-full h-2">
                  <div className="h-2 rounded-full bg-orange-400" style={{ width: `${(whapiTotal / 90) * 100}%` }} />
                </div>
              </div>
              <div className="bg-emerald-50 rounded-xl p-4 text-center border border-emerald-100">
                <p className="text-3xl font-bold text-emerald-700">{ownTotal}</p>
                <p className="text-xs text-muted mt-1">Свой шлюз (рекомендуемый)</p>
                <div className="mt-2 bg-emerald-100 rounded-full h-2">
                  <div className="h-2 rounded-full bg-emerald-500" style={{ width: `${(ownTotal / 90) * 100}%` }} />
                </div>
              </div>
            </div>

            {/* Comparison table */}
            <div className="overflow-x-auto mb-6">
              <table className="w-full text-xs border-collapse">
                <thead>
                  <tr className="bg-gray-50">
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Критерий</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Bot API</th>
                    <th className="text-center px-3 py-2 font-medium text-muted border border-border w-10">Балл</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Whapi.cloud</th>
                    <th className="text-center px-3 py-2 font-medium text-muted border border-border w-10">Балл</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Свой шлюз</th>
                    <th className="text-center px-3 py-2 font-medium text-muted border border-border w-10">Балл</th>
                  </tr>
                </thead>
                <tbody>
                  {approachComparison.map((row) => (
                    <tr key={row.criterion} className="hover:bg-gray-50/50">
                      <td className="px-3 py-2 border border-border text-gray-900 font-medium">{row.criterion}</td>
                      <td className="px-3 py-2 border border-border text-gray-600">{row.botApi}</td>
                      <td className="px-3 py-2 border border-border text-center">
                        <span className={cn(
                          'font-bold text-xs',
                          row.botApiScore >= 8 ? 'text-green-600' : row.botApiScore >= 5 ? 'text-yellow-600' : 'text-red-600',
                        )}>{row.botApiScore}</span>
                      </td>
                      <td className="px-3 py-2 border border-border text-gray-600">{row.whapiCloud}</td>
                      <td className="px-3 py-2 border border-border text-center">
                        <span className={cn(
                          'font-bold text-xs',
                          row.whapiScore >= 8 ? 'text-green-600' : row.whapiScore >= 5 ? 'text-yellow-600' : 'text-red-600',
                        )}>{row.whapiScore}</span>
                      </td>
                      <td className="px-3 py-2 border border-border text-emerald-700">{row.ownGateway}</td>
                      <td className="px-3 py-2 border border-border text-center">
                        <span className={cn(
                          'font-bold text-xs',
                          row.ownScore >= 8 ? 'text-green-600' : row.ownScore >= 5 ? 'text-yellow-600' : 'text-red-600',
                        )}>{row.ownScore}</span>
                      </td>
                    </tr>
                  ))}
                  <tr className="bg-gray-50 font-bold">
                    <td className="px-3 py-2 border border-border text-gray-900">ИТОГО</td>
                    <td className="px-3 py-2 border border-border" />
                    <td className="px-3 py-2 border border-border text-center text-gray-500">{botApiTotal}/90</td>
                    <td className="px-3 py-2 border border-border" />
                    <td className="px-3 py-2 border border-border text-center text-orange-600">{whapiTotal}/90</td>
                    <td className="px-3 py-2 border border-border" />
                    <td className="px-3 py-2 border border-border text-center text-emerald-700">{ownTotal}/90</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ АРХИТЕКТУРА ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <Server className="h-5 w-5 text-emerald-600" />
              Часть 4: Архитектура собственного шлюза MyFitCRM Gateway
            </h2>
            <p className="text-sm text-muted mb-6">
              Микросервисная архитектура: отдельный шлюз per-канал, оркестратор, интеграция с Unified Inbox
            </p>

            {/* Architecture diagram */}
            <div className="bg-gray-50 rounded-xl p-5 border border-border mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
                <Zap className="h-4 w-4 text-emerald-600" />
                Архитектура MyFitCRM Messaging Gateway
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
┌──────────────────────────────────────────────────────────────────────────────┐
│                          MyFitCRM Gateway Architecture                       │
│                                                                              │
│  Админ клуба                   Тренер / Менеджер                             │
│  ┌──────────────┐              ┌──────────────────┐                          │
│  │  QR-экран    │              │  Unified Inbox    │                          │
│  │  Подключение │              │  Чат с клиентом   │                          │
│  │  номера      │              │  "Написать первым"│                          │
│  └──────┬───────┘              └────────┬─────────┘                          │
│         │                               │                                    │
│         ▼                               ▼                                    │
│  ┌─────────────────────────────────────────────────────────┐                 │
│  │                  MyFitCRM API (NestJS)                   │                 │
│  │  ┌─────────────┐  ┌───────────────┐  ┌──────────────┐  │                 │
│  │  │ Gateway     │  │ Messaging     │  │ Session      │  │                 │
│  │  │ Controller  │  │ Service       │  │ Manager      │  │                 │
│  │  │ /v1/gateway │  │ (send-first)  │  │ (QR, auth)   │  │                 │
│  │  └──────┬──────┘  └──────┬────────┘  └──────┬───────┘  │                 │
│  └─────────┼────────────────┼──────────────────┼──────────┘                 │
│            │                │                  │                             │
│            ▼                ▼                  ▼                             │
│  ┌──────────────────────────────────────────────────────┐                    │
│  │              Gateway Orchestrator Service             │                    │
│  │  ┌──────────┐  ┌──────────┐  ┌───────────────────┐  │                    │
│  │  │ Instance │  │ Health   │  │ Session           │  │                    │
│  │  │ Manager  │  │ Monitor  │  │ Encryption (AES)  │  │                    │
│  │  └──────────┘  └──────────┘  └───────────────────┘  │                    │
│  └──────┬─────────────┬──────────────────┬─────────────┘                    │
│         │             │                  │                                   │
│    ┌────▼────┐   ┌────▼────┐       ┌─────▼─────┐                            │
│    │ Docker  │   │ Docker  │       │  Docker   │                             │
│    │Container│   │Container│       │ Container │     ← per-номер изоляция   │
│    │         │   │         │       │           │                             │
│    │┌───────┐│   │┌───────┐│       │┌─────────┐│                             │
│    ││Baileys││   ││GramJS ││       ││ vk-io   ││                             │
│    ││WA-GW  ││   ││TG-GW  ││       ││ VK-GW   ││                             │
│    │└───┬───┘│   │└───┬───┘│       │└────┬────┘│                             │
│    └────┼────┘   └────┼────┘       └─────┼─────┘                             │
│         │             │                  │                                   │
│    ┌────▼────┐   ┌────▼────┐       ┌─────▼─────┐                            │
│    │WhatsApp │   │Telegram │       │    VK     │     ← Внешние сервисы      │
│    │ Servers │   │ Servers │       │  Servers  │                             │
│    └─────────┘   └─────────┘       └───────────┘                             │
│                                                                              │
│  Хранилище:  PostgreSQL (сессии, логи)  │  Redis (кэш, очереди BullMQ)       │
└──────────────────────────────────────────────────────────────────────────────┘
              `.trim()}</pre>
            </div>

            {/* Channel solution cards */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3">Решения по каналам</h3>
            <div className="space-y-4 mb-6">
              {channelSolutions.map((sol) => (
                <div key={sol.channel} className="border border-border rounded-xl p-4">
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <span className="text-xl">{sol.icon}</span>
                      <h4 className="font-semibold text-gray-900">{sol.channel}</h4>
                      <span className="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-green-50 text-green-700">
                        Писать первым: ДА
                      </span>
                      <span className="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-green-50 text-green-700">
                        Свой номер: ДА
                      </span>
                    </div>
                    <span className="text-[10px] bg-gray-100 text-gray-600 font-mono px-2 py-0.5 rounded">
                      {sol.license}
                    </span>
                  </div>

                  <div className="grid grid-cols-2 gap-4 mb-3">
                    <div>
                      <p className="text-[10px] font-semibold text-muted uppercase tracking-wider mb-1">Библиотека</p>
                      <p className="text-xs font-mono text-emerald-700">{sol.library}</p>
                    </div>
                    <div>
                      <p className="text-[10px] font-semibold text-muted uppercase tracking-wider mb-1">Протокол</p>
                      <p className="text-xs font-mono text-gray-600">{sol.protocol}</p>
                    </div>
                  </div>

                  <div className="mb-2">
                    <p className="text-[10px] font-semibold text-muted uppercase tracking-wider mb-1">Авторизация</p>
                    <div className="flex items-center gap-1.5 text-xs text-gray-700">
                      <QrCode className="h-3 w-3 text-emerald-500 shrink-0" />
                      {sol.authMethod}
                    </div>
                  </div>

                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <p className="text-[10px] font-semibold text-green-700 uppercase tracking-wider mb-1">Возможности</p>
                      <ul className="space-y-0.5">
                        {sol.features.map((f, i) => (
                          <li key={i} className="flex items-start gap-1.5 text-xs text-gray-600">
                            <CheckCircle2 className="h-3 w-3 text-green-500 shrink-0 mt-0.5" />
                            {f}
                          </li>
                        ))}
                      </ul>
                    </div>
                    <div>
                      <p className="text-[10px] font-semibold text-red-700 uppercase tracking-wider mb-1">Риски</p>
                      <ul className="space-y-0.5">
                        {sol.risks.map((r, i) => (
                          <li key={i} className="flex items-start gap-1.5 text-xs text-gray-500">
                            <AlertTriangle className="h-3 w-3 text-red-400 shrink-0 mt-0.5" />
                            {r}
                          </li>
                        ))}
                      </ul>
                    </div>
                  </div>
                </div>
              ))}
            </div>

            {/* Hybrid strategy */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <RefreshCw className="h-4 w-4 text-emerald-600" />
              Гибридная стратегия: Gateway + Bot API
            </h3>
            <p className="text-xs text-muted mb-3">
              Рекомендация: использовать <strong>оба подхода</strong> — Gateway для личных сообщений (писать первым), Bot API для массовых рассылок и чат-ботов.
            </p>
            <div className="overflow-x-auto mb-6">
              <table className="w-full text-xs border-collapse">
                <thead>
                  <tr className="bg-gray-50">
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Сценарий</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Метод доставки</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Канал</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Почему</th>
                  </tr>
                </thead>
                <tbody>
                  {hybridStrategy.map((row, i) => (
                    <tr key={i} className="hover:bg-gray-50/50">
                      <td className="px-3 py-2 border border-border text-gray-900 font-medium">{row.scenario}</td>
                      <td className="px-3 py-2 border border-border">
                        <span className={cn(
                          'text-[10px] font-semibold px-2 py-0.5 rounded-full',
                          row.method.includes('Gateway') ? 'bg-emerald-50 text-emerald-700' : 'bg-blue-50 text-blue-700',
                        )}>
                          {row.method}
                        </span>
                      </td>
                      <td className="px-3 py-2 border border-border text-gray-600">{row.channel}</td>
                      <td className="px-3 py-2 border border-border text-gray-500">{row.reason}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ ТЕХНИЧЕСКАЯ СПЕЦИФИКАЦИЯ ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <Database className="h-5 w-5 text-emerald-600" />
              Часть 5: Техническая спецификация
            </h2>
            <p className="text-sm text-muted mb-6">
              Новые Prisma-модели, API эндпоинты, переменные окружения
            </p>

            {/* Prisma models */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <Database className="h-4 w-4 text-emerald-600" />
              Prisma-модели (новые и расширенные)
            </h3>
            <div className="space-y-4 mb-6">
              {gatewayPrismaModels.map((model) => (
                <div key={model.name}>
                  <div className="flex items-center gap-2 mb-1">
                    <h4 className="text-xs font-bold text-emerald-700 font-mono">model {model.name}</h4>
                    <span className={cn(
                      'text-[10px] font-semibold px-1.5 py-0.5 rounded-full',
                      model.isNew ? 'bg-green-50 text-green-700' : 'bg-yellow-50 text-yellow-700',
                    )}>
                      {model.isNew ? 'НОВАЯ' : 'РАСШИРЕНИЕ'}
                    </span>
                  </div>
                  <table className="w-full text-xs border-collapse">
                    <thead>
                      <tr className="bg-gray-50">
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border w-40">Поле</th>
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border">Тип</th>
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border">Описание</th>
                      </tr>
                    </thead>
                    <tbody>
                      {model.fields.map((f) => (
                        <tr key={f.name} className="hover:bg-gray-50/50">
                          <td className="px-3 py-1.5 border border-border font-mono text-gray-900">{f.name}</td>
                          <td className="px-3 py-1.5 border border-border font-mono text-emerald-600 text-[10px]">{f.type}</td>
                          <td className="px-3 py-1.5 border border-border text-gray-600">{f.description}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              ))}

              <div className="bg-emerald-50 rounded-lg p-3 border border-emerald-100">
                <h4 className="text-xs font-bold text-emerald-700 mb-1 font-mono">Новые Enums</h4>
                <div className="grid grid-cols-2 gap-x-6 gap-y-1 text-xs text-gray-700 font-mono">
                  <div>SessionStatus: QR_PENDING | CONNECTED | DISCONNECTED | BANNED</div>
                  <div>HealthStatus: HEALTHY | UNHEALTHY | STARTING | STOPPED</div>
                  <div>DeliveryMethod: GATEWAY | BOT_API | BUSINESS_API</div>
                </div>
              </div>
            </div>

            {/* API Endpoints */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <Link2 className="h-4 w-4 text-emerald-600" />
              REST API эндпоинты (новые — дополнение к ТЗ #42)
            </h3>
            <div className="overflow-x-auto mb-6">
              <table className="w-full text-xs border-collapse">
                <thead>
                  <tr className="bg-gray-50">
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border w-16">Метод</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Путь</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">Описание</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border w-40">Роли</th>
                  </tr>
                </thead>
                <tbody>
                  {gatewayApiEndpoints.map((ep, i) => (
                    <tr key={i} className="hover:bg-gray-50/50">
                      <td className="px-3 py-1.5 border border-border">{methodBadge(ep.method)}</td>
                      <td className="px-3 py-1.5 border border-border font-mono text-gray-900">{ep.path}</td>
                      <td className="px-3 py-1.5 border border-border text-gray-600">{ep.description}</td>
                      <td className="px-3 py-1.5 border border-border text-gray-500 text-[10px]">{ep.roles}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            {/* NestJS module structure */}
            <div className="bg-gray-50 rounded-xl p-5 border border-border mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
                <Shield className="h-4 w-4 text-emerald-600" />
                Структура NestJS-модуля gateway/
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
apps/api/src/modules/gateway/
├── gateway.module.ts                  // @RequireModule('messaging_gateway')
├── gateway.controller.ts             // REST: /v1/gateway/*
├── gateway-session.service.ts        // CRUD сессий, QR-генерация, авторизация
├── gateway-orchestrator.service.ts   // Управление Docker-контейнерами
├── gateway-health.service.ts         // Health check, мониторинг, алерты
├── gateway-routing.service.ts        // Выбор метода доставки (Gateway vs Bot API)
├── encryption.service.ts             // AES-256 шифрование auth state
├── adapters/
│   ├── gateway-adapter.interface.ts  // Интерфейс адаптера шлюза
│   ├── wa-gateway.adapter.ts        // Baileys: QR, send, receive, reconnect
│   ├── tg-gateway.adapter.ts        // GramJS: auth, sendMessage, resolvePhone
│   └── vk-gateway.adapter.ts        // vk-io: OAuth, sendMessage, longpoll
├── dto/
│   ├── create-session.dto.ts
│   ├── auth-session.dto.ts
│   └── send-first-message.dto.ts
└── processors/
    └── gateway-reconnect.processor.ts // BullMQ: авто-реконнект при disconnect

// Микросервисы (отдельные Docker-образы):
apps/wa-gateway/                       // Standalone Baileys service
├── src/
│   ├── wa-gateway.service.ts         // Baileys connection, events
│   ├── wa-gateway.controller.ts      // Internal REST API (:3100)
│   ├── wa-auth-state.service.ts      // Persist auth state (PG/Redis)
│   └── wa-rate-limiter.ts            // Anti-ban: msg/day counter
├── Dockerfile
└── package.json

apps/tg-gateway/                       // Standalone GramJS service
├── src/
│   ├── tg-gateway.service.ts         // GramJS client, MTProto
│   ├── tg-gateway.controller.ts      // Internal REST API (:3101)
│   ├── tg-session.service.ts         // Persist StringSession
│   └── tg-flood-control.ts           // FLOOD_WAIT exponential backoff
├── Dockerfile
└── package.json
              `.trim()}</pre>
            </div>

            {/* Auth flow diagrams */}
            <div className="bg-gray-50 rounded-xl p-5 border border-border mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
                <QrCode className="h-4 w-4 text-emerald-600" />
                Поток авторизации: подключение номера клуба
              </h3>
              <div className="grid grid-cols-2 gap-6">
                <div>
                  <h4 className="text-xs font-bold text-gray-700 mb-2">WhatsApp (QR-код)</h4>
                  <pre className="text-[10px] text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
1. Админ клуба → "Подключить WhatsApp"
2. POST /v1/gateway/sessions
   { channel: "WHATSAPP" }
3. Backend создаёт Docker-контейнер
   с Baileys
4. Baileys генерирует QR-код
   → WebSocket → UI
5. Админ сканирует QR телефоном
   (WhatsApp → Linked Devices)
6. Baileys получает auth state
   → шифрование (AES-256)
   → PostgreSQL
7. Статус: QR_PENDING → CONNECTED
8. Номер клуба готов к отправке!
                  `.trim()}</pre>
                </div>
                <div>
                  <h4 className="text-xs font-bold text-gray-700 mb-2">Telegram (MTProto)</h4>
                  <pre className="text-[10px] text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
1. Админ клуба → "Подключить Telegram"
2. POST /v1/gateway/sessions
   { channel: "TELEGRAM",
     phoneNumber: "+79991234567" }
3. GramJS → Telegram API:
   sendCode(phone)
4. Telegram присылает SMS-код
5. Админ вводит код в UI
   POST /v1/gateway/sessions/:id/auth
   { code: "12345" }
6. Если 2FA → ввод пароля
7. GramJS получает session string
   → шифрование → PostgreSQL
8. Статус: CONNECTED
                  `.trim()}</pre>
                </div>
              </div>
            </div>

            {/* Send first message flow */}
            <div className="bg-gray-50 rounded-xl p-5 border border-border mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
                <Send className="h-4 w-4 text-emerald-600" />
                Поток: «Написать первым» клиенту
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
Тренер / Менеджер (Unified Inbox)
         │
         │  "Написать клиенту Иванову (+79161234567)"
         │  Выбирает канал: WhatsApp / Telegram
         ▼
POST /v1/messaging/send-first
{
  "clientId": "uuid-client",
  "channel": "WHATSAPP",
  "text": "Здравствуйте! Это Анна из FitLife. Напоминаю о тренировке завтра в 10:00."
}
         │
         ▼
┌─────────────────────────────────┐
│   Gateway Routing Service       │
│                                 │
│   1. Найти ChannelSession       │
│      (clubId + channel)         │
│   2. Проверить session.status   │
│      == CONNECTED               │
│   3. Проверить rate limit       │
│      (< 200 msg/day)            │
│   4. Если Gateway доступен →    │
│      отправить через шлюз       │
│   5. Если нет → fallback на     │
│      Bot API / Business API     │
└──────────┬──────────────────────┘
           │
           ▼
┌──────────────────────────────┐
│  wa-gateway (Baileys)        │
│                              │
│  const jid =                 │
│    "79161234567@s.whatsapp.net"│
│  await sock.sendMessage(     │
│    jid,                      │
│    { text: "Здравствуйте!.." }│
│  )                           │
│                              │
│  → ACK: sent → delivered     │
│    → read                    │
└──────────────────────────────┘
         │
         ▼
Клиент видит сообщение от номера
клуба "+7 999 123-45-67" (Анна)
а НЕ от бота @FitLifeBot
              `.trim()}</pre>
            </div>

            {/* Env variables */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <Lock className="h-4 w-4 text-emerald-600" />
              Переменные окружения (новые)
            </h3>
            <div className="space-y-4 mb-6">
              {envVariables.map((group) => (
                <div key={group.group}>
                  <h4 className="text-xs font-bold text-gray-700 mb-1">{group.group}</h4>
                  <table className="w-full text-xs border-collapse">
                    <thead>
                      <tr className="bg-gray-50">
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border w-64">Переменная</th>
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border w-32">Default</th>
                        <th className="text-left px-3 py-1.5 font-medium text-muted border border-border">Описание</th>
                      </tr>
                    </thead>
                    <tbody>
                      {group.vars.map((v) => (
                        <tr key={v.name} className="hover:bg-gray-50/50">
                          <td className="px-3 py-1.5 border border-border font-mono text-emerald-700">{v.name}</td>
                          <td className="px-3 py-1.5 border border-border font-mono text-gray-500">{v.value || '***'}</td>
                          <td className="px-3 py-1.5 border border-border text-gray-600">{v.desc}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              ))}
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ ФАЗЫ РЕАЛИЗАЦИИ ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <ArrowRight className="h-5 w-5 text-emerald-600" />
              Часть 6: Фазы реализации
            </h2>
            <p className="text-sm text-muted mb-6">
              Общая трудоёмкость: 9-13 недель. Параллелизуется с основным ТЗ #42 (Bot API).
            </p>

            {/* Summary metrics */}
            <div className="grid grid-cols-4 gap-3 mb-6">
              <div className="bg-emerald-50 rounded-xl p-3 text-center border border-emerald-100">
                <p className="text-2xl font-bold text-emerald-700">4</p>
                <p className="text-[10px] text-muted mt-1">Фазы</p>
              </div>
              <div className="bg-purple-50 rounded-xl p-3 text-center border border-purple-100">
                <p className="text-2xl font-bold text-purple-700">9-13</p>
                <p className="text-[10px] text-muted mt-1">Недель</p>
              </div>
              <div className="bg-blue-50 rounded-xl p-3 text-center border border-blue-100">
                <p className="text-2xl font-bold text-blue-700">3</p>
                <p className="text-[10px] text-muted mt-1">Микросервиса</p>
              </div>
              <div className="bg-orange-50 rounded-xl p-3 text-center border border-orange-100">
                <p className="text-2xl font-bold text-orange-700">12</p>
                <p className="text-[10px] text-muted mt-1">API эндпоинтов</p>
              </div>
            </div>

            {/* Phase cards */}
            <div className="space-y-4 mb-6">
              {gatewayPhases.map((phase, pi) => (
                <div key={pi} className="border border-border rounded-xl p-4">
                  <div className="flex items-center justify-between mb-2">
                    <div className="flex items-center gap-2">
                      <h4 className="font-semibold text-gray-900 text-sm">{phase.phase}</h4>
                      {priorityBadge(phase.priority)}
                    </div>
                    <span className="text-xs bg-emerald-50 text-emerald-700 font-semibold px-2 py-0.5 rounded-full">
                      {phase.timeline}
                    </span>
                  </div>
                  <ul className="space-y-1">
                    {phase.deliverables.map((d, i) => (
                      <li key={i} className="flex items-start gap-1.5 text-xs text-gray-600">
                        <CheckCircle2 className="h-3 w-3 text-emerald-500 shrink-0 mt-0.5" />
                        {d}
                      </li>
                    ))}
                  </ul>
                </div>
              ))}
            </div>

            {/* Integration with original TZ */}
            <div className="bg-gray-50 rounded-xl p-5 border border-border mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
                <Wifi className="h-4 w-4 text-emerald-600" />
                Интеграция с основным ТЗ #42 (Bot API)
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
┌──────────────────────────────────────────────────────────────┐
│           Итоговая архитектура мессенджеров MyFitCRM          │
│                                                              │
│  Метод доставки выбирается автоматически:                     │
│                                                              │
│  ┌─────────────────────┐   ┌─────────────────────────────┐   │
│  │   Gateway Layer     │   │       Bot API Layer          │   │
│  │   (этот документ)   │   │       (ТЗ #42)               │   │
│  │                     │   │                               │   │
│  │  • Писать первым    │   │  • Массовые рассылки (HSM)   │   │
│  │  • Личные сообщения │   │  • Чат-бот (FAQ, запись)     │   │
│  │  • От номера клуба  │   │  • Inline-кнопки (TG)       │   │
│  │  • Unified Inbox    │   │  • VK рассылки подписчикам   │   │
│  │                     │   │  • Масштабируемость          │   │
│  │  Baileys + GramJS   │   │  Meta Cloud API + TG Bot API │   │
│  │  + vk-io            │   │  + VK Community API          │   │
│  └──────────┬──────────┘   └──────────────┬──────────────┘   │
│             │                              │                  │
│             ▼                              ▼                  │
│  ┌──────────────────────────────────────────────────────┐    │
│  │         Messaging Service (NestJS, единый)           │    │
│  │                                                      │    │
│  │  DeliveryMethod: GATEWAY | BOT_API | BUSINESS_API    │    │
│  │                                                      │    │
│  │  Gateway Routing Service:                            │    │
│  │    if (firstMessage && session.connected) → GATEWAY   │    │
│  │    if (massMailout) → BOT_API / BUSINESS_API          │    │
│  │    if (chatbot) → BOT_API                             │    │
│  │    if (session.disconnected) → fallback BOT_API       │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  Результат: клуб может писать первым И использовать ботов    │
└──────────────────────────────────────────────────────────────┘
              `.trim()}</pre>
            </div>
          </div>

          {/* Divider */}
          <div className="border-t-2 border-emerald-100" />

          {/* ═══════════════ ВЫВОДЫ ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <CheckCircle2 className="h-5 w-5 text-emerald-600" />
              Выводы и рекомендации
            </h2>

            <div className="bg-emerald-50 rounded-xl p-5 border border-emerald-100 mb-6">
              <ul className="space-y-2">
                {[
                  'Дополнить ТЗ #42 Gateway-слоем: Baileys (WhatsApp) + GramJS (Telegram) + vk-io (VK) — возможность писать первым с номера клуба',
                  'Гибридная стратегия: Gateway для личных сообщений (писать первым, напоминания), Bot API для массовых рассылок и чат-ботов',
                  'Своё решение (не Whapi.cloud): полный контроль данных, нет vendor lock-in, дешевле при масштабировании (100+ клубов)',
                  'Микросервисная архитектура: отдельный Docker-контейнер per номер — изоляция, масштабируемость, независимые обновления',
                  'Шифрование сессий (AES-256): credentials хранятся в PostgreSQL в зашифрованном виде, ключ в env',
                  'Rate limiting обязателен: WhatsApp ≤ 200 msg/день, Telegram ≤ 30 msg/сек — иначе бан номера',
                  'Мониторинг здоровья сессий: Prometheus метрики, алерты в Telegram при disconnect/ban',
                  'Fallback-стратегия: если Gateway-сессия отключена → автоматический переход на Bot API',
                  'Фаза 0 (WhatsApp MVP) — 3-4 недели. Фаза 1 (Telegram) — ещё 2-3 недели. Итого MVP: 5-7 недель',
                  'Данный документ дополняет, а не заменяет ТЗ #42. Оба подхода сосуществуют.',
                ].map((item, i) => (
                  <li key={i} className="flex items-start gap-1.5 text-xs text-emerald-800">
                    <CheckCircle2 className="h-3 w-3 text-emerald-600 shrink-0 mt-0.5" />
                    {item}
                  </li>
                ))}
              </ul>
            </div>

            {/* Updated limitation list for TZ #42 */}
            <div className="bg-yellow-50 rounded-xl p-5 border border-yellow-100">
              <h3 className="text-sm font-semibold text-yellow-800 mb-2 flex items-center gap-2">
                <AlertTriangle className="h-4 w-4" />
                Обновлённые ограничения v1 (с учётом Gateway)
              </h3>
              <ul className="space-y-1">
                {[
                  'MAX: только Bot API (Gateway не требуется — малая аудитория, нет клиентского API для userbot)',
                  'Запись звонков через мессенджеры — не поддерживается (только текст, фото, документы)',
                  'Групповые чаты — не поддерживаются (только 1-к-1: клуб ↔ клиент)',
                  'Видео/голосовые сообщения — не в v1 (добавить в v2)',
                  'WhatsApp Gateway: risk of ban при агрессивном rate — необходим warm-up номера (первые 2 недели: ≤ 50 msg/день)',
                  'Telegram MTProto: требуется API ID/Hash с my.telegram.org — регистрация ручная per-платформа',
                  'VK User API: нестабильный (капча), рекомендуется Community API как primary + User API как дополнение',
                  'Мобильное приложение: «Написать первым» — только с веб-панели в v1 (мобильная отправка в v2)',
                ].map((item, i) => (
                  <li key={i} className="flex items-start gap-1.5 text-xs text-yellow-800">
                    <AlertTriangle className="h-3 w-3 text-yellow-500 shrink-0 mt-0.5" />
                    {item}
                  </li>
                ))}
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
