'use client';

import { useRef } from 'react';
import { useRouter } from 'next/navigation';
import {
  ArrowLeft,
  FileDown,
  Printer,
  Table2,
  MessageCircle,
  CheckCircle2,
  XCircle,
  AlertTriangle,
  Star,
  Zap,
  Shield,
  Users,
  Bot,
  Send,
  Link2,
  Clock,
  BarChart3,
  Layers,
  ArrowRight,
} from 'lucide-react';
import { cn } from '@/lib/cn';

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

/* ─────────────── Данные: Анализ 1С:Фитнес клуб ─────────────── */

interface MessengerCapability {
  messenger: string;
  icon: string;
  supported: boolean;
  apiType: string;
  features: string[];
  limitations: string[];
  score: number; // 1-10
}

const competitorMessengers: MessengerCapability[] = [
  {
    messenger: 'WhatsApp',
    icon: '💬',
    supported: true,
    apiType: 'WhatsApp Business API (Cloud API)',
    features: [
      'Отправка и приём сообщений в едином окне',
      'Шаблонные сообщения (HSM) для исходящих',
      'Ссылки на оплату прямо в чате',
      'Автоответы по ключевым словам',
      'Привязка к карточке клиента (история)',
      'Уведомления: запись, отмена, напоминание',
    ],
    limitations: [
      'Требуется верификация бизнеса Meta',
      'Платные шаблонные сообщения (conversation-based pricing)',
      'Ограничение 24-часового окна для свободной переписки',
    ],
    score: 8,
  },
  {
    messenger: 'Telegram',
    icon: '✈️',
    supported: true,
    apiType: 'Telegram Bot API',
    features: [
      'Бот клуба: запись, расписание, баланс',
      'Inline-кнопки для действий (записаться, отменить)',
      'Уведомления тренерам и координаторам',
      'История переписки в карточке клиента',
      'Групповые каналы для сотрудников',
    ],
    limitations: [
      'Только через бота (нет прямого чата с номера клуба)',
      'Клиент должен сам начать диалог с ботом',
      'Нет аналога HSM — нельзя писать первым без /start',
    ],
    score: 7,
  },
  {
    messenger: 'VK (ВКонтакте)',
    icon: '🔵',
    supported: true,
    apiType: 'VK Community API (сообщения сообщества)',
    features: [
      'Сообщения от имени группы клуба',
      'Чат-бот с клавиатурой и действиями',
      'Рассылки подписчикам сообщества',
      'Уведомления о записи и акциях',
      'Автоответы и сценарии',
    ],
    limitations: [
      'Требуется подтверждённое сообщество',
      'Ограничения на рассылки (клиент должен подписаться)',
      'Более низкая конверсия открытий vs. WhatsApp',
    ],
    score: 6,
  },
  {
    messenger: 'MAX (ex-OK)',
    icon: '🟡',
    supported: true,
    apiType: 'MAX Bot API (TamTam/OK Messenger)',
    features: [
      'Бот для записи и уведомлений',
      'Кнопки и карусели для услуг',
      'Уведомления о событиях клуба',
    ],
    limitations: [
      'Малая аудитория по сравнению с WA/TG',
      'Ограниченный API (меньше возможностей)',
      'Нестабильность API (частые изменения)',
      'Нет ссылок на оплату в чате',
    ],
    score: 4,
  },
];

interface ComparisonRow {
  feature: string;
  category: string;
  fitness1c: string;
  fitness1cStatus: 'yes' | 'partial' | 'no';
  myfitcrm: string;
  myfitcrmStatus: 'yes' | 'partial' | 'no' | 'planned';
}

const comparisonTable: ComparisonRow[] = [
  { feature: 'Единое окно диалогов (Inbox)', category: 'Ядро', fitness1c: 'Все мессенджеры в одном UI', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'WhatsApp Business API', category: 'Каналы', fitness1c: 'Cloud API, шаблоны HSM', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'Telegram Bot API', category: 'Каналы', fitness1c: 'Бот + inline-кнопки', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'VK Community API', category: 'Каналы', fitness1c: 'Сообщения от группы', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'MAX Bot API', category: 'Каналы', fitness1c: 'Бот для уведомлений', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'Автоответы / чат-боты', category: 'Автоматизация', fitness1c: 'Ключевые слова + сценарии', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'Ссылки на оплату в чате', category: 'Платежи', fitness1c: 'Генерация ссылки в WA/TG', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'История переписки в карточке', category: 'CRM', fitness1c: 'Привязка к клиенту', fitness1cStatus: 'yes', myfitcrm: 'Не реализовано', myfitcrmStatus: 'planned' },
  { feature: 'Уведомления сотрудникам', category: 'Внутренние', fitness1c: 'TG/VK для тренеров', fitness1cStatus: 'yes', myfitcrm: 'Только Push (FCM/APNs)', myfitcrmStatus: 'partial' },
  { feature: 'Сегментация рассылок', category: 'Маркетинг', fitness1c: 'По абонементу, активности', fitness1cStatus: 'yes', myfitcrm: 'Только Email (EmailCampaign)', myfitcrmStatus: 'partial' },
  { feature: 'Трекинг доставки/прочтения', category: 'Аналитика', fitness1c: 'Статусы сообщений', fitness1cStatus: 'partial', myfitcrm: 'Только Email (EmailLog)', myfitcrmStatus: 'partial' },
  { feature: 'Viber', category: 'Каналы', fitness1c: 'Поддерживается', fitness1cStatus: 'yes', myfitcrm: 'Не планируется в v1', myfitcrmStatus: 'no' },
];

/* ─────────────── Данные: ТЗ для MyFitCRM ─────────────── */

interface TzModule {
  id: string;
  name: string;
  description: string;
  priority: 'P0' | 'P1' | 'P2';
  effort: string;
  features: string[];
}

