import os
from flask import Flask, redirect, url_for, request, g, session, flash
from dotenv import load_dotenv
from .blueprints.auth.routes import auth_bp
from .blueprints.main.routes import main_bp
from .blueprints.public.routes import public_bp

# from flask import g
# from flask_login import current_user
# from .utils.tokens import ensure_fresh_appwrite_jwt

# load_dotenv()
from .utils.settings import get_settings
from .utils.session_user import SessionUser

settings = get_settings()

def create_app():
    app = Flask(__name__, template_folder="templates")
    app.config.update(
        SECRET_KEY=settings.flask_secret_key,
        APPWRITE_ENDPOINT=settings.appwrite_endpoint,
        APPWRITE_PROJECT_ID=settings.appwrite_project_id,
        APPWRITE_API_KEY=settings.appwrite_api_key,
    )

    if not app.config["APPWRITE_ENDPOINT"] or not app.config["APPWRITE_PROJECT_ID"]:
        raise RuntimeError("Missing APPWRITE_ENDPOINT or APPWRITE_PROJECT_ID")

    # Blueprints
    app.register_blueprint(auth_bp)
    app.register_blueprint(main_bp)
    app.register_blueprint(public_bp)

    @app.before_request
    def require_login():
        """Gate all routes behind a session 'user' except auth + static."""
        # Always allow static files
        if request.endpoint == "static":
            return

        # Endpoints that should be accessible without being logged in
        public_endpoints = [
            "auth.login",
            "auth.register",
            "auth.verify",
            "auth.callback",
            "auth.send_verification",
            # add any health checks or webhooks here
            "public.home",
        ]

        # Make session user easy to access in views/templates
        g.user = session.get("user")

        endpoint = (request.endpoint or "")

        # Let any route under the auth blueprint through (login/verify/etc.)
        if endpoint.startswith("public.") or endpoint.startswith("auth."):
            return
        
        if endpoint in public_endpoints:
            return
        

        # Block everything else unless logged in
        if g.user is None:
            # preserve destination for GETs
            next_url = request.url if request.method == "GET" else url_for("auth.login")
            flash("Please log in to continue.", "warning")
            return redirect(url_for("auth.login", next=next_url))

    @app.before_request
    def load_user():
        user_data = session.get("user")
        print(user_data)

        if user_data:
            g.current_user = SessionUser(
                id=user_data.get("$id",""),
                registered_on=user_data.get("registration",""),
                email=user_data.get("email",""),
                email_verified=user_data.get("emailVerification", False),
                phone=user_data.get("phone",""),
                phone_verified=user_data.get("phoneVerification",False),
                mfa=user_data.get("mfa","")
            )
        else:
            # Anonymous user object with same interface
            class AnonymousUser:
                is_authenticated = False
                email_verification = False

            g.current_user = AnonymousUser()


    @app.context_processor
    def inject_globals():
        """Add variables available to all Jinja templates."""
        return dict(
            app_name=settings.app_name,
            app_version=settings.app_version,
            current_user=getattr(g, "current_user", None),
            )

    return app
