import eventlet

eventlet.monkey_patch()

import logging
from flask import Flask
from flask_socketio import SocketIO

from app.di_container import Container
from app.configs import Config, LoggerConfig
from app.blueprints import (
    auth_blueprint,
    user_blueprint,
    quiz_bp,
    default_blueprint,
    history_blueprint,
    subject_blueprint,
    session_bp,
)
from app.database import init_db
from redis import Redis


def createApp() -> tuple[Flask, SocketIO]:
    app = Flask(__name__)
    app.config.from_object(Config)
    LoggerConfig.init_logger(app)

    logging.basicConfig(
        level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
    )

    container = Container()
    app.container = container

    mongo = init_db(app)
    if mongo is not None:
        container.mongo.override(mongo)

    redis_url = Config().REDIS_URL
    redis_client = Redis.from_url(redis_url)
    redis_client.ping()
    container.redis.override(redis_client)

    socketio = SocketIO(
        cors_allowed_origins="*",
        # message_queue=redis_url,
        async_mode="eventlet",
    )

    container.socketio.override(socketio)
    container.socket_controller()

    socketio.init_app(app)

    container.wire(
        modules=[
            "app.blueprints.auth",
            "app.blueprints.user",
            "app.blueprints.quiz",
            "app.blueprints.history",
            "app.blueprints.subject",
            "app.blueprints.session",
        ]
    )

    app.register_blueprint(default_blueprint)
    app.register_blueprint(auth_blueprint, url_prefix="/api")
    app.register_blueprint(user_blueprint, url_prefix="/api")
    app.register_blueprint(quiz_bp, url_prefix="/api/quiz")
    app.register_blueprint(history_blueprint, url_prefix="/api/history")
    app.register_blueprint(subject_blueprint, url_prefix="/api/subject")
    app.register_blueprint(session_bp, url_prefix="/api/session")

    return app, socketio
