# Утилиты и вспомогательные функции
import json
from datetime import datetime, timedelta
from typing import Optional, Dict
from .database import Database


class PointsValidator:
    """Валидатор для защиты от повторных начислений"""
    
    VALIDATION_FILE = 'data/points_log.json'
    
    @staticmethod
    def _load_log():
        """Загрузить лог начисленных очков"""
        try:
            with open(PointsValidator.VALIDATION_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except:
            return {}
    
    @staticmethod
    def _save_log(log: Dict):
        """Сохранить лог начисленных очков"""
        try:
            with open(PointsValidator.VALIDATION_FILE, 'w', encoding='utf-8') as f:
                json.dump(log, f, ensure_ascii=False, indent=2)
        except:
            pass
    
    @staticmethod
    def can_complete_school(user_id: int) -> bool:
        """Проверить, может ли пользователь пройти школу"""
        log = PointsValidator._load_log()
        user_id_str = str(user_id)
        
        if user_id_str not in log:
            return True
        
        user_log = log[user_id_str]
        if 'school_completed' in user_log:
            return False
        
        return True
    
    @staticmethod
    def mark_school_completed(user_id: int):
        """Отметить школу как пройденную"""
        log = PointsValidator._load_log()
        user_id_str = str(user_id)
        
        if user_id_str not in log:
            log[user_id_str] = {}
        
        log[user_id_str]['school_completed'] = datetime.now().isoformat()
        PointsValidator._save_log(log)
    
    @staticmethod
    def can_activate_butterfly_farm(user_id: int) -> bool:
        """Проверить, может ли пользователь активировать Бабочкарий"""
        log = PointsValidator._load_log()
        user_id_str = str(user_id)
        
        if user_id_str not in log:
            return True
        
        user_log = log[user_id_str]
        activations = user_log.get('butterfly_activations', [])
        
        # Проверяем, была ли активация в этом месяце
        today = datetime.now()
        current_month = today.strftime('%Y-%m')
        
        for activation_date_str in activations:
            try:
                activation_date = datetime.fromisoformat(activation_date_str)
                if activation_date.strftime('%Y-%m') == current_month:
                    return False
            except:
                pass
        
        return True
    
    @staticmethod
    def mark_butterfly_activation(user_id: int):
        """Отметить активацию Бабочкария"""
        log = PointsValidator._load_log()
        user_id_str = str(user_id)
        
        if user_id_str not in log:
            log[user_id_str] = {}
        
        if 'butterfly_activations' not in log[user_id_str]:
            log[user_id_str]['butterfly_activations'] = []
        
        log[user_id_str]['butterfly_activations'].append(datetime.now().isoformat())
        PointsValidator._save_log(log)


class TeamManager:
    """Менеджер для работы со стаями"""
    
    TEAMS_FILE = 'data/teams.json'
    
    @staticmethod
    def _load_teams():
        """Загрузить данные о стаях"""
        try:
            with open(TeamManager.TEAMS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except:
            return {}
    
    @staticmethod
    def _save_teams(teams: Dict):
        """Сохранить данные о стаях"""
        try:
            with open(TeamManager.TEAMS_FILE, 'w', encoding='utf-8') as f:
                json.dump(teams, f, ensure_ascii=False, indent=2)
        except:
            pass
    
    @staticmethod
    def get_team_name(team_id: int) -> Optional[str]:
        """Получить название стаи"""
        teams = TeamManager._load_teams()
        team_id_str = str(team_id)
        
        if team_id_str in teams:
            return teams[team_id_str].get('team_name')
        
        return None
    
    @staticmethod
    def update_team_name(team_id: int, new_name: str):
        """Обновить название стаи"""
        teams = TeamManager._load_teams()
        team_id_str = str(team_id)
        
        if team_id_str in teams:
            teams[team_id_str]['team_name'] = new_name
            TeamManager._save_teams(teams)
    
    @staticmethod
    def add_member(team_id: int, member_id: int):
        """Добавить участника в стаю"""
        teams = TeamManager._load_teams()
        team_id_str = str(team_id)
        
        if team_id_str not in teams:
            teams[team_id_str] = {
                'team_name': f'Стая {team_id}',
                'captain_id': team_id,
                'members': [],
                'created_at': datetime.now().isoformat()
            }
        
        if member_id not in teams[team_id_str]['members']:
            teams[team_id_str]['members'].append(member_id)
        
        TeamManager._save_teams(teams)
    
    @staticmethod
    def remove_member(team_id: int, member_id: int):
        """Удалить участника из стаи"""
        teams = TeamManager._load_teams()
        team_id_str = str(team_id)
        
        if team_id_str in teams:
            if member_id in teams[team_id_str]['members']:
                teams[team_id_str]['members'].remove(member_id)
        
        TeamManager._save_teams(teams)


class MessageFormatter:
    """Форматтер для сообщений"""
    
    @staticmethod
    def format_points_message(points: int, reason: str) -> str:
        """Форматировать сообщение о начислении очков"""
        emoji = "⭐" if points > 0 else "❌"
        sign = "+" if points > 0 else ""
        
        return f"{emoji} {sign}{points} очков за {reason}"
    
    @staticmethod
    def format_ranking_row(position: int, name: str, points: int) -> str:
        """Форматировать строку рейтинга"""
        medals = {1: "🥇", 2: "🥈", 3: "🥉"}
        medal = medals.get(position, f"{position}️⃣")
        
        return f"{medal} {name} — {points} ⭐"


# Функции для работы с HTML/Markdown

def escape_markdown(text: str) -> str:
    """Экранировать специальные символы Markdown"""
    special_chars = ['*', '_', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!']
    for char in special_chars:
        text = text.replace(char, f'\\{char}')
    return text
