"""
Telegram бот для тайного Санты - ИСПРАВЛЕННАЯ ВЕРСИЯ
Требует: pip install pyTelegramBotAPI
"""

import telebot
import json
import os
import random
from datetime import datetime

# ===== НАСТРОЙКИ =====
# Замените на ваш токен от BotFather
BOT_TOKEN = "8585166053:AAEsgD2ioOc-SmV2uCae7xNkrAblxYQyajg"

# ID владельца (вас) - просто укажите ТОЛЬКО ВАШ ID
OWNER_ID = 1132670685

DATA_FILE = "santa_data.json"

DEFAULT_DATA = {
    "groups": {},
    "distributions": {}
}

# ===== ИНИЦИАЛИЗАЦИЯ =====
bot = telebot.TeleBot(BOT_TOKEN)

# ===== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ =====

def load_data():
    """Загружает данные из JSON"""
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    return DEFAULT_DATA.copy()

def save_data(data):
    """Сохраняет данные в JSON"""
    with open(DATA_FILE, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

def is_owner(user_id):
    """Проверяет, владелец ли пользователь"""
    return user_id == OWNER_ID

def secret_santa_algorithm(participants):
    """Алгоритм распределения"""
    names = list(participants.keys())
    receivers = names.copy()
    random.shuffle(receivers)
    
    for _ in range(100):
        valid = True
        for i, giver in enumerate(names):
            if giver == receivers[i]:
                valid = False
                break
        if valid:
            break
        random.shuffle(receivers)
    
    result = {}
    for giver, receiver in zip(names, receivers):
        result[giver] = receiver
    
    return result

def get_keyboard(buttons, row_width=2):
    """Создает клавиатуру с кнопками"""
    markup = telebot.types.ReplyKeyboardMarkup(row_width=row_width, resize_keyboard=True)
    markup.add(*[telebot.types.KeyboardButton(btn) for btn in buttons])
    return markup

def show_admin_menu(chat_id):
    """Показывает админ-панель"""
    markup = get_keyboard([
        '➕ Создать группу',
        '📋 Список групп',
        '✨ Генерировать распределение',
        '📢 Отправить результаты',
        '🔙 Назад'
    ], row_width=1)
    
    bot.send_message(
        chat_id,
        "🔑 <b>Панель администратора</b>\n\nВыберите действие:",
        reply_markup=markup,
        parse_mode='html'
    )

def show_participant_menu(chat_id):
    """Показывает меню участника"""
    markup = get_keyboard([
        '✏️ Присоединиться к группе',
        '📋 Мои группы',
        '🔙 Назад'
    ], row_width=1)
    
    bot.send_message(
        chat_id,
        "👥 <b>Меню участника</b>\n\nВыберите действие:",
        reply_markup=markup,
        parse_mode='html'
    )

# ===== КОМАНДЫ =====

@bot.message_handler(commands=['start'])
def start(message):
    """Команда /start"""
    markup = get_keyboard(['👑 Администратор', '👥 Участник'], row_width=1)
    bot.send_message(
        message.chat.id,
        "🎄 Добро пожаловать в бота для тайного Санты!\n\n"
        "Выберите вашу роль:",
        reply_markup=markup
    )

@bot.message_handler(commands=['help'])
def help_cmd(message):
    """Справка"""
    help_text = """
🎄 <b>Справка по боту</b>

<b>Для администраторов:</b>
• Создайте группу
• Посмотрите список групп и участников
• Генерируйте распределение (когда все добавлены)
• Отправьте результаты

<b>Для участников:</b>
• Присоединитесь к группе (вводите свое имя и название группы)
• Получите личное сообщение с получателем подарка

<b>Важно:</b> Все должны быть в приватном чате с ботом!
"""
    bot.send_message(message.chat.id, help_text, parse_mode='html')

@bot.message_handler(commands=['mystatus'])
def my_status(message):
    """Показывает статус пользователя"""
    user_id = message.from_user.id
    username = message.from_user.username or message.from_user.first_name
    
    if is_owner(user_id):
        status = "👑 Вы владелец бота (администратор)"
    else:
        status = "👤 Обычный участник"
    
    bot.send_message(
        message.chat.id,
        f"<b>Ваш статус:</b>\n{status}\n\n"
        f"ID: {user_id}\n"
        f"Username: @{username}",
        parse_mode='html'
    )

# ===== АДМИНИСТРАТОР =====

@bot.message_handler(func=lambda m: m.text == '👑 Администратор')
def admin_role(message):
    """Выбор роли администратора"""
    if not is_owner(message.from_user.id):
        bot.send_message(message.chat.id, "❌ Только владелец бота может быть администратором.")
        return
    
    show_admin_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '➕ Создать группу')