const tzModules: TzModule[] = [
  {
    id: 'messaging-core',
    name: 'Ядро мессенджер-модуля',
    description: 'Единое окно диалогов (Unified Inbox), маршрутизация сообщений, хранение истории',
    priority: 'P0',
    effort: '3-4 недели',
    features: [
      'Unified Inbox: все каналы в одном интерфейсе (веб-панель)',
      'Маршрутизация входящих: автоназначение на тренера/координатора',
      'Prisma-модели: Conversation, Message, Channel, MessageTemplate',
      'Хранение истории переписки с привязкой к Client (clientId)',
      'Статусы сообщений: queued → sent → delivered → read → failed',
      'BullMQ очередь: отправка, retry (3 попытки), rate limiting per-club',
      'REST API: /v1/messaging/* (CRUD conversations, send, history)',
      'WebSocket: real-time обновление диалогов в UI',
      'NestJS Guard: @RequireModule("messaging")',
    ],
  },
  {
    id: 'whatsapp',
    name: 'WhatsApp Business API',
    description: 'Интеграция через Meta Cloud API: шаблоны HSM, входящие/исходящие, webhook',
    priority: 'P0',
    effort: '2-3 недели',
    features: [
      'Подключение через Meta Cloud API (v18+)',
      'Шаблонные сообщения (HSM): создание, отправка, статусы',
      'Входящие сообщения: webhook → conversation → UI',
      'Исходящие: свободный текст (в окне 24ч) + шаблоны (вне окна)',
      'Медиа: отправка/приём изображений, документов',
      'Ссылки на оплату: deeplink в сообщении',
      'Webhook от Meta: статусы доставки (sent/delivered/read/failed)',
      'Конфигурация per-club: WABA ID, Phone Number ID, Access Token',
      'Rate limiting: соответствие Tier-ам Meta (1K/10K/100K msg/day)',
    ],
  },
  {
    id: 'telegram',
    name: 'Telegram Bot API',
    description: 'Бот клуба: запись, расписание, уведомления, inline-кнопки',
    priority: 'P0',
    effort: '2-3 недели',
    features: [
      'Создание бота через BotFather (per-club конфигурация)',
      'Команды: /start, /schedule, /balance, /book, /cancel',
      'Inline-кнопки: запись на тренировку, подтверждение, отмена',
      'Входящие сообщения → Unified Inbox',
      'Исходящие: текст, фото, документы, кнопки',
      'Уведомления: запись создана, отменена, напоминание за 24ч',
      'Webhook (long polling fallback): getUpdates / setWebhook',
      'Привязка Telegram ID к карточке клиента (по номеру телефона)',
      'Уведомления сотрудникам: отдельный бот или канал',
    ],
  },
  {
    id: 'vk',
    name: 'VK Community API',
    description: 'Сообщения от группы клуба, бот с клавиатурой, рассылки подписчикам',
    priority: 'P1',
    effort: '2 недели',
    features: [
      'Подключение через VK Community API (Callback API / Long Poll)',
      'Сообщения от имени группы клуба',
      'Клавиатура (keyboard) с кнопками действий',
      'Входящие → Unified Inbox',
      'Рассылки подписчикам сообщества (с согласия)',
      'Привязка VK ID к карточке клиента',
      'Автоответы по ключевым словам',
    ],
  },
  {
    id: 'max',
    name: 'MAX Bot API',
    description: 'Бот для уведомлений и записи через MAX (ex-OK Messenger)',
    priority: 'P2',
    effort: '1-2 недели',
    features: [
      'Подключение через MAX Bot API',
      'Кнопки и карусели для каталога услуг',
      'Входящие → Unified Inbox',
      'Уведомления: запись, отмена, акции',
      'Привязка MAX ID к карточке клиента',
    ],
  },
  {
    id: 'chatbot',
    name: 'Чат-бот (автоответы и сценарии)',
    description: 'Конструктор сценариев: ключевые слова, цепочки, FAQ, переключение на оператора',
    priority: 'P1',
    effort: '2-3 недели',
    features: [
      'Конструктор сценариев: визуальный flow-builder',
      'Триггеры: ключевые слова, первое сообщение, время суток',
      'Действия: ответ текстом, кнопки, передача оператору, запись на тренировку',
      'FAQ-бот: автоматические ответы на частые вопросы',
      'Переключение на живого оператора (тренера/координатора)',
      'Аналитика: кол-во диалогов, время ответа, % автоматизации',
    ],
  },
];

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

