#!/usr/bin/env python3

import re
import sys
import time
import logging
import requests

from config import VK_CONFIG, URL_VK_POST, URL_VK_GET, PARAMS_VK_GET


class VKClient:
    def __init__(self, content_processor):
        self.logger = logging.getLogger(__name__)
        self.content_processor = content_processor
        self.config = VK_CONFIG
        
    def get_wall_posts(self, max_retries=10, retry_delay=10):
        """Получение постов со стены VK с повторными попытками"""
        self.logger.debug("Получаем посты со стены VK")
        wall_posts = []
        params = PARAMS_VK_GET.copy()
        
        while True:
            success = False
            for attempt in range(max_retries):
                try:
                    response = requests.get(URL_VK_GET, params=params)
                    wall_data_json = response.json()
                    
                    if 'error' in wall_data_json:
                        error_code = wall_data_json['error']['error_code']
                        error_msg = wall_data_json['error']['error_msg']
                        self.logger.error(f"Ошибка VK API {error_code}: {error_msg}")
                        return wall_posts, []  # Возвращаем то что получили
                    
                    items = wall_data_json.get('response', {}).get('items', [])
                    if not items:
                        self.logger.warning("Постов на стене нет")
                        return wall_posts, []  # Завершаем цикл
                    
                    wall_posts.extend((post['text'] for post in items if 'text' in post))
                    if len(items) < 100:
                        # Получили все посты
                        success = True
                        break
                    
                    params['offset'] = str(int(params['offset']) + 100)
                    success = True
                    break
                    
                except requests.RequestException as e:
                    self.logger.warning(f"Ошибка при получении постов VK (попытка {attempt + 1}/{max_retries}): {e}")
                    if attempt < max_retries - 1:
                        self.logger.info(f"Повторная попытка через {retry_delay} секунд...")
                        time.sleep(retry_delay)
            
            if not success:
                self.logger.error(f"Все {max_retries} попыток получения постов VK неудачны")
                break
            
            # Если получили меньше 100 постов на последнем запросе, завершаем цикл
            if len(items) < 100:
                break
        
        # Извлечение заголовков из постов
        wall_titles = []
        pattern = re.compile(r'### (.*?)\t', re.MULTILINE)
        
        for message in wall_posts:
            # Ищем заголовки в формате "### Заголовок\t"
            matches = pattern.findall(message)
            wall_titles.extend(matches)
            
            # Также ищем в первой строке поста
            lines = message.strip().split('\n') if message else []
            if lines:
                first_line = lines[0].strip()
                # Убираем префиксы и табы
                first_line = re.sub(r'^[#*\s\t]+', '', first_line)
                first_line = re.sub(r'\t.*$', '', first_line)
                if first_line and first_line not in wall_titles:
                    wall_titles.append(first_line)
        
        self.logger.info(f"Найдено {len(wall_posts)} постов и {len(wall_titles)} заголовков в VK")
        self.logger.debug(f"Заголовки VK: {wall_titles[:5]}...")  # Показываем первые 5 заголовков
        return wall_posts, wall_titles
    
    def post_message(self, content, attachments=None, max_retries=10, retry_delay=10):
        """Отправка сообщения в VK с повторными попытками"""
        params_post = {
            'access_token': self.config['api_key'],
            'v': '5.199',
            'owner_id': str(self.config['owner_id'])
        }
        
        # Форматирование контента для VK
        formatted_content = self.content_processor.format_for_vk(content)
        
        data = {
            'message': formatted_content
        }
        
        if attachments:
            params_post['attachments'] = attachments
        
        for attempt in range(max_retries):
            try:
                response = requests.post(url=URL_VK_POST, params=params_post, data=data)
                response_json = response.json()
                
                if response.status_code == 200:
                    # Проверяем наличие ошибки в ответе VK API
                    if 'error' in response_json:
                        error_code = response_json['error']['error_code']
                        error_msg = response_json['error']['error_msg']
                        self.logger.error(f"Ошибка VK API {error_code}: {error_msg}")
                        if 'request_params' in response_json['error']:
                            self.logger.debug(f"Параметры запроса: {response_json['error']['request_params']}")
                        # Не повторяем попытки при ошибках валидации
                        if error_code == 100:  # Invalid parameter
                            return None
                    elif 'response' in response_json:
                        self.logger.info("Сообщение успешно опубликовано в VK")
                        self.logger.debug(f"ID поста: {response_json['response'].get('post_id', 'неизвестен')}")
                        return response
                    else:
                        self.logger.warning(f"Неожиданный формат ответа VK: {response_json}")
                else:
                    self.logger.warning(f"Ошибка при публикации в VK: {response.status_code} - {response.reason} (попытка {attempt + 1}/{max_retries})")
                    
            except requests.RequestException as err:
                self.logger.warning(f"Ошибка VK API (попытка {attempt + 1}/{max_retries}): {err}")
            
            if attempt < max_retries - 1:
                self.logger.info(f"Повторная попытка публикации через {retry_delay} секунд...")
                time.sleep(retry_delay)
        
        self.logger.error(f"Все {max_retries} попыток публикации в VK неудачны")
        return None
    
    def check_and_publish_news(self, news_list):
        """Проверка и публикация новостей в VK"""
        self.logger.info("Начинаем проверку новостей для VK")
        
        vk_posts, vk_titles = self.get_wall_posts()
        if not vk_posts:
            self.logger.warning("Постов на стене VK нет")
        
        if not news_list:
            self.logger.warning("Список новостей пуст")
            return
        
        # Фильтруем новости для публикации
        list_for_public = []
        for topic_id, topic_title in news_list:
            # Проверяем по заголовкам и по полному тексту сообщений
            title_exists = any(topic_title == title for title in vk_titles)
            text_contains = any(topic_title in vk_post for vk_post in vk_posts)
            
            if not title_exists and not text_contains:
                list_for_public.append((topic_id, topic_title))
            else:
                self.logger.debug(f"Новость '{topic_title}' уже есть в VK (title_exists={title_exists}, text_contains={text_contains})")
        
        if not list_for_public:
            self.logger.warning("Новостей для публикации в VK нет")
            return
        
        self.logger.info(f"Новости для публикации в VK: {list_for_public}")
        
        # Публикуем новости в обратном порядке, чтобы новые оказались сверху в ленте
        for topic_id, topic_title in reversed(list_for_public):
            from site_api import SiteAPI
            site_api = SiteAPI()
            text_data = site_api.get_news_content(topic_id, self.content_processor)
            
            if text_data:
                content = f"{topic_title}\t\n" + text_data + "\n"
                
                # Извлекаем ссылки для прикрепления
                links = self.content_processor.extract_links(content)
                
                # Специальная обработка для постов о скриптах
                if "Кумулятивное обновление скриптов" in topic_title:
                    # Добавляем изображение для постов о скриптах
                    self.post_message(content, "photo-99238527_457244491")
                else:
                    if links:
                        # Берем первую ссылку как прикрепление
                        self.post_message(content, links[0] if len(links) == 1 else None)
                    else:
                        self.post_message(content)
                
                time.sleep(1.0)  # Пауза между постами
            else:
                self.logger.warning(f"Не удалось получить содержимое новости {topic_id}")
    
    def is_enabled(self):
        """Проверка, включен ли VK клиент"""
        return True  # VK всегда включен в этой версии