# -*- coding: utf-8 -*-
import time
import logging
import pytz
import datetime
from telegram.request import HTTPXRequest
from telegram.ext import (
    ApplicationBuilder,
    CommandHandler,
    CallbackQueryHandler,
    MessageHandler,
    ContextTypes,
    filters,
)

from config import TELEGRAM_BOT_TOKEN
from database import init_db, get_all_auto_channels
from handlers import start_handler, button_handler, text_handler
from api_service import fetch_gold_prices, parse_prices, generate_price_message
from keyboards import get_channel_ad_keyboard

logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)

# ردیاب ارسال‌ها بر اساس (کانال + تاریخ روز + ساعت و دقیقه)
last_sent_tracker = set()

async def auto_channel_broadcaster_job(context: ContextTypes.DEFAULT_TYPE):
    try:
        tehran_tz = pytz.timezone("Asia/Tehran")
        now_tehran = datetime.datetime.now(tehran_tz)
        
        current_date = now_tehran.strftime("%Y-%m-%d")
        current_hm = now_tehran.strftime("%H:%M")

        # پاکسازی خودکار حافظه ردیاب در انتهای شب
        if current_hm == "00:00" and len(last_sent_tracker) > 50:
            last_sent_tracker.clear()

        channels = get_all_auto_channels()
        if not channels:
            return

        # پیدا کردن کانال‌هایی که در این دقیقه نوبت ارسال دارند
        channels_due = []
        for ch in channels:
            ch_id, channel_target, times_str, status = ch
            if status != "on":
                continue

            scheduled_times = [t.strip() for t in times_str.split(",") if t.strip()]
            tracker_key = f"{channel_target}_{current_date}_{current_hm}"

            if current_hm in scheduled_times and tracker_key not in last_sent_tracker:
                channels_due.append((tracker_key, channel_target))

        if not channels_due:
            return

        # دریافت زنده قیمت‌ها از API
        api_data = await fetch_gold_prices()
        if not api_data:
            logging.error("Failed to fetch gold prices for automated channel broadcast.")
            return

        prices = parse_prices(api_data)
        message_text = generate_price_message(prices)
        channel_reply_markup = get_channel_ad_keyboard()

        # مخابره به تمام کانال‌های واجد شرایط
        for tracker_key, channel_target in channels_due:
            last_sent_tracker.add(tracker_key)
            try:
                await context.bot.send_message(
                    chat_id=channel_target,
                    text=message_text,
                    reply_markup=channel_reply_markup
                )
                logging.info(f"Price successfully sent to channel {channel_target} at {current_hm}")
            except Exception as e:
                logging.error(f"Error sending message to channel {channel_target}: {e}")

    except Exception as general_job_err:
        logging.error(f"Error in auto_channel_broadcaster_job: {general_job_err}")

def main():
    init_db()

    # افزایش زمان تایم‌اوت‌های شبکه برای پایداری در برابر قطع و وصلی اینترنت
    request_config = HTTPXRequest(
        connection_pool_size=10,
        read_timeout=35.0,
        write_timeout=35.0,
        connect_timeout=35.0
    )

    # حلقه پایدار جهت بالا آوردن مجدد ربات در صورت بروز خطاهای غیرمنتظره شبکه
    while True:
        try:
            logging.info("Initializing bot application...")
            app = (
                ApplicationBuilder()
                .token(TELEGRAM_BOT_TOKEN)
                .request(request_config)
                .build()
            )

            job_queue = app.job_queue
            if job_queue:
                job_queue.run_repeating(auto_channel_broadcaster_job, interval=30, first=10)

            app.add_handler(CommandHandler("start", start_handler))
            app.add_handler(CallbackQueryHandler(button_handler))
            app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, text_handler))

            logging.info("Bot started successfully and polling is active...")
            app.run_polling(drop_pending_updates=True)

        except Exception as e:
            logging.error(f"Bot encountered an error: {e}. Re-initializing in 10 seconds...")
            time.sleep(10)

if __name__ == "__main__":
    main()