const prismaModels: PrismaModel[] = [
  {
    name: 'Conversation',
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'clubId', type: 'String', description: 'Привязка к клубу (multi-tenancy)' },
      { name: 'clientId', type: 'String?', description: 'Привязка к клиенту CRM' },
      { name: 'channel', type: 'MessengerChannel', description: 'WHATSAPP | TELEGRAM | VK | MAX' },
      { name: 'externalId', type: 'String', description: 'ID чата во внешней системе' },
      { name: 'assignedUserId', type: 'String?', description: 'Назначенный сотрудник' },
      { name: 'status', type: 'ConversationStatus', description: 'OPEN | CLOSED | PENDING' },
      { name: 'lastMessageAt', type: 'DateTime?', description: 'Время последнего сообщения' },
      { name: 'unreadCount', type: 'Int @default(0)', description: 'Непрочитанных' },
      { name: 'metadata', type: 'Json?', description: 'Доп. данные канала' },
    ],
  },
  {
    name: 'Message',
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'conversationId', type: 'String', description: 'FK → Conversation' },
      { name: 'direction', type: 'MessageDirection', description: 'INBOUND | OUTBOUND' },
      { name: 'content', type: 'String', description: 'Текст сообщения' },
      { name: 'contentType', type: 'MessageContentType', description: 'TEXT | IMAGE | DOCUMENT | TEMPLATE' },
      { name: 'externalId', type: 'String?', description: 'ID сообщения во внешней системе' },
      { name: 'status', type: 'MessageStatus', description: 'QUEUED | SENT | DELIVERED | READ | FAILED' },
      { name: 'sentAt', type: 'DateTime?', description: 'Время отправки' },
      { name: 'deliveredAt', type: 'DateTime?', description: 'Время доставки' },
      { name: 'readAt', type: 'DateTime?', description: 'Время прочтения' },
      { name: 'errorMsg', type: 'String?', description: 'Ошибка доставки' },
      { name: 'senderUserId', type: 'String?', description: 'Сотрудник-отправитель' },
    ],
  },
  {
    name: 'MessageTemplate',
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'clubId', type: 'String', description: 'Привязка к клубу' },
      { name: 'channel', type: 'MessengerChannel', description: 'Канал (или ALL)' },
      { name: 'name', type: 'String', description: 'Системное имя шаблона' },
      { name: 'title', type: 'String', description: 'Отображаемое название' },
      { name: 'body', type: 'String', description: 'Текст с {{placeholders}}' },
      { name: 'type', type: 'TemplateType', description: 'WELCOME | REMINDER | PROMO | CUSTOM' },
      { name: 'externalId', type: 'String?', description: 'ID шаблона в WA (HSM)' },
      { name: 'isActive', type: 'Boolean @default(true)', description: 'Активен' },
    ],
  },
  {
    name: 'ChannelConfig',
    fields: [
      { name: 'id', type: 'String @id @default(uuid())', description: 'PK' },
      { name: 'clubId', type: 'String', description: 'Привязка к клубу' },
      { name: 'channel', type: 'MessengerChannel', description: 'Канал' },
      { name: 'isEnabled', type: 'Boolean @default(false)', description: 'Включён' },
      { name: 'credentials', type: 'Json', description: 'Зашифрованные credentials (token, API key)' },
      { name: 'webhookUrl', type: 'String?', description: 'URL для входящих webhook' },
      { name: 'settings', type: 'Json?', description: 'Настройки канала (rate limit, auto-reply)' },
    ],
  },
];

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

const apiEndpoints: ApiEndpoint[] = [
  { method: 'GET', path: '/v1/messaging/conversations', description: 'Список диалогов (фильтр по каналу, статусу, клиенту)', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'GET', path: '/v1/messaging/conversations/:id', description: 'Детали диалога + последние сообщения', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'GET', path: '/v1/messaging/conversations/:id/messages', description: 'История сообщений (cursor-based пагинация)', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'POST', path: '/v1/messaging/conversations/:id/send', description: 'Отправить сообщение в диалог', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'POST', path: '/v1/messaging/send', description: 'Отправить сообщение клиенту (создать диалог если нет)', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'PUT', path: '/v1/messaging/conversations/:id/assign', description: 'Назначить диалог сотруднику', roles: 'coordinator, manager, club_admin' },
  { method: 'PUT', path: '/v1/messaging/conversations/:id/close', description: 'Закрыть диалог', roles: 'trainer, coordinator, manager, club_admin' },
  { method: 'GET', path: '/v1/messaging/templates', description: 'Список шаблонов сообщений', roles: 'club_admin' },
  { method: 'POST', path: '/v1/messaging/templates', description: 'Создать шаблон сообщения', roles: 'club_admin' },
  { method: 'PUT', path: '/v1/messaging/templates/:id', description: 'Обновить шаблон', roles: 'club_admin' },
  { method: 'DELETE', path: '/v1/messaging/templates/:id', description: 'Удалить шаблон', roles: 'club_admin' },
  { method: 'GET', path: '/v1/messaging/channels', description: 'Список подключённых каналов', roles: 'club_admin' },
  { method: 'PUT', path: '/v1/messaging/channels/:channel', description: 'Настроить канал (credentials, webhook)', roles: 'club_admin' },
  { method: 'POST', path: '/v1/messaging/channels/:channel/test', description: 'Тестовое сообщение для проверки', roles: 'club_admin' },
  { method: 'GET', path: '/v1/messaging/stats', description: 'Статистика: сообщения, каналы, время ответа', roles: 'manager, club_admin' },
  { method: 'POST', path: '/v1/messaging/webhook/:channel', description: 'Входящий webhook от мессенджера', roles: 'public (HMAC)' },
];

interface PhaseItem {
  phase: string;
  timeline: string;
  modules: string[];
  deliverables: string[];
}

const phases: PhaseItem[] = [
  {
    phase: 'Фаза 1: Ядро + WhatsApp + Telegram',
    timeline: '6-8 недель',
    modules: ['messaging-core', 'whatsapp', 'telegram'],
    deliverables: [
      'Prisma-модели: Conversation, Message, MessageTemplate, ChannelConfig',
      'NestJS модуль messaging/ (контроллер, сервисы, BullMQ)',
      'Provider Strategy: WhatsAppProvider, TelegramProvider',
      'Unified Inbox UI в панели администратора клуба',
      'Webhook endpoints для входящих сообщений',
      'Привязка переписки к карточке клиента',
      'Unit + E2E тесты',
    ],
  },
  {
    phase: 'Фаза 2: VK + Чат-бот',
    timeline: '4-5 недель',
    modules: ['vk', 'chatbot'],
    deliverables: [
      'VK Community API интеграция',
      'Конструктор чат-ботов (flow-builder)',
      'Автоответы и FAQ-бот',
      'Переключение бот → оператор',
      'Аналитика мессенджеров (дашборд)',
    ],
  },
  {
    phase: 'Фаза 3: MAX + Доп. функции',
    timeline: '2-3 недели',
    modules: ['max'],
    deliverables: [
      'MAX Bot API интеграция',
      'Рассылки через мессенджеры (сегментация)',
      'Ссылки на оплату в чатах',
      'Мобильное приложение: экран чатов',
    ],
  },
];

