from dotenv import load_dotenv
load_dotenv()

import fastapi
import uvicorn
import os
import hashlib
import asyncio
import logging
from datetime import datetime as dt
from contextlib import asynccontextmanager
from telegram_module import (
    configure_bot_commands,
    create_bot,
    restore_state,
    send_message,
    start_alert_checker,
    start_app_master_event_monitor,
    start_auto_trader,
    start_bot_polling,
    start_position_monitor,
    stop_alert_checker,
)
from app_master_service import app_master_service
from official_mail_service import official_mail_service
from persistence import init_db, close_db

logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO,
)
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.WARNING)

bot_app = None


@asynccontextmanager
async def lifespan(app):
    global bot_app
    # DB 초기화 + 상태 복원
    await init_db()
    await app_master_service.initialize()
    await official_mail_service.initialize()
    bot_app = create_bot()
    await bot_app.initialize()
    await configure_bot_commands(bot_app)
    await bot_app.start()
    # Restore the authorized chat before accepting commands.
    await restore_state(bot_app)
    await start_bot_polling(bot_app)
    alert_task = asyncio.create_task(start_alert_checker(bot_app))
    trade_task = asyncio.create_task(start_auto_trader(bot_app))
    monitor_task = asyncio.create_task(start_position_monitor(bot_app))
    app_event_task = asyncio.create_task(start_app_master_event_monitor(bot_app))
    yield
    background_tasks = [alert_task, trade_task, monitor_task, app_event_task]
    for task in background_tasks:
        task.cancel()
    for task in background_tasks:
        try:
            await task
        except asyncio.CancelledError:
            pass
    await stop_alert_checker()
    await bot_app.updater.stop()
    await bot_app.stop()
    await bot_app.shutdown()
    await official_mail_service.close()
    await app_master_service.close()
    await close_db()


app = fastapi.FastAPI(lifespan=lifespan)

AUTH_KEYS = os.environ.get("AUTH_KEYS", "")
auth_hashes = [hashlib.sha256(k.encode()).hexdigest() for k in AUTH_KEYS.split(",") if k]


@app.get("/")
async def root():
    return "Telegram Bot API"


@app.get("/health")
async def health():
    return {
        "status": "ok",
        "official_mail_db": official_mail_service.is_ready,
    }


@app.post("/auth/bot")
async def auth_bot(request: fastapi.Request):
    times = dt.now().strftime("%Y-%m-%d %H:%M:%S")
    body = await request.json()
    try:
        if body["auth"] in auth_hashes:
            await send_message(bot_app, body["msg"], body.get("chat_id"))
            return {"Time": times, "Result": "Success"}
        else:
            return {"Time": times, "Result": "Fail"}
    except Exception as e:
        return {"Time": times, "Result": "Error", "Detail": str(e)}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 4001)))
