(1. Анализ Редактированных Сообщений
Отслеживание Изменений: Автоматическое определение и отображение изменений между оригинальным и отредактированным сообщением.
Частота Редактирований: Анализ количества редактирований по пользователям и общая статистика редактирований.
Временная Динамика Редактирований: Визуализация, в какие периоды времени происходят редактирования чаще всего.
2. Анализ Пересланных Сообщений
Источник Пересылок: Определение, какие пользователи чаще всего пересылают сообщения и от кого.
Частота Пересылок: Общее количество пересланных сообщений и распределение по пользователям.
Тематика Пересланных Сообщений: Анализ содержания пересланных сообщений для выявления популярных тем или интересов.
3. Анализ Ответов и Тематических Веток
Строительство Тематических Веток: Использование поля reply_to_message_id для построения цепочек ответов и анализа диалогов.
Активные Темы: Выявление наиболее обсуждаемых тем или вопросов в чате.
Время Ответа: Измерение времени, которое пользователи тратят на ответы, и анализ средних показателей по пользователям.
4. Анализ Медиафайлов
Типы Медиафайлов: Детализация по типам медиа (фото, видео, голосовые сообщения, стикеры) и их распределение.
Размер и Длительность Медиа: Анализ размеров файлов и длительности медиа (особенно для видео и голосовых сообщений).
Популярные Медиафайлы: Определение наиболее часто используемых медиафайлов или типов медиа.
5. Обнаружение и Анализ Эмодзи
Извлечение Эмодзи: Автоматическое обнаружение и подсчет использования стандартных и пользовательских эмодзи.
Распределение Эмодзи по Категориям: Классификация эмодзи по эмоциям (радость, грусть, удивление и т.д.) и анализ их использования.
6. Облако Слов и Облако Эмодзи
Облако Слов: Генерация облака слов для наглядного отображения наиболее часто используемых слов.
Облако Эмодзи: Создание облака эмодзи для визуализации популярности различных эмодзи в чате.
7. Анализ Взаимодействий между Пользователями
Сетевой Граф Взаимодействий: Построение графа, показывающего, как пользователи взаимодействуют друг с другом (ответы, упоминания).
Индикаторы Взаимодействия: Определение самых активных в общении участников и их связи.
8. Анализ Временной Активности
Тепловая Карта Активности: Визуализация активности пользователей по часам и дням недели в виде тепловой карты.
Активность по Временным Поясам: Если есть данные о географическом расположении, анализ активности по разным временным поясам.
9. Анализ Ссылок и Веб-Активности
Категоризация Ссылок: Классификация ссылок по типам (новости, социальные сети, видео) и анализ их распространения.
Популярные Домены: Определение наиболее часто упоминаемых доменов или сайтов.
10. Анализ Частоты и Длины Сообщений
Распределение Длины Сообщений: Анализ распределения длин сообщений по пользователям и в целом.
Тренды в Частоте Сообщений: Определение периодов с наибольшей и наименьшей активностью.
11. Облачное Визуальное Представление Пользователей
Облако Пользователей: Создание облака имен пользователей, где размер шрифта отражает их активность или уровень участия.
12. Интеграция с Визуальными Инструментами
Графики и Диаграммы с Использованием Plotly или D3.js: Создание более интерактивных и динамичных визуализаций.
Карты Географического Распределения: Если доступны данные о местоположении, отображение активности пользователей на карте.
13. Интеграция Машинного Обучения
Классификация Сообщений: Автоматическое определение типа сообщений (вопросы, утверждения, команды) с использованием моделей классификации.
Предсказание Активности: Модели, предсказывающие будущую активность пользователей на основе исторических данных.
14. Предиктивный Анализ 
Предсказание Активности Пользователей: На основе исторических данных прогнозирование количества сообщений или активности конкретных пользователей в будущем.
Выявление Аномалий: Обнаружение необычной активности, такой как резкий рост или падение числа сообщений.
15. Анализ Времени Отклика по Пользователям
Усовершенствование существующего анализа времени отклика, предоставляя более детализированные метрики:
Медиана Времени Отклика: Вместе с средним временем, предоставьте медиану и другие статистические показатели.
Распределение Времени Отклика: Построение гистограмм или плотности распределения времени отклика по пользователям.
16. Автоматическое Генерирование Резюме Чата
Создание краткого обзора обсуждений:
Сбор Ключевых Тем и Выводов: Используя тематическое моделирование, генерируйте резюме основных тем и выводов из чата.
Отчет о Настроении: Включите общий анализ настроений участников чата.
17. Интеграция с Пользовательским Интерфейсом
Создание интерактивного веб-интерфейса для просмотра и взаимодействия с отчетом:
Фильтрация и Сортировка: Позволяет пользователям фильтровать сообщения по пользователям, дате, типу медиа и другим параметрам.
Поиск по Сообщениям: Интерактивный поиск по содержимому сообщений.
Динамические Обновления: Использование AJAX или WebSocket для обновления данных в реальном времени.
18. Анализ Распределения Активности по Времени и Дням Недели
Углубленный анализ активности пользователей:
Глубокая Временная Анализ: Исследование активности на уровне минут или секунд, если данные позволяют.
Сезонные Тренды: Анализ активности в разные периоды (дни недели, месяцы) для выявления регулярных паттернов.)
[Пример json:  {
   "id": 877303,
   "type": "message",
   "date": "2024-09-23T11:25:07",
   "date_unixtime": "1727079907",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "2006",
   "text_entities": [
    {
     "type": "plain",
     "text": "2006"
    }
   ]
  },
  {
   "id": 877304,
   "type": "message",
   "date": "2024-09-23T11:25:19",
   "date_unixtime": "1727079919",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "file": "(File not included. Change data exporting settings to download.)",
   "thumbnail": "(File not included. Change data exporting settings to download.)",
   "media_type": "video_message",
   "mime_type": "video/mp4",
   "duration_seconds": 2,
   "width": 384,
   "height": 384,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877305,
   "type": "message",
   "date": "2024-09-23T11:25:23",
   "date_unixtime": "1727079923",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Откуда знаешь?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Откуда знаешь?"
    }
   ]
  },
  {
   "id": 877306,
   "type": "message",
   "date": "2024-09-23T11:25:43",
   "date_unixtime": "1727079943",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Я волшебник",
   "text_entities": [
    {
     "type": "plain",
     "text": "Я волшебник"
    }
   ]
  },
  {
   "id": 877307,
   "type": "message",
   "date": "2024-09-23T11:25:52",
   "date_unixtime": "1727079952",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Могу даже тебе в лс в тг написать спорим ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Могу даже тебе в лс в тг написать спорим ?"
    }
   ]
  },
  {
   "id": 877308,
   "type": "message",
   "date": "2024-09-23T11:26:02",
   "date_unixtime": "1727079962",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Напиши ей))))",
   "text_entities": [
    {
     "type": "plain",
     "text": "Напиши ей))))"
    }
   ]
  },
  {
   "id": 877310,
   "type": "message",
   "date": "2024-09-23T11:26:20",
   "date_unixtime": "1727079980",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Пусть с катушек слетит",
   "text_entities": [
    {
     "type": "plain",
     "text": "Пусть с катушек слетит"
    }
   ]
  },
  {
   "id": 877311,
   "type": "message",
   "date": "2024-09-23T11:26:27",
   "date_unixtime": "1727079987",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Да уже",
   "text_entities": [
    {
     "type": "plain",
     "text": "Да уже"
    }
   ]
  },
  {
   "id": 877321,
   "type": "message",
   "date": "2024-09-23T11:27:54",
   "date_unixtime": "1727080074",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Пхпхаха",
   "text_entities": [
    {
     "type": "plain",
     "text": "Пхпхаха"
    }
   ]
  },
  {
   "id": 877322,
   "type": "message",
   "date": "2024-09-23T11:27:58",
   "date_unixtime": "1727080078",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Ахахаххаха",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ахахаххаха"
    }
   ]
  },
  {
   "id": 877325,
   "type": "message",
   "date": "2024-09-23T11:28:10",
   "date_unixtime": "1727080090",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Она уже тут в штаны ссыт",
   "text_entities": [
    {
     "type": "plain",
     "text": "Она уже тут в штаны ссыт"
    }
   ]
  },
  {
   "id": 877327,
   "type": "message",
   "date": "2024-09-23T11:28:21",
   "date_unixtime": "1727080101",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Пхахахаха",
   "text_entities": [
    {
     "type": "plain",
     "text": "Пхахахаха"
    }
   ]
  },
  {
   "id": 877331,
   "type": "message",
   "date": "2024-09-23T11:28:57",
   "date_unixtime": "1727080137",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Ну блин а что )",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ну блин а что )"
    }
   ]
  },
  {
   "id": 877332,
   "type": "message",
   "date": "2024-09-23T11:29:32",
   "date_unixtime": "1727080172",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Она сидит и не знает как ты это все сделал",
   "text_entities": [
    {
     "type": "plain",
     "text": "Она сидит и не знает как ты это все сделал"
    }
   ]
  },
  {
   "id": 877333,
   "type": "message",
   "date": "2024-09-23T11:29:45",
   "date_unixtime": "1727080185",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "У нее в тт что-нибудь есть ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "У нее в тт что-нибудь есть ?"
    }
   ]
  },
  {
   "id": 877335,
   "type": "message",
   "date": "2024-09-23T11:29:51",
   "date_unixtime": "1727080191",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "А то у меня его нету",
   "text_entities": [
    {
     "type": "plain",
     "text": "А то у меня его нету"
    }
   ]
  },
  {
   "id": 877336,
   "type": "message",
   "date": "2024-09-23T11:29:54",
   "date_unixtime": "1727080194",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "А профиль есть",
   "text_entities": [
    {
     "type": "plain",
     "text": "А профиль есть"
    }
   ]
  },
  {
   "id": 877337,
   "type": "message",
   "date": "2024-09-23T11:29:58",
   "date_unixtime": "1727080198",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": [
    {
     "type": "custom_emoji",
     "text": "🥴",
     "document_id": "video_files/sticker (19).webm"
    },
    ""
   ],
   "text_entities": [
    {
     "type": "custom_emoji",
     "text": "🥴",
     "document_id": "video_files/sticker (19).webm"
    },
    {
     "type": "plain",
     "text": ""
    }
   ]
  },
  {
   "id": 877340,
   "type": "message",
   "date": "2024-09-23T11:30:22",
   "date_unixtime": "1727080222",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Есть",
   "text_entities": [
    {
     "type": "plain",
     "text": "Есть"
    }
   ]
  },
  {
   "id": 877341,
   "type": "message",
   "date": "2024-09-23T11:30:31",
   "date_unixtime": "1727080231",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": [
    {
     "type": "link",
     "text": "https://www.tiktok.com/@6779999238480987142"
    }
   ],
   "text_entities": [
    {
     "type": "link",
     "text": "https://www.tiktok.com/@6779999238480987142"
    }
   ]
  },
  {
   "id": 877342,
   "type": "message",
   "date": "2024-09-23T11:30:35",
   "date_unixtime": "1727080235",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Ну я его уже нашел",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ну я его уже нашел"
    }
   ]
  },
  {
   "id": 877343,
   "type": "message",
   "date": "2024-09-23T11:30:40",
   "date_unixtime": "1727080240",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "А вот посмотреть не могу",
   "text_entities": [
    {
     "type": "plain",
     "text": "А вот посмотреть не могу"
    }
   ]
  },
  {
   "id": 877344,
   "type": "message",
   "date": "2024-09-23T11:31:06",
   "date_unixtime": "1727080266",
   "from": "Миро",
   "from_id": "user1525524847",
   "photo": "(File not included. Change data exporting settings to download.)",
   "width": 576,
   "height": 1280,
   "text": "А реально есть",
   "text_entities": [
    {
     "type": "plain",
     "text": "А реально есть"
    }
   ]
  },
  {
   "id": 877345,
   "type": "message",
   "date": "2024-09-23T11:31:16",
   "date_unixtime": "1727080276",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Испугал девочку ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Испугал девочку ?"
    }
   ]
  },
  {
   "id": 877346,
   "type": "message",
   "date": "2024-09-23T11:31:27",
   "date_unixtime": "1727080287",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Да)",
   "text_entities": [
    {
     "type": "plain",
     "text": "Да)"
    }
   ]
  },
  {
   "id": 877347,
   "type": "message",
   "date": "2024-09-23T11:31:43",
   "date_unixtime": "1727080303",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "У меня ее еще инста есть и номер",
   "text_entities": [
    {
     "type": "plain",
     "text": "У меня ее еще инста есть и номер"
    }
   ]
  },
  {
   "id": 877348,
   "type": "message",
   "date": "2024-09-23T11:31:58",
   "date_unixtime": "1727080318",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "))))",
   "text_entities": [
    {
     "type": "plain",
     "text": "))))"
    }
   ]
  },
  {
   "id": 877349,
   "type": "message",
   "date": "2024-09-23T11:32:03",
   "date_unixtime": "1727080323",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Набери ей на номер",
   "text_entities": [
    {
     "type": "plain",
     "text": "Набери ей на номер"
    }
   ]
  },
  {
   "id": 877352,
   "type": "message",
   "date": "2024-09-23T11:32:12",
   "date_unixtime": "1727080332",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Это будет смешно",
   "text_entities": [
    {
     "type": "plain",
     "text": "Это будет смешно"
    }
   ]
  },
  {
   "id": 877353,
   "type": "message",
   "date": "2024-09-23T11:32:26",
   "date_unixtime": "1727080346",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Ща из ванны вылезу",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ща из ванны вылезу"
    }
   ]
  },
  {
   "id": 877354,
   "type": "message",
   "date": "2024-09-23T11:32:32",
   "date_unixtime": "1727080352",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Да бля",
   "text_entities": [
    {
     "type": "plain",
     "text": "Да бля"
    }
   ]
  },
  {
   "id": 877355,
   "type": "message",
   "date": "2024-09-23T11:32:35",
   "date_unixtime": "1727080355",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Долго",
   "text_entities": [
    {
     "type": "plain",
     "text": "Долго"
    }
   ]
  },
  {
   "id": 877356,
   "type": "message",
   "date": "2024-09-23T11:32:43",
   "date_unixtime": "1727080363",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Да бля ее пробивал",
   "text_entities": [
    {
     "type": "plain",
     "text": "Да бля ее пробивал"
    }
   ]
  },
  {
   "id": 877357,
   "type": "message",
   "date": "2024-09-23T11:32:51",
   "date_unixtime": "1727080371",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "+нашел ее сообщения в группах",
   "text_entities": [
    {
     "type": "plain",
     "text": "+нашел ее сообщения в группах"
    }
   ]
  },
  {
   "id": 877358,
   "type": "message",
   "date": "2024-09-23T11:32:59",
   "date_unixtime": "1727080379",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Могу еще и историю вк чекнуть",
   "text_entities": [
    {
     "type": "plain",
     "text": "Могу еще и историю вк чекнуть"
    }
   ]
  },
  {
   "id": 877359,
   "type": "message",
   "date": "2024-09-23T11:33:07",
   "date_unixtime": "1727080387",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Как хочешь)",
   "text_entities": [
    {
     "type": "plain",
     "text": "Как хочешь)"
    }
   ]
  },
  {
   "id": 877360,
   "type": "message",
   "date": "2024-09-23T11:33:22",
   "date_unixtime": "1727080402",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Она там не думает уже что ты с маньяком общаешься ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Она там не думает уже что ты с маньяком общаешься ?"
    }
   ]
  },
  {
   "id": 877361,
   "type": "message",
   "date": "2024-09-23T11:33:29",
   "date_unixtime": "1727080409",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Пхахахаха не-а",
   "text_entities": [
    {
     "type": "plain",
     "text": "Пхахахаха не-а"
    }
   ]
  },
  {
   "id": 877376,
   "type": "message",
   "date": "2024-09-23T11:33:36",
   "date_unixtime": "1727080416",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Просто боится",
   "text_entities": [
    {
     "type": "plain",
     "text": "Просто боится"
    }
   ]
  },
  {
   "id": 877377,
   "type": "message",
   "date": "2024-09-23T11:33:38",
   "date_unixtime": "1727080418",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Пхахахахах",
   "text_entities": [
    {
     "type": "plain",
     "text": "Пхахахахах"
    }
   ]
  },
  {
   "id": 877378,
   "type": "message",
   "date": "2024-09-23T11:34:11",
   "date_unixtime": "1727080451",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Она пол меняла ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Она пол меняла ?"
    }
   ]
  },
  {
   "id": 877379,
   "type": "message",
   "date": "2024-09-23T11:34:32",
   "date_unixtime": "1727080472",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Не знаю",
   "text_entities": [
    {
     "type": "plain",
     "text": "Не знаю"
    }
   ]
  },
  {
   "id": 877380,
   "type": "message",
   "date": "2024-09-23T11:34:35",
   "date_unixtime": "1727080475",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Нет",
   "text_entities": [
    {
     "type": "plain",
     "text": "Нет"
    }
   ]
  },
  {
   "id": 877381,
   "type": "message",
   "date": "2024-09-23T11:34:57",
   "date_unixtime": "1727080497",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "У нее вк было имя ДАНИЛ ДАНИИЛ Добромиров",
   "text_entities": [
    {
     "type": "plain",
     "text": "У нее вк было имя ДАНИЛ ДАНИИЛ Добромиров"
    }
   ]
  },
  {
   "id": 877382,
   "type": "message",
   "date": "2024-09-23T11:35:14",
   "date_unixtime": "1727080514",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Потом Мальчик Вредный",
   "text_entities": [
    {
     "type": "plain",
     "text": "Потом Мальчик Вредный"
    }
   ]
  },
  {
   "id": 877383,
   "type": "message",
   "date": "2024-09-23T11:35:15",
   "date_unixtime": "1727080515",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Ну может угарала",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ну может угарала"
    }
   ]
  },
  {
   "id": 877384,
   "type": "message",
   "date": "2024-09-23T11:36:08",
   "date_unixtime": "1727080568",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Ну когда там уже звонить будешь?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ну когда там уже звонить будешь?"
    }
   ]
  },
  {
   "id": 877385,
   "type": "message",
   "date": "2024-09-23T11:36:09",
   "date_unixtime": "1727080569",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Верхняя пышма",
   "text_entities": [
    {
     "type": "plain",
     "text": "Верхняя пышма"
    }
   ]
  },
  {
   "id": 877386,
   "type": "message",
   "date": "2024-09-23T11:36:13",
   "date_unixtime": "1727080573",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Это где ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Это где ?"
    }
   ]
  },
  {
   "id": 877387,
   "type": "message",
   "date": "2024-09-23T11:36:28",
   "date_unixtime": "1727080588",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Практически вплотную с екб",
   "text_entities": [
    {
     "type": "plain",
     "text": "Практически вплотную с екб"
    }
   ]
  },
  {
   "id": 877388,
   "type": "message",
   "date": "2024-09-23T11:36:50",
   "date_unixtime": "1727080610",
   "from": "Миро",
   "from_id": "user1525524847",
   "forwarded_from": "Дарья",
   "text": "Ща Дима кринжатины навалит, 100%",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ща Дима кринжатины навалит, 100%"
    }
   ]
  },
  {
   "id": 877389,
   "type": "message",
   "date": "2024-09-23T11:37:42",
   "date_unixtime": "1727080662",
   "from": "Миро",
   "from_id": "user1525524847",
   "forwarded_from": "Дарья",
   "file": "(File not included. Change data exporting settings to download.)",
   "thumbnail": "(File not included. Change data exporting settings to download.)",
   "media_type": "video_file",
   "mime_type": "video/mp4",
   "duration_seconds": 5,
   "width": 720,
   "height": 1280,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877390,
   "type": "message",
   "date": "2024-09-23T11:37:47",
   "date_unixtime": "1727080667",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Это у вас ?",
   "text_entities": [
    {
     "type": "plain",
     "text": "Это у вас ?"
    }
   ]
  },
  {
   "id": 877391,
   "type": "message",
   "date": "2024-09-23T11:37:51",
   "date_unixtime": "1727080671",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Да",
   "text_entities": [
    {
     "type": "plain",
     "text": "Да"
    }
   ]
  },
  {
   "id": 877402,
   "type": "message",
   "date": "2024-09-23T11:50:08",
   "date_unixtime": "1727081408",
   "from": "Миро",
   "from_id": "user1525524847",
   "file": "(File not included. Change data exporting settings to download.)",
   "media_type": "voice_message",
   "mime_type": "audio/ogg",
   "duration_seconds": 3,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877403,
   "type": "message",
   "date": "2024-09-23T11:50:15",
   "date_unixtime": "1727081415",
   "from": "Миро",
   "from_id": "user1525524847",
   "file": "(File not included. Change data exporting settings to download.)",
   "media_type": "voice_message",
   "mime_type": "audio/ogg",
   "duration_seconds": 2,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877406,
   "type": "message",
   "date": "2024-09-23T12:00:26",
   "date_unixtime": "1727082026",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Ну сейчас то уже понятно что нет, в начале ей было страшно",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ну сейчас то уже понятно что нет, в начале ей было страшно"
    }
   ]
  },
  {
   "id": 877407,
   "type": "message",
   "date": "2024-09-23T12:00:58",
   "date_unixtime": "1727082058",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Когда ты начал её инфу рассказать",
   "text_entities": [
    {
     "type": "plain",
     "text": "Когда ты начал её инфу рассказать"
    }
   ]
  },
  {
   "id": 877409,
   "type": "message",
   "date": "2024-09-23T12:01:57",
   "date_unixtime": "1727082117",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Ахпхахаа",
   "text_entities": [
    {
     "type": "plain",
     "text": "Ахпхахаа"
    }
   ]
  },
  {
   "id": 877410,
   "type": "message",
   "date": "2024-09-23T12:02:27",
   "date_unixtime": "1727082147",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "Дя",
   "text_entities": [
    {
     "type": "plain",
     "text": "Дя"
    }
   ]
  },
  {
   "id": 877475,
   "type": "message",
   "date": "2024-09-23T17:17:31",
   "date_unixtime": "1727101051",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "forwarded_from": "Девочка из пинтерест🫦",
   "file": "(File not included. Change data exporting settings to download.)",
   "thumbnail": "(File not included. Change data exporting settings to download.)",
   "media_type": "video_message",
   "mime_type": "video/mp4",
   "duration_seconds": 6,
   "width": 384,
   "height": 384,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877478,
   "type": "message",
   "date": "2024-09-23T17:47:00",
   "date_unixtime": "1727102820",
   "from": "Миро",
   "from_id": "user1525524847",
   "reply_to_message_id": 877475,
   "text": "Интересно",
   "text_entities": [
    {
     "type": "plain",
     "text": "Интересно"
    }
   ]
  },
  {
   "id": 877484,
   "type": "message",
   "date": "2024-09-23T17:49:31",
   "date_unixtime": "1727102971",
   "from": "Миро",
   "from_id": "user1525524847",
   "file": "(File not included. Change data exporting settings to download.)",
   "media_type": "voice_message",
   "mime_type": "audio/ogg",
   "duration_seconds": 3,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877490,
   "type": "message",
   "date": "2024-09-23T17:50:43",
   "date_unixtime": "1727103043",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "file": "(File not included. Change data exporting settings to download.)",
   "thumbnail": "(File not included. Change data exporting settings to download.)",
   "media_type": "video_message",
   "mime_type": "video/mp4",
   "duration_seconds": 9,
   "width": 384,
   "height": 384,
   "text": "",
   "text_entities": []
  },
  {
   "id": 877494,
   "type": "message",
   "date": "2024-09-23T17:51:10",
   "date_unixtime": "1727103070",
   "from": "Миро",
   "from_id": "user1525524847",
   "reply_to_message_id": 877490,
   "text": "Она у теюя поселилась ?)",
   "text_entities": [
    {
     "type": "plain",
     "text": "Она у теюя поселилась ?)"
    }
   ]
  },
  {
   "id": 877495,
   "type": "message",
   "date": "2024-09-23T17:51:25",
   "date_unixtime": "1727103085",
   "from": "Викуся (Екатеринбург)",
   "from_id": "user1473750116",
   "text": "Не-а)",
   "text_entities": [
    {
     "type": "plain",
     "text": "Не-а)"
    }
   ]
  },
  {
   "id": 877496,
   "type": "message",
   "date": "2024-09-23T17:51:47",
   "date_unixtime": "1727103107",
   "edited": "2024-09-23T17:53:49",
   "edited_unixtime": "1727103229",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": "А я наш чат ща буду препарировать )",
   "text_entities": [
    {
     "type": "plain",
     "text": "А я наш чат ща буду препарировать )"
    }
   ]
  },
  {
   "id": 877497,
   "type": "message",
   "date": "2024-09-23T17:51:51",
   "date_unixtime": "1727103111",
   "edited": "2024-09-23T17:53:48",
   "edited_unixtime": "1727103228",
   "from": "Миро",
   "from_id": "user1525524847",
   "text": [
    {
     "type": "custom_emoji",
     "text": "😈",
     "document_id": "video_files/sticker (16).webm"
    },
    ""
   ],
   "text_entities": [
    {
     "type": "custom_emoji",
     "text": "😈",
     "document_id": "video_files/sticker (16).webm"
    },
    {
     "type": "plain",
     "text": ""
    }
   ]
  },
  {
   "id": 877500,
   "type": "message",
   "date": "2024-09-23T17:52:06",
   "date_unixtime": "1727103126",
   "edited": "2024-09-23T17:53:45",
   "edited_unixtime": "1727103225",
   "from": "Миро",
   "from_id": "user1525524847",
   "file": "(File not included. Change data exporting settings to download.)",
   "media_type": "voice_message",
   "mime_type": "audio/ogg",
   "duration_seconds": 11,
   "text": "",
   "text_entities": []
  }
 ]
}  ]  {код для внедрение изменений: import json
import os
import string
import re
from collections import defaultdict, Counter
from datetime import datetime
from urllib.parse import urlparse
import html  # Для безопасного экранирования HTML

def load_json(file_path):
    if not os.path.exists(file_path):
        print(f"Входной файл '{file_path}' не найден.")
        return None
    try:
        with open(file_path, 'r', encoding='utf-8') as infile:
            return json.load(infile)
    except json.JSONDecodeError as e:
        print(f"Ошибка декодирования JSON: {e}")
        return None

def save_json(data, file_path):
    try:
        with open(file_path, 'w', encoding='utf-8') as outfile:
            json.dump(data, outfile, ensure_ascii=False, indent=2)
            print(f"Данные успешно сохранены в '{file_path}'.")
    except Exception as e:
        print(f"Ошибка при сохранении файла: {e}")

def save_html(content, file_path):
    try:
        with open(file_path, 'w', encoding='utf-8') as html_file:
            html_file.write(content)
            print(f"HTML отчет успешно сохранен в '{file_path}'.")
    except Exception as e:
        print(f"Ошибка при сохранении HTML файла: {e}")

def extract_text(text_content):
    if isinstance(text_content, str):
        return text_content
    elif isinstance(text_content, list):
        text_parts = []
        for item in text_content:
            if isinstance(item, str):
                text_parts.append(item)
            elif isinstance(item, dict) and 'text' in item:
                text_parts.append(item['text'])
        return ''.join(text_parts)
    elif isinstance(text_content, dict) and 'text' in text_content:
        return text_content['text']
    else:
        return ''

def tokenize_text(text):
    text = text.lower()
    text = text.translate(str.maketrans('', '', string.punctuation))
    words = text.split()
    return words

def get_time_of_day(hour):
    if 6 <= hour < 12:
        return 'Утро'
    elif 12 <= hour < 18:
        return 'День'
    elif 18 <= hour < 24:
        return 'Вечер'
    else:
        return 'Ночь'

def identify_hashtags(text):
    return re.findall(r'#\w+', text)

def identify_mentions(text):
    return re.findall(r'@\w+', text)

def identify_links(text):
    # Простое регулярное выражение для поиска ссылок
    return re.findall(r'(https?://[^\s]+)', text)

def get_link_type(url):
    parsed_url = urlparse(url)
    domain = parsed_url.netloc.lower()
    if 'youtube.com' in domain or 'youtu.be' in domain:
        return 'YouTube'
    elif 'twitter.com' in domain:
        return 'Twitter'
    elif 'facebook.com' in domain:
        return 'Facebook'
    elif 'instagram.com' in domain:
        return 'Instagram'
    else:
        return 'Другое'

def analyze_data(data):
    cleaned_messages = []
    user_message_counts = defaultdict(int)
    user_video_counts = defaultdict(int)
    user_voice_counts = defaultdict(int)
    user_sticker_counts = defaultdict(int)
    user_citation_counts = defaultdict(int)
    user_mentions_received = defaultdict(int)
    user_mentions_made = defaultdict(int)
    hashtag_counter = Counter()
    user_links_made = defaultdict(int)
    link_type_counter = Counter()
    activity_by_hour = defaultdict(int)
    activity_by_weekday = defaultdict(int)
    activity_by_time_of_day = defaultdict(int)
    word_counter = Counter()
    user_interactions = defaultdict(lambda: defaultdict(int))
    user_reply_counts = defaultdict(int)
    user_citations_made = defaultdict(int)
    user_citations_received = defaultdict(int)
    user_hashtags_made = defaultdict(int)
    user_long_messages = defaultdict(int)
    user_message_lengths = defaultdict(list)
    message_edits = defaultdict(int)
    total_edit_count = 0
    total_messages = 0
    media_files_counter = Counter()
    user_media_counts = defaultdict(int)
    response_times = defaultdict(list)

    russian_stopwords = set([
        'и', 'в', 'во', 'не', 'что', 'он', 'на', 'я', 'с', 'со',
        'как', 'а', 'то', 'все', 'она', 'так', 'его', 'но', 'да',
        'ты', 'к', 'у', 'же', 'вы', 'за', 'бы', 'по', 'только', 'ее',
        'мне', 'было', 'вот', 'от', 'меня', 'еще', 'нет', 'о', 'из',
        'ему', 'теперь', 'когда', 'даже', 'ну', 'вдруг', 'ли', 'если',
        'уже', 'или', 'ни', 'быть', 'был', 'него', 'до', 'вас', 'нибудь',
        'опять', 'уж', 'вам', 'ведь', 'там', 'потом', 'себя', 'ничего',
        'ей', 'может', 'они', 'тут', 'где', 'есть', 'надо', 'ней', 'для',
        'мы', 'тебя', 'их', 'чем', 'была', 'сам', 'чтобы', 'без', 'будто',
        'чего', 'раз', 'тоже', 'себе', 'под', 'будет', 'ж', 'тогда', 'кто',
        'этот', 'того', 'потому', 'этого', 'какой', 'совсем', 'ним', 'здесь',
        'этом', 'один', 'почти', 'мой', 'тем', 'чтобы', 'нее', 'кажется', 'сюда',
        'туда', 'этой'
    ])

    users = set()

    # Предварительная обработка сообщений по id для быстрого поиска
    messages_by_id = {msg['id']: msg for msg in data.get('messages', [])}

    for message in data.get('messages', []):
        total_messages += 1
        user = message.get('from', 'Неизвестный пользователь')
        if user != 'Неизвестный пользователь':
            users.add(user)
            user_message_counts[user] += 1

        # Обработка медиафайлов
        media_type = message.get('media_type')
        if media_type:
            # Перевод типов медиафайлов на русский
            media_type_translations = {
                'voice_message': 'Голосовое сообщение',
                'video_message': 'Видеосообщение',
                'sticker': 'Стикер',
                'video_file': 'Видеофайл',
                'audio_file': 'Аудиофайл'
            }
            translated_media_type = media_type_translations.get(media_type, media_type)
            media_files_counter[translated_media_type] += 1
            user_media_counts[user] += 1

            if media_type in ['video_file', 'video_message']:
                user_video_counts[user] += 1
            elif media_type == 'voice_message':
                user_voice_counts[user] += 1
            elif media_type == 'sticker':
                user_sticker_counts[user] += 1

        cleaned_message = {
            'id': message.get('id'),
            'date': message.get('date'),
            'from': user,
            'text': ''
        }

        text_content = message.get('text', '')
        cleaned_text = extract_text(text_content)
        cleaned_message['text'] = cleaned_text
        cleaned_messages.append(cleaned_message)

        message_length = len(cleaned_text)
        user_message_lengths[user].append(message_length)

        if message_length > 140:
            user_long_messages[user] += 1

        # Анализ редактирования сообщений
        if 'edited' in message and message['edited']:
            message_edits[user] += 1
            total_edit_count += 1

        # Обработка цитат
        if 'reply_to_message_id' in message:
            user_citation_counts[user] += 1
            user_citations_made[user] += 1
            reply_message = messages_by_id.get(message['reply_to_message_id'])
            if reply_message:
                reply_user = reply_message.get('from', 'Неизвестный пользователь')
                if reply_user != 'Неизвестный пользователь':
                    user_citations_received[reply_user] += 1

        # Обработка упоминаний
        mentions = identify_mentions(cleaned_text)
        if mentions:
            user_mentions_made[user] += len(mentions)
            for mention in mentions:
                mentioned_user = mention[1:]  # Удаляем '@'
                user_mentions_received[mentioned_user] += 1

        # Обработка хештегов
        hashtags = identify_hashtags(cleaned_text)
        if hashtags:
            user_hashtags_made[user] += len(hashtags)
            hashtag_counter.update([tag.lower() for tag in hashtags])

        # Обработка ссылок
        links = identify_links(cleaned_text)
        if links:
            user_links_made[user] += len(links)
            for link in links:
                link_type = get_link_type(link)
                link_type_counter[link_type] += 1

        # Анализ времени отправки
        message_date = message.get('date')
        if message_date:
            try:
                dt = datetime.fromisoformat(message_date)
                hour = dt.hour
                weekday = dt.weekday()  # Monday = 0
                time_of_day = get_time_of_day(hour)
                activity_by_hour[hour] += 1
                activity_by_weekday[weekday] += 1
                activity_by_time_of_day[time_of_day] += 1
            except ValueError:
                pass

        # Токенизация и подсчет слов
        words = tokenize_text(cleaned_text)
        words = [word for word in words if word not in russian_stopwords]
        word_counter.update(words)

        # Анализ взаимодействий между пользователями
        if 'reply_to_message_id' in message:
            reply_message_id = message['reply_to_message_id']
            reply_message = messages_by_id.get(reply_message_id)
            if reply_message:
                reply_user = reply_message.get('from', 'Неизвестный пользователь')
                if reply_user != 'Неизвестный пользователь':
                    user_interactions[user][reply_user] += 1
                    user_reply_counts[user] += 1

    # Анализ времени отклика
    if len(users) >= 2:
        user_last_message_time = defaultdict(lambda: None)
        for message in data.get('messages', []):
            user = message.get('from', 'Неизвестный пользователь')
            if user == 'Неизвестный пользователь':
                continue
            current_date = message.get('date')
            if not current_date:
                continue
            try:
                current_dt = datetime.fromisoformat(current_date)
            except ValueError:
                continue

            # Проверяем дату последнего сообщения от других пользователей
            for other_user in users:
                if other_user == user:
                    continue
                last_time = user_last_message_time[other_user]
                if last_time:
                    response_time = (current_dt - last_time).total_seconds()
                    if response_time > 0:
                        response_times[user].append(response_time)

            # Обновляем время последнего сообщения для текущего пользователя
            user_last_message_time[user] = current_dt

    # Преобразование Counter и defaultdict в обычные словари для сериализации
    analysis_results = {
        'cleaned_messages': cleaned_messages,
        'user_message_counts': dict(user_message_counts),
        'user_video_counts': dict(user_video_counts),
        'user_voice_counts': dict(user_voice_counts),
        'user_sticker_counts': dict(user_sticker_counts),
        'user_citation_counts': dict(user_citation_counts),
        'user_mentions_received': dict(user_mentions_received),
        'user_mentions_made': dict(user_mentions_made),
        'user_hashtag_counts': dict(hashtag_counter),
        'user_hashtags_made': dict(user_hashtags_made),
        'user_links_made': dict(user_links_made),
        'link_type_counts': dict(link_type_counter),
        'activity_by_hour': dict(sorted(activity_by_hour.items())),
        'activity_by_weekday': dict(sorted(activity_by_weekday.items())),
        'activity_by_time_of_day': dict(sorted(activity_by_time_of_day.items())),
        'word_counter': dict(word_counter),
        'user_interactions': {user: dict(targets) for user, targets in user_interactions.items()},
        'user_reply_counts': dict(user_reply_counts),
        'user_citations_made': dict(user_citations_made),
        'user_citations_received': dict(user_citations_received),
        'user_hashtags_made': dict(user_hashtags_made),
        'user_links_made': dict(user_links_made),
        'user_long_messages': dict(user_long_messages),
        'user_message_lengths': {user: lengths for user, lengths in user_message_lengths.items()},
        'message_edits': dict(message_edits),
        'total_edit_count': total_edit_count,
        'total_messages': total_messages,
        'media_files_counter': dict(media_files_counter),
        'user_media_counts': dict(user_media_counts),
        'response_times': {user: times for user, times in response_times.items()}
    }

    return analysis_results

def generate_html(data):
    total_messages = data['total_messages']
    total_edit_count = data['total_edit_count']
    total_links = sum(data['user_links_made'].values())
    total_mentions = sum(data['user_mentions_made'].values())
    total_quotes = sum(data['user_citation_counts'].values())

    edit_percentage = (total_edit_count / total_messages) * 100 if total_messages > 0 else 0

    user_average_lengths = {
        user: round(sum(lengths) / len(lengths), 2) if lengths else 0
        for user, lengths in data['user_message_lengths'].items()
    }

    # Исправление: сортируем словарь по значению и выбираем топ-50
    most_common_words = sorted(data['word_counter'].items(), key=lambda x: x[1], reverse=True)[:50]

    # Для дней недели
    weekdays_num = sorted(map(int, data['activity_by_weekday'].keys()), key=int)
    messages_per_weekday = [data['activity_by_weekday'].get(wd, 0) for wd in weekdays_num]
    weekday_labels = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']
    weekdays_labels = [weekday_labels[wd] for wd in weekdays_num if 0 <= wd < 7]

    # Для времени суток
    time_of_day_labels = list(data['activity_by_time_of_day'].keys())
    messages_time_of_day = list(data['activity_by_time_of_day'].values())

    # Проверка наличия данных для различных анализов
    has_media_files = any(data['media_files_counter'].values())
    word_freq_present = len(most_common_words) > 0
    user_interactions_present = any(len(v) > 0 for v in data['user_interactions'].values())
    response_times_present = any(len(v) > 0 for v in data['response_times'].values())

    html_content = f"""
    <!DOCTYPE html>
    <html lang="ru">
    <head>
        <meta charset="UTF-8">
        <title>Статистика Чата</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
        <style>
            body {{
                font-family: Arial, sans-serif;
                margin: 20px;
            }}
            table {{
                width: 100%;
                border-collapse: collapse;
                margin-bottom: 40px;
            }}
            th, td {{
                border: 1px solid #ddd;
                padding: 8px;
                text-align: left;
            }}
            th {{
                background-color: #f2f2f2;
            }}
            h2 {{
                color: #333;
            }}
            .chart-container {{
                width: 100%;
                height: 400px;
                margin-bottom: 40px;
            }}
            .summary {{
                margin-bottom: 40px;
            }}
        </style>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
    </head>
    <body>
        <h1>Статистика Чата</h1>

        <div class="summary">
            <p><strong>Общее количество сообщений:</strong> {total_messages}</p>
            <p><strong>Общее количество редактирований:</strong> {total_edit_count}</p>
            <p><strong>Процент редактированных сообщений:</strong> {edit_percentage:.2f}%</p>
            <p><strong>Общее количество ссылок:</strong> {total_links}</p>
            <p><strong>Общее количество упоминаний:</strong> {total_mentions}</p>
            <p><strong>Общее количество цитирований:</strong> {total_quotes}</p>
        </div>

        <h2>Анализ Медиафайлов</h2>
        <table id="mediaFilesTable" class="display">
            <thead>
                <tr>
                    <th>Тип Медиафайла</th>
                    <th>Количество</th>
                </tr>
            </thead>
            <tbody>
    """

    # Таблица медиафайлов
    for media_type, count in sorted(data['media_files_counter'].items(), key=lambda x: x[1], reverse=True):
        html_content += f"""
                <tr>
                    <td>{html.escape(media_type)}</td>
                    <td>{count}</td>
                </tr>
        """
    html_content += """
            </tbody>
        </table>

        <h2>Медиастатистика на Пользователя и Другие Анализы</h2>
        <table id="combinedMediaAndLinksTable" class="display">
            <thead>
                <tr>
                    <th>Пользователь</th>
                    <th>Количество Медиафайлов</th>
                    <th>Видеосообщения</th>
                    <th>Голосовые Сообщения</th>
                    <th>Стикеры</th>
                    <th>Цитирования</th>
                    <th>Отправляет Ссылки</th>
                </tr>
            </thead>
            <tbody>
    """
    users_sorted = sorted(data['user_message_counts'].keys())

    for user in users_sorted:
        media_count = data['user_media_counts'].get(user, 0)
        video_count = data['user_video_counts'].get(user, 0)
        voice_count = data['user_voice_counts'].get(user, 0)
        sticker_count = data['user_sticker_counts'].get(user, 0)
        citation_count = data['user_citation_counts'].get(user, 0)
        links_sent = data['user_links_made'].get(user, 0)

        html_content += f"""
                <tr>
                    <td>{html.escape(user)}</td>
                    <td>{media_count}</td>
                    <td>{video_count}</td>
                    <td>{voice_count}</td>
                    <td>{sticker_count}</td>
                    <td>{citation_count}</td>
                    <td>{links_sent}</td>
                </tr>
        """
    html_content += """
            </tbody>
        </table>
    """

    # Анализ редактирования сообщений
    if total_edit_count > 0:
        html_content += f"""
        <h2>Анализ Редактирования Сообщений</h2>
        <!-- Удалены строки с общим количеством редактирований и процентом редактированных сообщений -->
        <table id="messageEditsTable" class="display">
            <thead>
                <tr>
                    <th>Пользователь</th>
                    <th>Количество Редактирований</th>
                </tr>
            </thead>
            <tbody>
        """
        for user, count in sorted(data['message_edits'].items(), key=lambda x: x[1], reverse=True):
            html_content += f"""
                    <tr>
                        <td>{html.escape(user)}</td>
                        <td>{count}</td>
                    </tr>
            """
        html_content += """
            </tbody>
        </table>
        """

    # Анализ временной активности
    html_content += """
    <h2>Активность Пользователей</h2>
    <div class="chart-container">
        <canvas id="activityByHourChart"></canvas>
    </div>
    <div class="chart-container">
        <canvas id="activityByWeekdayChart"></canvas>
    </div>
    <div class="chart-container">
        <canvas id="activityByTimeOfDayChart"></canvas>
    </div>
    """

    # Частотный анализ слов
    if word_freq_present:
        html_content += """
        <h2>Частотный Анализ Слов (Топ-50)</h2>
        <table id="wordFrequencyTable" class="display">
            <thead>
                <tr>
                    <th>Слово</th>
                    <th>Частота</th>
                </tr>
            </thead>
            <tbody>
        """
        for word, freq in most_common_words:
            html_content += f"""
                    <tr>
                        <td>{html.escape(word)}</td>
                        <td>{freq}</td>
                    </tr>
            """
        html_content += """
            </tbody>
        </table>
        """

    # Анализ взаимодействий между пользователями
    if user_interactions_present:
        interactions_data = []
        for user, interactions in data['user_interactions'].items():
            for target_user, count in interactions.items():
                interactions_data.append((user, target_user, count))

        if interactions_data:
            html_content += """
            <h2>Анализ Взаимодействий между Пользователями</h2>
            <table id="userInteractionsTable" class="display">
                <thead>
                    <tr>
                        <th>Отправитель</th>
                        <th>Получатель</th>
                        <th>Количество</th>
                    </tr>
                </thead>
                <tbody>
            """
            for sender, receiver, count in interactions_data:
                html_content += f"""
                        <tr>
                            <td>{html.escape(sender)}</td>
                            <td>{html.escape(receiver)}</td>
                            <td>{count}</td>
                        </tr>
                """
            html_content += """
                </tbody>
            </table>
            """

    # Анализ времени отклика
    if response_times_present:
        html_content += """
        <h2>Анализ Времени Отклика</h2>
        <table id="responseTimesTable" class="display">
            <thead>
                <tr>
                    <th>Пользователь</th>
                    <th>Среднее Время Отклика (секунды)</th>
                </tr>
            </thead>
            <tbody>
        """
        for user, times in data['response_times'].items():
            avg_time = round(sum(times) / len(times), 2) if times else 0
            html_content += f"""
                    <tr>
                        <td>{html.escape(user)}</td>
                        <td>{avg_time}</td>
                    </tr>
            """
        html_content += """
            </tbody>
        </table>
        """

    # Добавление графиков
    # График активности по часам
    hours = sorted(map(int, data['activity_by_hour'].keys()))
    messages_per_hour = [data['activity_by_hour'].get(hour, 0) for hour in hours]
    labels_hours = [str(hour) for hour in hours]

    # График активности по дням недели
    messages_per_weekday = [data['activity_by_weekday'].get(wd, 0) for wd in weekdays_num]
    labels_weekdays = weekdays_labels

    # График активности по времени суток
    labels_time_of_day = time_of_day_labels
    messages_time_of_day = messages_time_of_day

    html_content += f"""
    <script>
        // Данные для графика активности по часам
        const activityByHourCtx = document.getElementById('activityByHourChart').getContext('2d');
        const activityByHourChart = new Chart(activityByHourCtx, {{
            type: 'bar',
            data: {{
                labels: {json.dumps(labels_hours)},
                datasets: [{{
                    label: 'Количество Сообщений',
                    data: {json.dumps(messages_per_hour)},
                    backgroundColor: 'rgba(54, 162, 235, 0.6)',
                    borderColor: 'rgba(54, 162, 235, 1)',
                    borderWidth: 1
                }}]
            }},
            options: {{
                scales: {{
                    x: {{
                        title: {{
                            display: true,
                            text: 'Часы'
                        }}
                    }},
                    y: {{
                        beginAtZero: true,
                        title: {{
                            display: true,
                            text: 'Количество Сообщений'
                        }}
                    }}
                }}
            }}
        }});

        // Данные для графика активности по дням недели
        const activityByWeekdayCtx = document.getElementById('activityByWeekdayChart').getContext('2d');
        const activityByWeekdayChart = new Chart(activityByWeekdayCtx, {{
            type: 'bar',
            data: {{
                labels: {json.dumps(labels_weekdays)},
                datasets: [{{
                    label: 'Количество Сообщений',
                    data: {json.dumps(messages_per_weekday)},
                    backgroundColor: 'rgba(255, 99, 132, 0.6)',
                    borderColor: 'rgba(255, 99, 132, 1)',
                    borderWidth: 1
                }}]
            }},
            options: {{
                scales: {{
                    x: {{
                        title: {{
                            display: true,
                            text: 'Дни Недели'
                        }}
                    }},
                    y: {{
                        beginAtZero: true,
                        title: {{
                            display: true,
                            text: 'Количество Сообщений'
                        }}
                    }}
                }}
            }}
        }});

        // Данные для графика активности по времени суток
        const activityByTimeOfDayCtx = document.getElementById('activityByTimeOfDayChart').getContext('2d');
        const activityByTimeOfDayChart = new Chart(activityByTimeOfDayCtx, {{
            type: 'bar',
            data: {{
                labels: {json.dumps(labels_time_of_day)},
                datasets: [{{
                    label: 'Количество Сообщений',
                    data: {json.dumps(messages_time_of_day)},
                    backgroundColor: 'rgba(153, 102, 255, 0.6)',
                    borderColor: 'rgba(153, 102, 255, 1)',
                    borderWidth: 1
                }}]
            }},
            options: {{
                scales: {{
                    x: {{
                        title: {{
                            display: true,
                            text: 'Время Суток'
                        }}
                    }},
                    y: {{
                        beginAtZero: true,
                        title: {{
                            display: true,
                            text: 'Количество Сообщений'
                        }}
                    }}
                }}
            }}
        }});

        // Инициализация DataTables
        $(document).ready(function() {{
            $('#mediaFilesTable').DataTable({{
                "paging": false,
                "searching": false,
                "info": false
            }});
            $('#combinedMediaAndLinksTable').DataTable({{
                "paging": false,
                "searching": false,
                "info": false
            }});
    """

    if total_edit_count > 0:
        html_content += """
            $('#messageEditsTable').DataTable({
                "paging": false,
                "searching": false,
                "info": false
            });
        """

    if word_freq_present:
        html_content += """
            $('#wordFrequencyTable').DataTable({
                "paging": false,
                "searching": false,
                "info": false
            });
        """

    if user_interactions_present:
        html_content += """
            $('#userInteractionsTable').DataTable({
                "paging": false,
                "searching": false,
                "info": false
            });
        """

    if response_times_present:
        html_content += """
            $('#responseTimesTable').DataTable({
                "paging": false,
                "searching": false,
                "info": false
            });
        """

    html_content += """
        });
    </script>

    </body>
    </html>
    """

    return html_content

if __name__ == "__main__":
    # Рекомендуется использовать os.path.join для построения путей
    base_dir = r"C:\Users\Admin\Downloads\AyuGram Desktop\ChatExport_2024-09-23 (4)"
    input_file = os.path.join(base_dir, "result.json")
    output_json = os.path.join(base_dir, "cleaned_result.json")
    output_html = os.path.join(base_dir, "chat_statistics.html")

    data = load_json(input_file)
    if data:
        analyzed_data = analyze_data(data)
        save_json(analyzed_data['cleaned_messages'], output_json)
        html_content = generate_html(analyzed_data)
        save_html(html_content, output_html)}