const overallScore = {
  fitness1c: 7.5,
  categories: [
    { name: 'Покрытие каналов', score: 9, comment: '5 мессенджеров — отличное покрытие' },
    { name: 'Единое окно (Inbox)', score: 8, comment: 'Все диалоги в одном UI' },
    { name: 'Автоматизация', score: 7, comment: 'Чат-боты + автоответы, но без визуального конструктора' },
    { name: 'CRM-интеграция', score: 8, comment: 'История в карточке клиента' },
    { name: 'Платежи в чатах', score: 7, comment: 'Ссылки на оплату (WA), но не во всех каналах' },
    { name: 'Аналитика', score: 5, comment: 'Базовая: статусы доставки, нет ROI рассылок' },
    { name: 'Настройка per-club', score: 7, comment: 'Каждый клуб подключает свои каналы' },
    { name: 'Документация API', score: 8, comment: 'Хорошо документировано' },
  ],
};

/* ─────────────── Компонент страницы ─────────────── */

const statusMap = {
  yes: { bg: 'bg-green-50', text: 'text-green-700', label: 'Реализовано' },
  partial: { bg: 'bg-yellow-50', text: 'text-yellow-700', label: 'Частично' },
  no: { bg: 'bg-red-50', text: 'text-red-700', label: 'Нет' },
  planned: { bg: 'bg-blue-50', text: 'text-blue-700', label: 'Планируется' },
} as const;

const statusBadge = (status: string) => {
  const s = statusMap[status as keyof typeof statusMap] ?? statusMap.no;
  return (
    <span className={cn('text-[10px] font-semibold px-2 py-0.5 rounded-full', s.bg, s.text)}>
      {s.label}
    </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 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>
  );
};

