from datetime import datetime

from flask import Flask, has_request_context, redirect, request, session, url_for
from flask_login import LoginManager
from flask.sessions import SecureCookieSessionInterface
from flask_wtf.csrf import CSRFProtect

from config import Config
from app.database_profiles import (
    DATABASE_PROFILES,
    PROFILE_IMPORT,
    PROFILE_PROD,
    profile_badge_class,
    profile_label,
    profile_path,
    register_database_hooks,
    session_profile_key,
)
from app.db_sqlite import register_sqlite_pragmas
from app.models import User, db
from app.wsgi_middleware import ForwardedPrefixMiddleware

login_manager = LoginManager()
csrf = CSRFProtect()


class ProxyAwareSessionInterface(SecureCookieSessionInterface):
    """Cookie de session calé sur le préfixe envoyé par le proxy (ex. /papa, /gestion)."""

    def get_cookie_path(self, app):
        if has_request_context() and request.script_root:
            return request.script_root
        return super().get_cookie_path(app)


def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)
    app.session_interface = ProxyAwareSessionInterface()

    # Préfixe public fourni par le proxy (X-Forwarded-Prefix), pas dans le code des routes.
    app.wsgi_app = ForwardedPrefixMiddleware(app.wsgi_app)

    db.init_app(app)
    register_sqlite_pragmas()
    register_database_hooks(app, db)
    login_manager.init_app(app)
    csrf.init_app(app)

    login_manager.login_view = "auth.login"
    login_manager.login_message = "Veuillez vous connecter pour accéder à cette page."
    login_manager.login_message_category = "warning"

    @login_manager.user_loader
    def load_user(user_id):
        return db.session.get(User, int(user_id))

    from app.routes.auth import bp as auth_bp
    from app.routes.main import bp as main_bp
    from app.routes.coproprietes import bp as copro_bp
    from app.routes.personnes import bp as personnes_bp
    from app.routes.lots import bp as lots_bp
    from app.routes.compteurs import bp as compteurs_bp
    from app.routes.admin import bp as admin_bp
    from app.routes.types import bp as types_bp
    from app.routes.pwa import bp as pwa_bp

    # Pas de /papa ici : l'app vit à la racine du service Gunicorn.
    app.register_blueprint(auth_bp)
    app.register_blueprint(main_bp)
    app.register_blueprint(copro_bp)
    app.register_blueprint(personnes_bp)
    app.register_blueprint(lots_bp)
    app.register_blueprint(compteurs_bp)
    app.register_blueprint(types_bp)
    app.register_blueprint(admin_bp)
    app.register_blueprint(pwa_bp)

    @app.context_processor
    def inject_globals():
        from flask import request
        from flask_login import current_user
        from app.models import Copropriete
        from app.phone import TEL_AFFICHAGE_LABELS

        copro_id = session.get("copropriete_id")
        copro = db.session.get(Copropriete, copro_id) if copro_id else None
        public_path = request.script_root or ""
        from app.constants import ROLE_LABELS

        return {
            "public_path": public_path,
            "copropriete_active": copro,
            "now_year": datetime.utcnow().year,
            "role_labels": ROLE_LABELS,
            "tel_affichage_labels": TEL_AFFICHAGE_LABELS,
            "db_profile": session_profile_key(),
            "db_profile_label": profile_label(session_profile_key()),
            "db_profile_badge_class": profile_badge_class(session_profile_key()),
            "database_profiles": DATABASE_PROFILES,
            "profile_prod": PROFILE_PROD,
            "profile_import": PROFILE_IMPORT,
            "import_db_available": profile_path(PROFILE_IMPORT).is_file(),
        }

    @app.template_filter("format_tel")
    def format_tel_filter(numero):
        from flask_login import current_user
        from app.phone import TEL_AFFICHAGE_INTERNATIONAL, format_phone

        style = TEL_AFFICHAGE_INTERNATIONAL
        if current_user.is_authenticated:
            style = current_user.tel_affichage or TEL_AFFICHAGE_INTERNATIONAL
        return format_phone(numero or "", style)

    @app.template_filter("sort_by_date")
    def sort_by_date_filter(items, attr="date_debut"):
        """Tri décroissant par date ; les valeurs nulles en dernier."""
        from datetime import date

        sentinel = date(1, 1, 1)

        def sort_key(item):
            value = getattr(item, attr, None)
            return value or sentinel

        return sorted(items, key=sort_key, reverse=True)

    @app.errorhandler(404)
    def page_not_found(_error):
        """URL inconnue sous /papa/… → racine de l'application."""
        return redirect(url_for("main.index"))

    return app