def create_group(message):
    """Создание новой группы"""
    if not is_owner(message.from_user.id):
        return
    
    msg = bot.send_message(
        message.chat.id,
        "📝 Введите название группы (например: 'Друзья 2025'):"
    )
    bot.register_next_step_handler(msg, process_group_name)

def process_group_name(message):
    """Обработка названия группы"""
    group_name = message.text.strip()
    data = load_data()
    
    if group_name in data["groups"]:
        bot.send_message(message.chat.id, "❌ Группа с таким названием уже существует!")
        show_admin_menu(message.chat.id)
        return
    
    data["groups"][group_name] = {
        "created_by": message.from_user.id,
        "created_at": datetime.now().isoformat(),
        "participants": {},
        "distributed": False
    }
    save_data(data)
    
    bot.send_message(
        message.chat.id,
        f"✅ Группа '<b>{group_name}</b>' создана!\n\n"
        f"<b>Скажите друзьям:</b>\n"
        f"Напишите мне в приватный чат, выберите '👥 Участник',\n"
        f"затем '✏️ Присоединиться к группе',\n"
        f"введите название группы '<b>{group_name}</b>' и своё имя.",
        parse_mode='html'
    )
    show_admin_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '📋 Список групп')
def list_groups(message):
    """Список всех групп"""
    if not is_owner(message.from_user.id):
        return
    
    data = load_data()
    groups = data["groups"]
    
    if not groups:
        bot.send_message(message.chat.id, "📭 Групп еще не создано.")
        show_admin_menu(message.chat.id)
        return
    
    text = "📋 <b>Список групп:</b>\n\n"
    for i, (name, info) in enumerate(groups.items(), 1):
        count = len(info["participants"])
        status = "✅ Распределено" if info["distributed"] else "⏳ Ожидание"
        text += f"{i}. <b>{name}</b>\n   Участников: {count}\n   Статус: {status}\n"
        
        if info["participants"]:
            text += "   Участники: "
            names = list(info["participants"].keys())
            text += ", ".join(names)
            text += "\n"
        text += "\n"
    
    bot.send_message(message.chat.id, text, parse_mode='html')
    show_admin_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '✨ Генерировать распределение')
def generate_distribution(message):
    """Генерирование распределения Санты"""
    if not is_owner(message.from_user.id):
        return
    
    data = load_data()
    groups = list(data["groups"].keys())
    
    if not groups:
        bot.send_message(message.chat.id, "❌ Групп не найдено!")
        show_admin_menu(message.chat.id)
        return
    
    markup = get_keyboard(groups, row_width=1)
    msg = bot.send_message(message.chat.id, "Выберите группу:", reply_markup=markup)
    bot.register_next_step_handler(msg, lambda m: process_distribution(m, groups))

