"""
cPanel "Setup Python App" (Passenger/WSGI) uchun webhook ilovasi.

Ishlash tartibi:
- Fonda bitta doimiy asyncio event loop ishga tushiriladi (thread ichida).
- Bot va Dispatcher shu loop ichida BIR MARTA yaratiladi (worker jarayoni
  tirik turgan davomida qayta ishlatiladi).
- Telegram POST so'rov yuborganda, Flask uni loop'ga topshiradi
  (run_coroutine_threadsafe) va darhol {"ok": true} javob qaytaradi.

Kirish nuqtasi sifatida "application" o'zgaruvchisi passenger_wsgi.py orqali
ishlatiladi.
"""
import asyncio
import logging
import threading

from flask import Flask, request, jsonify

import config
from bot_factory import create_bot_and_dispatcher

logging.basicConfig(level=logging.INFO)

app = Flask(__name__)

# --- Fon event loop ----------------------------------------------------
_loop = asyncio.new_event_loop()


def _run_loop():
    asyncio.set_event_loop(_loop)
    _loop.run_forever()


_thread = threading.Thread(target=_run_loop, daemon=True, name="aiogram-loop")
_thread.start()

# --- Bot/Dispatcher yaratiladi -------------------------------------------
# create_bot_and_dispatcher() sinxron funksiya (faqat obyektlarni quradi,
# tarmoqqa chiqmaydi — aiohttp sessiyasi birinchi API chaqiruvida, fon
# loop ichida avtomatik yaratiladi), shuning uchun uni to'g'ridan-to'g'ri
# chaqirish yetarli.
_bot, _dp = create_bot_and_dispatcher()


@app.route("/", methods=["GET"])
def health():
    return "Anon bot webhook ishlayapti.", 200


@app.route(f"/{config.WEBHOOK_PATH}", methods=["POST"])
def telegram_webhook():
    if config.WEBHOOK_SECRET_TOKEN:
        header = request.headers.get("X-Telegram-Bot-Api-Secret-Token", "")
        if header != config.WEBHOOK_SECRET_TOKEN:
            return jsonify({"ok": False, "error": "forbidden"}), 403

    data = request.get_json(force=True, silent=True)
    if not data:
        return jsonify({"ok": False, "error": "bad request"}), 400

    # Yangilanishni fon loop'iga topshiramiz va darhol javob qaytaramiz —
    # Telegram javobni tez kutadi (odatda bir necha soniya ichida).
    asyncio.run_coroutine_threadsafe(_dp.feed_raw_update(_bot, data), _loop)
    return jsonify({"ok": True}), 200


if __name__ == "__main__":
    # Faqat mahalliy sinov uchun (cPanel'da Passenger o'zi ishga tushiradi)
    app.run(host="0.0.0.0", port=8080)
