import os
import re
import json
import asyncio
import logging
from telethon import TelegramClient, events
from dotenv import load_dotenv

# Настройка логирования
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[
        logging.FileHandler("data/bot.log", encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logging.getLogger('telethon').setLevel(logging.WARNING)
logging.getLogger('urllib3').setLevel(logging.WARNING)
logger = logging.getLogger('MonitorBot')

# Загрузка конфигурации
load_dotenv()
api_id = int(os.getenv('API_ID', 0))
api_hash = os.getenv('API_HASH', '')
bot_token = os.getenv('BOT_TOKEN', '')
channels_to_watch = [ch.strip() for ch in os.getenv('CHANNELS', '').split(',') if ch.strip()]
USERS_FILE = os.getenv('USERS_FILE', 'data/users.json')
SESSION_FILE = os.getenv('SESSION_FILE', 'data/bot_session')

# Валидация
if not api_id or not api_hash or not bot_token or not channels_to_watch:
    logger.critical("Не заданы обязательные переменные окружения: API_ID, API_HASH, BOT_TOKEN или CHANNELS")
    exit(1)

# Создаем необходимые директории и файлы
os.makedirs(os.path.dirname(USERS_FILE), exist_ok=True)
if not os.path.exists(USERS_FILE):
    with open(USERS_FILE, 'w', encoding='utf-8') as f:
        json.dump([], f)
    logger.debug(f"Создан файл пользователей: {USERS_FILE}")
os.makedirs(os.path.dirname(SESSION_FILE), exist_ok=True)

# Паттерн для слов 'билет' или 'экскурсия'
pattern = re.compile(r"\b(?:билет(?:ы|ов|у|ом|ах)?|экскурси(?:я|и|ю|ей)?)\b", re.IGNORECASE)

# Работа с подписчиками
def load_users():
    with open(USERS_FILE, 'r', encoding='utf-8') as f:
        users = json.load(f)
    logger.debug(f"Загружено {len(users)} пользователей")
    return users

def save_users(users):
    with open(USERS_FILE, 'w', encoding='utf-8') as f:
        json.dump(users, f, ensure_ascii=False, indent=2)
    logger.debug(f"Сохранено {len(users)} пользователей")

def add_user(user_id):
    users = load_users()
    if user_id not in users:
        users.append(user_id)
        save_users(users)
        logger.info(f"Новый подписчик: {user_id}")
    else:
        logger.debug(f"Пользователь {user_id} уже подписан")

# Основная логика бота
async def main():
    # Инициализируем клиент с сессией в data
    client = TelegramClient(SESSION_FILE, api_id, api_hash)
    # Запускаем бота по токену
    await client.start(bot_token=bot_token)
    me = await client.get_me()
    logger.info(f"Бот @{me.username} запущен")

    # Регистрация подписчиков
    @client.on(events.NewMessage(incoming=True, func=lambda e: e.is_private))
    async def register(event):
        if event.message.text and event.message.text.strip() == '/start':
            add_user(event.message.sender_id)
            await event.respond('Вы подписаны на уведомления.')

    # Мониторинг каналов
    @client.on(events.NewMessage(chats=channels_to_watch, incoming=True))
    async def monitor(event):
        text = event.message.text or ''
        chat = await event.get_chat()
        name = getattr(chat, 'username', chat.title if hasattr(chat, 'title') else str(event.chat_id))
        logger.debug(f"Сообщение в {name}: {text}")
        if pattern.search(text):
            logger.info(f"Найдено ключевое слово в {name}")
            for uid in load_users():
                try:
                    await client.send_message(uid, f"Найдено в {name}: {text[:200]}")
                    logger.debug(f"Уведомление отправлено {uid}")
                except Exception as e:
                    logger.error(f"Ошибка отправки {uid}: {e}")

    logger.info(f"Мониторинг: {channels_to_watch}")
    await client.run_until_disconnected()

if __name__ == '__main__':
    asyncio.run(main())