import os

from flask import Flask, render_template

from config import CONFIG_MAP, APP_NAME
from app.extensions import db, migrate, login_manager, csrf, limiter
from app.services import jalali
from app.services.permissions import allowed_page_keys, can_access, page_label


def create_app(config_name=None):
    app = Flask(__name__)
    config_name = config_name or os.environ.get("FLASK_CONFIG", "development")
    app.config.from_object(CONFIG_MAP[config_name])

    app.config["LOCAL_PHOTO_DIR"].mkdir(parents=True, exist_ok=True)
    (app.instance_path and os.makedirs(app.instance_path, exist_ok=True))

    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    login_manager.login_view = "auth.login"
    login_manager.login_message = None
    csrf.init_app(app)
    limiter.init_app(app)

    from app.models.user import User

    @login_manager.user_loader
    def load_user(user_id):
        return db.session.get(User, int(user_id))

    from app.blueprints.auth.routes import bp as auth_bp
    from app.blueprints.dashboard.routes import bp as dashboard_bp
    from app.blueprints.accounts.routes import bp as accounts_bp
    from app.blueprints.calls.routes import bp as calls_bp
    from app.blueprints.tag_admin.routes import bp as tag_admin_bp
    from app.blueprints.settings.routes import bp as settings_bp
    from app.blueprints.reports.routes import bp as reports_bp
    from app.blueprints.tasks.routes import bp as tasks_bp
    from app.blueprints.customer_account.routes import bp as customer_account_bp
    from app.blueprints.customer_profile.routes import bp as customer_profile_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(dashboard_bp)
    app.register_blueprint(accounts_bp)
    app.register_blueprint(calls_bp)
    app.register_blueprint(tag_admin_bp)
    app.register_blueprint(settings_bp)
    app.register_blueprint(reports_bp)
    app.register_blueprint(tasks_bp)
    app.register_blueprint(customer_account_bp)
    app.register_blueprint(customer_profile_bp)

    @app.context_processor
    def inject_globals():
        return {
            "APP_NAME": APP_NAME,
            "jalali": jalali,
            "can_access": can_access,
            "allowed_page_keys": allowed_page_keys,
            "page_label": page_label,
        }

    @app.errorhandler(403)
    def forbidden(_e):
        return render_template("errors/403.html"), 403

    @app.errorhandler(404)
    def not_found(_e):
        return render_template("errors/404.html"), 404

    return app