export default function MessengerIntegrationsTzDocument() {
  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-integrations-tz.pdf');
  };

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

    // Sheet 1: Comparison
    const compData = comparisonTable.map((r) => ({
      'Функция': r.feature,
      'Категория': r.category,
      '1С:Фитнес клуб': r.fitness1c,
      'Статус 1С': r.fitness1cStatus === 'yes' ? 'Да' : r.fitness1cStatus === 'partial' ? 'Частично' : 'Нет',
      'MyFitCRM': r.myfitcrm,
      'Статус MyFitCRM': r.myfitcrmStatus === 'planned' ? 'Планируется' : r.myfitcrmStatus === 'partial' ? 'Частично' : 'Нет',
    }));
    const ws1 = XLSX.utils.json_to_sheet(compData);
    ws1['!cols'] = [{ wch: 35 }, { wch: 15 }, { wch: 35 }, { wch: 12 }, { wch: 30 }, { wch: 15 }];
    XLSX.utils.book_append_sheet(wb, ws1, 'Сравнение');

    // Sheet 2: Modules
    const modData = tzModules.map((m) => ({
      'ID': m.id,
      'Модуль': m.name,
      'Описание': m.description,
      'Приоритет': m.priority,
      'Оценка трудоёмкости': m.effort,
      'Кол-во фич': m.features.length,
    }));
    const ws2 = XLSX.utils.json_to_sheet(modData);
    ws2['!cols'] = [{ wch: 18 }, { wch: 25 }, { wch: 50 }, { wch: 10 }, { wch: 15 }, { wch: 12 }];
    XLSX.utils.book_append_sheet(wb, ws2, 'Модули ТЗ');

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

    // Sheet 4: Prisma Models
    const prismaData = prismaModels.flatMap((m) =>
      m.fields.map((f) => ({
        'Модель': m.name,
        'Поле': f.name,
        'Тип': f.type,
        'Описание': f.description,
      })),
    );
    const ws4 = XLSX.utils.json_to_sheet(prismaData);
    ws4['!cols'] = [{ wch: 18 }, { wch: 18 }, { wch: 35 }, { wch: 40 }];
    XLSX.utils.book_append_sheet(wb, ws4, 'Prisma-модели');

    // Sheet 5: Phases
    const phaseData = phases.map((p) => ({
      'Фаза': p.phase,
      'Сроки': p.timeline,
      'Модули': p.modules.join(', '),
      'Результаты': p.deliverables.join('; '),
    }));
    const ws5 = XLSX.utils.json_to_sheet(phaseData);
    ws5['!cols'] = [{ wch: 35 }, { wch: 12 }, { wch: 30 }, { wch: 80 }];
    XLSX.utils.book_append_sheet(wb, ws5, 'Фазы');

    // Sheet 6: Scores
    const scoreData = overallScore.categories.map((c) => ({
      'Критерий': c.name,
      'Оценка (1-10)': c.score,
      'Комментарий': c.comment,
    }));
    const ws6 = XLSX.utils.json_to_sheet(scoreData);
    ws6['!cols'] = [{ wch: 25 }, { wch: 14 }, { wch: 50 }];
    XLSX.utils.book_append_sheet(wb, ws6, 'Оценка 1С');

    XLSX.writeFile(wb, 'messenger-integrations-tz.xlsx');
  };

  const avgScore = Math.round(overallScore.categories.reduce((s, c) => s + c.score, 0) / overallScore.categories.length * 10) / 10;

  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-indigo-50 p-2.5 rounded-lg">
                <MessageCircle className="h-6 w-6 text-indigo-600" />
              </div>
              <div>
                <h1 className="text-xl font-bold text-gray-900">
                  ТЗ: Интеграция мессенджеров в MyFitCRM
                </h1>
                <p className="text-sm text-muted mt-1">
                  Дата: {LAST_UPDATE} | На основе анализа 1С:Фитнес клуб (задача #39) | WhatsApp, Telegram, VK, MAX
                </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">

          {/* ═══════════════ ЧАСТЬ 1: АНАЛИЗ 1С ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <BarChart3 className="h-5 w-5 text-indigo-600" />
              Часть 1: Анализ реализации мессенджеров в 1С:Фитнес клуб
            </h2>
            <p className="text-sm text-muted mb-6">
              Оценка по данным из{' '}
              <a href="/document/competitor-1c-fitness" className="text-indigo-600 underline hover:text-indigo-800">
                конкурентного анализа (задача #39)
              </a>
            </p>

            {/* Overall score card */}
            <div className="grid grid-cols-2 gap-4 mb-6">
              <div className="bg-gradient-to-br from-indigo-50 to-purple-50 rounded-xl p-5 border border-indigo-100">
                <div className="flex items-center justify-between mb-3">
                  <h3 className="text-sm font-semibold text-gray-700">Общая оценка мессенджеров 1С</h3>
                  <Star className="h-5 w-5 text-yellow-500" />
                </div>
                <div className="flex items-end gap-2">
                  <span className="text-4xl font-bold text-indigo-700">{avgScore}</span>
                  <span className="text-lg text-gray-400 mb-1">/10</span>
                </div>
                <p className="text-xs text-muted mt-2">
                  Средневзвешенная по 8 критериям. Сильная сторона — покрытие каналов. Слабая — аналитика.
                </p>
              </div>
              <div className="bg-gradient-to-br from-orange-50 to-amber-50 rounded-xl p-5 border border-orange-100">
                <div className="flex items-center justify-between mb-3">
                  <h3 className="text-sm font-semibold text-gray-700">MyFitCRM — текущее состояние</h3>
                  <AlertTriangle className="h-5 w-5 text-orange-500" />
                </div>
                <div className="flex items-end gap-2">
                  <span className="text-4xl font-bold text-orange-600">0</span>
                  <span className="text-lg text-gray-400 mb-1">мессенджеров</span>
                </div>
                <p className="text-xs text-muted mt-2">
                  Мессенджеры отмечены как «Планируется» в ТЗ. Реализованы только Push (FCM/APNs) и Email-рассылки.
                </p>
              </div>
            </div>

            {/* Score breakdown */}
            <div className="mb-6">
              <h3 className="text-sm font-semibold text-gray-700 mb-3">Оценка по критериям</h3>
              <div className="space-y-2">
                {overallScore.categories.map((cat) => (
                  <div key={cat.name} className="flex items-center gap-3">
                    <span className="text-sm text-gray-600 w-44 shrink-0">{cat.name}</span>
                    <div className="flex-1 bg-gray-100 rounded-full h-2.5">
                      <div
                        className="h-2.5 rounded-full transition-all"
                        style={{
                          width: `${cat.score * 10}%`,
                          backgroundColor: cat.score >= 8 ? '#16a34a' : cat.score >= 6 ? '#f59e0b' : '#ef4444',
                        }}
                      />
                    </div>
                    <span className="text-sm font-bold w-8 text-right" style={{
                      color: cat.score >= 8 ? '#16a34a' : cat.score >= 6 ? '#f59e0b' : '#ef4444',
                    }}>
                      {cat.score}
                    </span>
                    <span className="text-xs text-muted w-72 shrink-0">{cat.comment}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Messenger cards */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3">Детализация по каждому мессенджеру</h3>
            <div className="grid grid-cols-2 gap-4 mb-6">
              {competitorMessengers.map((m) => (
                <div key={m.messenger} className="border border-border rounded-xl p-4">
                  <div className="flex items-center justify-between mb-3">
                    <div className="flex items-center gap-2">
                      <span className="text-xl">{m.icon}</span>
                      <h4 className="font-semibold text-gray-900">{m.messenger}</h4>
                    </div>
                    <div className="flex items-center gap-1.5">
                      <span className="text-xs text-muted">Оценка:</span>
                      <span className={cn(
                        'text-sm font-bold',
                        m.score >= 8 ? 'text-green-600' : m.score >= 6 ? 'text-yellow-600' : 'text-red-600',
                      )}>
                        {m.score}/10
                      </span>
                    </div>
                  </div>
                  <p className="text-xs text-muted mb-2 font-mono">{m.apiType}</p>
                  <div className="mb-2">
                    <p className="text-[10px] font-semibold text-green-700 uppercase tracking-wider mb-1">Возможности:</p>
                    <ul className="space-y-0.5">
                      {m.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">
                      {m.limitations.map((l, i) => (
                        <li key={i} className="flex items-start gap-1.5 text-xs text-gray-500">
                          <XCircle className="h-3 w-3 text-red-400 shrink-0 mt-0.5" />
                          {l}
                        </li>
                      ))}
                    </ul>
                  </div>
                </div>
              ))}
            </div>

            {/* Comparison table */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3">Сравнение: 1С:Фитнес клуб vs MyFitCRM (мессенджеры)</h3>
            <div className="overflow-x-auto mb-2">
              <table className="w-full text-sm 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-center px-3 py-2 font-medium text-muted border border-border w-20">Категория</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">1С:Фитнес клуб</th>
                    <th className="text-center px-3 py-2 font-medium text-muted border border-border w-24">Статус</th>
                    <th className="text-left px-3 py-2 font-medium text-muted border border-border">MyFitCRM</th>
                    <th className="text-center px-3 py-2 font-medium text-muted border border-border w-24">Статус</th>
                  </tr>
                </thead>
                <tbody>
                  {comparisonTable.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.feature}</td>
                      <td className="px-3 py-2 border border-border text-center text-xs text-muted">{row.category}</td>
                      <td className="px-3 py-2 border border-border text-gray-600 text-xs">{row.fitness1c}</td>
                      <td className="px-3 py-2 border border-border text-center">{statusBadge(row.fitness1cStatus)}</td>
                      <td className="px-3 py-2 border border-border text-gray-600 text-xs">{row.myfitcrm}</td>
                      <td className="px-3 py-2 border border-border text-center">{statusBadge(row.myfitcrmStatus)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

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

          {/* ═══════════════ ЧАСТЬ 2: ТЗ ═══════════════ */}
          <div>
            <h2 className="text-lg font-bold text-gray-900 mb-1 flex items-center gap-2">
              <Layers className="h-5 w-5 text-indigo-600" />
              Часть 2: Техническое задание на интеграцию мессенджеров в MyFitCRM
            </h2>
            <p className="text-sm text-muted mb-6">
              Архитектура, модули, API, модели данных и фазы реализации
            </p>

            {/* Architecture overview */}
            <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-indigo-600" />
                Архитектура решения
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
┌──────────────────────────────────────────────────────────────────────┐
│                        MyFitCRM Messaging                          │
│                                                                    │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐              │
│  │WhatsApp │  │Telegram │  │   VK    │  │  MAX    │  ← Каналы    │
│  │Cloud API│  │ Bot API │  │Community│  │ Bot API │              │
│  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘              │
│       │            │            │            │                    │
│       ▼            ▼            ▼            ▼                    │
│  ┌──────────────────────────────────────────────┐                 │
│  │        Channel Provider (Strategy)           │  ← NestJS      │
│  │  WhatsAppProvider │ TelegramProvider │ ...    │                 │
│  └──────────────────┬───────────────────────────┘                 │
│                     │                                             │
│  ┌──────────────────▼───────────────────────────┐                 │
│  │         MessagingService (ядро)               │                 │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────────┐  │                 │
│  │  │ Routing  │ │ History  │ │ Templates    │  │                 │
│  │  │ Engine   │ │ Store    │ │ Engine       │  │                 │
│  │  └──────────┘ └──────────┘ └──────────────┘  │                 │
│  └──────────────────┬───────────────────────────┘                 │
│                     │                                             │
│       ┌─────────────┼──────────────┐                              │
│       ▼             ▼              ▼                              │
│  ┌─────────┐  ┌──────────┐  ┌──────────┐                         │
│  │ BullMQ  │  │ WebSocket│  │  Prisma  │  ← Инфраструктура      │
│  │ Queue   │  │ Gateway  │  │  Models  │                         │
│  └─────────┘  └──────────┘  └──────────┘                         │
│                                                                    │
│  UI: Unified Inbox (web-club-admin) + Mobile Chat Screen          │
└──────────────────────────────────────────────────────────────────────┘
              `.trim()}</pre>
            </div>

            {/* Summary metrics */}
            <div className="grid grid-cols-5 gap-3 mb-6">
              <div className="bg-indigo-50 rounded-xl p-3 text-center border border-indigo-100">
                <p className="text-2xl font-bold text-indigo-700">4</p>
                <p className="text-[10px] text-muted mt-1">Мессенджера</p>
              </div>
              <div className="bg-green-50 rounded-xl p-3 text-center border border-green-100">
                <p className="text-2xl font-bold text-green-700">6</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">16</p>
                <p className="text-[10px] text-muted mt-1">API эндпоинтов</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">4</p>
                <p className="text-[10px] text-muted mt-1">Prisma-модели</p>
              </div>
              <div className="bg-cyan-50 rounded-xl p-3 text-center border border-cyan-100">
                <p className="text-2xl font-bold text-cyan-700">12-16</p>
                <p className="text-[10px] text-muted mt-1">Недель</p>
              </div>
            </div>

            {/* Modules */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <Layers className="h-4 w-4 text-indigo-600" />
              Модули ТЗ
            </h3>
            <div className="space-y-4 mb-6">
              {tzModules.map((mod) => (
                <div key={mod.id} 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">{mod.name}</h4>
                      {priorityBadge(mod.priority)}
                    </div>
                    <div className="flex items-center gap-2">
                      <Clock className="h-3.5 w-3.5 text-muted" />
                      <span className="text-xs text-muted">{mod.effort}</span>
                    </div>
                  </div>
                  <p className="text-xs text-muted mb-3">{mod.description}</p>
                  <div className="grid grid-cols-2 gap-x-4 gap-y-1">
                    {mod.features.map((f, i) => (
                      <div key={i} className="flex items-start gap-1.5 text-xs text-gray-600">
                        <CheckCircle2 className="h-3 w-3 text-indigo-500 shrink-0 mt-0.5" />
                        {f}
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </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-indigo-600" />
                Структура NestJS-модуля
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
apps/api/src/modules/messaging/
├── messaging.module.ts              // @RequireModule('messaging')
├── messaging.controller.ts          // REST: /v1/messaging/*
├── messaging.service.ts             // Бизнес-логика: маршрутизация, отправка
├── messaging.gateway.ts             // WebSocket: real-time обновления
├── conversation.service.ts          // CRUD диалогов
├── message.service.ts               // Отправка/приём, статусы
├── template.service.ts              // Шаблоны сообщений
├── channel-config.service.ts        // Настройки каналов per-club
├── providers/
│   ├── channel-provider.interface.ts // Strategy interface
│   ├── whatsapp.provider.ts         // WhatsApp Cloud API
│   ├── telegram.provider.ts         // Telegram Bot API
│   ├── vk.provider.ts              // VK Community API
│   └── max.provider.ts             // MAX Bot API
├── processors/
│   └── message-send.processor.ts    // BullMQ: очередь отправки
├── dto/
│   ├── send-message.dto.ts
│   ├── create-template.dto.ts
│   └── channel-config.dto.ts
└── entities/                        // (Prisma-модели)
              `.trim()}</pre>
            </div>

            {/* Prisma models */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <Users className="h-4 w-4 text-indigo-600" />
              Prisma-модели (схема БД)
            </h3>
            <div className="space-y-4 mb-6">
              {prismaModels.map((model) => (
                <div key={model.name}>
                  <h4 className="text-xs font-bold text-indigo-700 mb-1 font-mono">model {model.name}</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-36">Поле</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-indigo-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-indigo-50 rounded-lg p-3 border border-indigo-100">
                <h4 className="text-xs font-bold text-indigo-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>MessengerChannel: WHATSAPP | TELEGRAM | VK | MAX</div>
                  <div>ConversationStatus: OPEN | CLOSED | PENDING</div>
                  <div>MessageDirection: INBOUND | OUTBOUND</div>
                  <div>MessageContentType: TEXT | IMAGE | DOCUMENT | TEMPLATE</div>
                  <div>MessageStatus: QUEUED | SENT | DELIVERED | READ | FAILED</div>
                  <div>TemplateType: WELCOME | REMINDER | PROMO | CUSTOM</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-indigo-600" />
              REST API эндпоинты
            </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-48">Роли</th>
                  </tr>
                </thead>
                <tbody>
                  {apiEndpoints.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>

            {/* Webhook events */}
            <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-indigo-600" />
                Webhook-события (исходящие)
              </h3>
              <div className="grid grid-cols-2 gap-x-6 gap-y-1">
                {[
                  { event: 'message.received', desc: 'Входящее сообщение от клиента' },
                  { event: 'message.sent', desc: 'Сообщение отправлено клиенту' },
                  { event: 'message.delivered', desc: 'Сообщение доставлено' },
                  { event: 'message.read', desc: 'Сообщение прочитано' },
                  { event: 'message.failed', desc: 'Ошибка доставки' },
                  { event: 'conversation.created', desc: 'Новый диалог создан' },
                  { event: 'conversation.assigned', desc: 'Диалог назначен сотруднику' },
                  { event: 'conversation.closed', desc: 'Диалог закрыт' },
                ].map((w) => (
                  <div key={w.event} className="flex items-center gap-2 text-xs">
                    <code className="bg-white px-1.5 py-0.5 rounded border border-border text-indigo-700 font-mono">{w.event}</code>
                    <span className="text-gray-600">{w.desc}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Provider Strategy */}
            <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">
                <Bot className="h-4 w-4 text-indigo-600" />
                Provider Strategy (интерфейс)
              </h3>
              <pre className="text-xs text-gray-600 font-mono leading-relaxed whitespace-pre overflow-x-auto">{`
interface ChannelProvider {
  readonly channel: MessengerChannel;

  // Отправка сообщения
  send(options: SendOptions): Promise<SendResult>;

  // Отправка шаблонного сообщения (HSM для WA)
  sendTemplate(options: TemplateOptions): Promise<SendResult>;

  // Обработка входящего webhook
  handleWebhook(body: unknown, headers: Record<string, string>): Promise<InboundMessage>;

  // Валидация подписи webhook (HMAC)
  verifyWebhook(body: unknown, signature: string): boolean;

  // Проверка конфигурации канала
  validateConfig(config: ChannelConfig): Promise<boolean>;

  // Получение статуса сообщения
  getMessageStatus(externalId: string): Promise<MessageStatus>;
}

// Реализации:
class WhatsAppProvider implements ChannelProvider { channel = 'WHATSAPP'; ... }
class TelegramProvider implements ChannelProvider { channel = 'TELEGRAM'; ... }
class VkProvider       implements ChannelProvider { channel = 'VK';       ... }
class MaxProvider      implements ChannelProvider { channel = 'MAX';      ... }
              `.trim()}</pre>
            </div>

            {/* Env variables */}
            <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">Переменные окружения</h3>
              <div className="grid grid-cols-2 gap-x-6 gap-y-0.5 text-xs font-mono text-gray-600">
                <div># WhatsApp (per-club в БД, глобальные дефолты в .env)</div>
                <div />
                <div>WHATSAPP_API_VERSION=v18.0</div>
                <div>WHATSAPP_WEBHOOK_VERIFY_TOKEN=***</div>
                <div># Telegram</div>
                <div />
                <div>TELEGRAM_WEBHOOK_BASE_URL=https://api.myfitcrm.ru</div>
                <div>TELEGRAM_WEBHOOK_SECRET=***</div>
                <div># VK</div>
                <div />
                <div>VK_API_VERSION=5.199</div>
                <div>VK_CALLBACK_CONFIRMATION=***</div>
                <div># Общие</div>
                <div />
                <div>MESSAGING_RATE_LIMIT=60</div>
                <div className="text-muted"># сообщений/мин per-club</div>
                <div>MESSAGING_QUEUE_CONCURRENCY=5</div>
                <div className="text-muted"># BullMQ workers</div>
                <div>MESSAGING_RETRY_ATTEMPTS=3</div>
                <div className="text-muted"># попытки при ошибке</div>
              </div>
            </div>

            {/* Phases */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
              <ArrowRight className="h-4 w-4 text-indigo-600" />
              Фазы реализации
            </h3>
            <div className="space-y-4 mb-6">
              {phases.map((phase, pi) => (
                <div key={pi} className="border border-border rounded-xl p-4">
                  <div className="flex items-center justify-between mb-2">
                    <h4 className="font-semibold text-gray-900 text-sm">{phase.phase}</h4>
                    <span className="text-xs bg-indigo-50 text-indigo-700 font-semibold px-2 py-0.5 rounded-full">
                      {phase.timeline}
                    </span>
                  </div>
                  <div className="flex gap-2 mb-3">
                    {phase.modules.map((m) => (
                      <span key={m} className="text-[10px] bg-gray-100 text-gray-600 font-mono px-2 py-0.5 rounded">
                        {m}
                      </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-indigo-500 shrink-0 mt-0.5" />
                        {d}
                      </li>
                    ))}
                  </ul>
                </div>
              ))}
            </div>

            {/* Licensing */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3">Модульное лицензирование</h3>
            <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">Модуль</th>
                  <th className="text-center px-3 py-2 font-medium text-muted border border-border">club_modules ID</th>
                  <th className="text-center 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">Стандартная</th>
                  <th className="text-center 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>
                {[
                  { name: 'Мессенджеры (ядро)', id: 'messaging', s: '—', st: '✅', pr: '✅', billing: '+доплата/мес' },
                  { name: 'WhatsApp', id: 'messaging_wa', s: '—', st: '✅', pr: '✅', billing: '+доплата (Meta pricing)' },
                  { name: 'Telegram', id: 'messaging_tg', s: '—', st: '✅', pr: '✅', billing: 'Включено в messaging' },
                  { name: 'VK', id: 'messaging_vk', s: '—', st: '✅', pr: '✅', billing: 'Включено в messaging' },
                  { name: 'MAX', id: 'messaging_max', s: '—', st: '—', pr: '✅', billing: 'Включено в messaging' },
                  { name: 'Чат-бот', id: 'chatbot', s: '—', st: '—', pr: '✅', billing: '+доплата/мес' },
                ].map((row) => (
                  <tr key={row.id} className="hover:bg-gray-50/50">
                    <td className="px-3 py-1.5 border border-border text-gray-900">{row.name}</td>
                    <td className="px-3 py-1.5 border border-border text-center font-mono text-indigo-600">{row.id}</td>
                    <td className="px-3 py-1.5 border border-border text-center">{row.s}</td>
                    <td className="px-3 py-1.5 border border-border text-center">{row.st}</td>
                    <td className="px-3 py-1.5 border border-border text-center">{row.pr}</td>
                    <td className="px-3 py-1.5 border border-border text-gray-600">{row.billing}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            {/* Usage metering */}
            <h3 className="text-sm font-semibold text-gray-700 mb-3">Usage-based ресурсы (metering)</h3>
            <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">Ресурс</th>
                  <th className="text-center 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">Лимит (Стандартная)</th>
                  <th className="text-center px-3 py-2 font-medium text-muted border border-border">Сверх лимита</th>
                </tr>
              </thead>
              <tbody>
                {[
                  { res: 'Сообщения (исходящие)', unit: 'сообщений/мес', limit: '5,000', over: '+0.5 ₽/сообщение' },
                  { res: 'WhatsApp шаблоны (HSM)', unit: 'conversation/мес', limit: '1,000', over: 'Meta pricing' },
                  { res: 'Медиа-файлы', unit: 'ГБ/мес', limit: '1', over: '+50 ₽/ГБ' },
                  { res: 'Чат-бот диалоги', unit: 'диалогов/мес', limit: '500 (Премиум)', over: '+1 ₽/диалог' },
                ].map((row) => (
                  <tr key={row.res} className="hover:bg-gray-50/50">
                    <td className="px-3 py-1.5 border border-border text-gray-900">{row.res}</td>
                    <td className="px-3 py-1.5 border border-border text-center text-gray-600">{row.unit}</td>
                    <td className="px-3 py-1.5 border border-border text-center text-gray-600">{row.limit}</td>
                    <td className="px-3 py-1.5 border border-border text-center text-gray-600">{row.over}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            {/* Limitations v1 */}
            <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" />
                Ограничения v1 (первая реализация)
              </h3>
              <ul className="space-y-1">
                {[
                  'Без SMS-рассылок (отдельный модуль, не входит в ТЗ)',
                  'Без Viber (малый охват в РФ, добавить в v2 при необходимости)',
                  'Чат-бот: только rule-based (без AI/NLP в v1)',
                  'Без групповых чатов (только 1-к-1: клуб ↔ клиент)',
                  'Без видео/голосовых сообщений (только текст, фото, документы)',
                  'Без drag-and-drop конструктора сценариев (будет в v2)',
                  'Мобильное приложение: чтение диалогов (отправка — только с веб-панели в v1)',
                ].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>

            {/* Conclusions */}
            <div className="bg-indigo-50 rounded-xl p-5 border border-indigo-100">
              <h3 className="text-sm font-semibold text-indigo-800 mb-2">Выводы и рекомендации</h3>
              <ul className="space-y-1.5">
                {[
                  'Мессенджеры — критический GAP в MyFitCRM по сравнению с 1С:Фитнес клуб (0 vs 5 каналов)',
                  'Приоритет реализации: WhatsApp (самый востребованный) → Telegram → VK → MAX',
                  'Архитектура Provider Strategy позволяет добавлять новые каналы без изменения ядра',
                  'Ядро мессенджер-модуля переиспользует паттерны из Email-модуля (BullMQ, шаблоны, трекинг)',
                  'Multi-tenancy: credentials каналов хранятся per-club в зашифрованном виде (ChannelConfig)',
                  'Модульное лицензирование: мессенджеры = отдельный модуль @RequireModule("messaging")',
                  'Оценка трудоёмкости: 12-16 недель (3 фазы), может быть параллелизована с другими задачами',
                  'Данный документ — ТЗ для оценки, без постановки в план разработки',
                ].map((item, i) => (
                  <li key={i} className="flex items-start gap-1.5 text-xs text-indigo-800">
                    <CheckCircle2 className="h-3 w-3 text-indigo-600 shrink-0 mt-0.5" />
                    {item}
                  </li>
                ))}
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