def process_distribution(message, groups):
    """Обработка генерирования распределения"""
    if message.text not in groups:
        bot.send_message(message.chat.id, "❌ Неверная группа!")
        show_admin_menu(message.chat.id)
        return
    
    group_name = message.text
    data = load_data()
    group = data["groups"][group_name]
    
    if len(group["participants"]) < 2:
        bot.send_message(
            message.chat.id,
            f"❌ В группе '<b>{group_name}</b>' должно быть минимум 2 участника!\n"
            f"Сейчас в группе: {len(group['participants'])} участников.",
            parse_mode='html'
        )
        show_admin_menu(message.chat.id)
        return
    
    # Генерируем распределение
    distribution = secret_santa_algorithm(group["participants"])
    
    # Сохраняем результат
    data["distributions"][group_name] = {
        "generated_at": datetime.now().isoformat(),
        "distribution": distribution
    }
    data["groups"][group_name]["distributed"] = True
    save_data(data)
    
    bot.send_message(
        message.chat.id,
        f"✅ <b>Распределение для группы '{group_name}' сгенерировано!</b>\n\n"
        f"Участников: {len(distribution)}\n\n"
        f"Готово к отправке результатов!",
        parse_mode='html'
    )
    show_admin_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '📢 Отправить результаты')
def send_results(message):
    """Отправка результатов участникам"""
    if not is_owner(message.from_user.id):
        return
    
    data = load_data()
    distributions = list(data["distributions"].keys())
    
    if not distributions:
        bot.send_message(message.chat.id, "❌ Нет сгенерированных распределений!")
        show_admin_menu(message.chat.id)
        return
    
    markup = get_keyboard(distributions, row_width=1)
    msg = bot.send_message(message.chat.id, "Выберите группу:", reply_markup=markup)
    bot.register_next_step_handler(msg, lambda m: send_group_results(m, distributions, data))

def send_group_results(message, distributions, data):
    """Отправка результатов группе"""
    if message.text not in distributions:
        bot.send_message(message.chat.id, "❌ Неверная группа!")
        show_admin_menu(message.chat.id)
        return
    
    group_name = message.text
    distribution = data["distributions"][group_name]["distribution"]
    sent_count = 0
    failed_count = 0
    
    for giver_name, receiver_name in distribution.items():
        # Получаем user_id дарителя из сохранённых данных
        participant_data = data["groups"][group_name]["participants"][giver_name]
        user_id = participant_data["user_id"]
        
        try:
            bot.send_message(
                user_id,
                f"🎄 <b>Тайный Санта!</b>\n\n"
                f"Вы дарите подарок: <b>{receiver_name}</b>\n\n"
                f"Группа: <b>{group_name}</b>\n\n"
                f"Сохраняйте в секрете! 🤫",
                parse_mode='html'
            )
            sent_count += 1
        except Exception as e:
            failed_count += 1
            print(f"Ошибка отправки {user_id} ({giver_name}): {e}")
    
    result_msg = (
        f"✅ <b>Результаты отправлены!</b>\n\n"
        f"Успешно отправлено: {sent_count}\n"
    )
    if failed_count > 0:
        result_msg += f"Ошибок: {failed_count}\n"
    
    bot.send_message(message.chat.id, result_msg, parse_mode='html')
    show_admin_menu(message.chat.id)

# ===== УЧАСТНИК =====

@bot.message_handler(func=lambda m: m.text == '👥 Участник')
def participant_role(message):
    """Выбор роли участника"""
    show_participant_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '✏️ Присоединиться к группе')
def join_group(message):
    """Присоединение к группе"""
    data = load_data()
    groups = list(data["groups"].keys())
    
    if not groups:
        bot.send_message(message.chat.id, "❌ Групп еще не создано. Попросите администратора создать группу.")
        show_participant_menu(message.chat.id)
        return
    
    markup = get_keyboard(groups, row_width=1)
    msg = bot.send_message(
        message.chat.id,
        "Выберите группу, к которой хотите присоединиться:",
        reply_markup=markup
    )
    bot.register_next_step_handler(msg, lambda m: select_group_to_join(m, groups, message.from_user.id))

def select_group_to_join(message, groups, user_id):
    """Выбор группы для присоединения"""
    if message.text not in groups:
        bot.send_message(message.chat.id, "❌ Неверная группа!")
        show_participant_menu(message.chat.id)
        return
    
    selected_group = message.text
    msg = bot.send_message(
        message.chat.id,
        f"📝 Введите своё имя для группы '<b>{selected_group}</b>':",
        parse_mode='html'
    )
    bot.register_next_step_handler(msg, lambda m: add_self_to_group(m, selected_group, user_id))

def add_self_to_group(message, group_name, user_id):
    """Добавление себя в группу"""
    participant_name = message.text.strip()
    data = load_data()
    
    if participant_name in data["groups"][group_name]["participants"]:
        bot.send_message(
            message.chat.id,
            f"❌ В группе '<b>{group_name}</b>' уже есть участник с именем '<b>{participant_name}</b>'.\n"
            f"Введите другое имя или прозвище.",
            parse_mode='html'
        )
        show_participant_menu(message.chat.id)
        return
    
    # ⭐ ГЛАВНОЕ: сохраняем user_id участника!
    data["groups"][group_name]["participants"][participant_name] = {
        "user_id": user_id,
        "added_at": datetime.now().isoformat()
    }
    save_data(data)
    
    bot.send_message(
        message.chat.id,
        f"✅ Отлично! Вы добавлены в группу '<b>{group_name}</b>' под именем '<b>{participant_name}</b>'.\n\n"
        f"Администратор пришлёт вам результаты, когда сгенерирует распределение.",
        parse_mode='html'
    )
    show_participant_menu(message.chat.id)

@bot.message_handler(func=lambda m: m.text == '📋 Мои группы')
def my_groups(message):
    """Показывает группы пользователя"""
    user_id = message.from_user.id
    data = load_data()
    
    user_groups = []
    for group_name, group_info in data["groups"].items():
        for participant_name, participant_info in group_info["participants"].items():
            if participant_info["user_id"] == user_id:
                user_groups.append((group_name, participant_name, group_info["distributed"]))
    
    if not user_groups:
        bot.send_message(message.chat.id, "📭 Вы еще не присоединились ни к одной группе.")
        show_participant_menu(message.chat.id)
        return
    
    text = "📋 <b>Ваши группы:</b>\n\n"
    for group_name, participant_name, distributed in user_groups:
        status = "✅ Распределено" if distributed else "⏳ Ожидание"
        text += f"• <b>{group_name}</b>\n   Ваше имя: {participant_name}\n   Статус: {status}\n\n"
    
    bot.send_message(message.chat.id, text, parse_mode='html')
    show_participant_menu(message.chat.id)

# ===== НАВИГАЦИЯ =====

@bot.message_handler(func=lambda m: m.text == '🔙 Назад')
def back(message):
    """Возврат в главное меню"""
    markup = get_keyboard(['👑 Администратор', '👥 Участник'], row_width=1)
    bot.send_message(
        message.chat.id,
        "Выберите вашу роль:",
        reply_markup=markup
    )

@bot.message_handler(commands=['about'])
def about(message):
    """Информация о боте"""
    bot.send_message(
        message.chat.id,
        "🎄 <b>Telegram бот для тайного Санты v1.2</b>\n\n"
        "✨ <b>Как работает:</b>\n"
        "1. Администратор создаёт группу\n"
        "2. Участники сами присоединяются к группе\n"
        "3. Администратор генерирует распределение\n"
        "4. Каждый получает личное сообщение с получателем\n\n"
        "/help - справка",
        parse_mode='html'
    )

@bot.message_handler(func=lambda m: True)
def unknown_message(message):
    """Обработка неизвестных сообщений"""
    bot.send_message(
        message.chat.id,
        "❓ Команда не распознана.\n\n"
        "Используйте /start для начала работы или /help для справки."
    )

# ===== ЗАПУСК БОТА =====

if __name__ == '__main__':
    print("🤖 Бот запущен! (Нажмите Ctrl+C для остановки)")
    try:
        bot.infinity_polling()
    except KeyboardInterrupt:
        print("⛔ Бот остановлен.")