from __future__ import annotations

from pathlib import Path
from typing import Any

from flask import Flask, jsonify, send_from_directory
from flask_cors import CORS
from werkzeug.middleware.proxy_fix import ProxyFix

from .routes import access_requests, account, admin_access, ai, auth_config, health, lab, monero


def create_app() -> Flask:
    """Build the Flask app with API routes and SPA fallback handling.

    WHY: the portal needs a single assembly point so the API, auth routes, and
    frontend fallback all stay wired the same way in Flask, tests, and Jenkins.
    """

    app = Flask(__name__, static_folder="../frontend/dist", static_url_path="")
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)
    CORS(app, resources={r"/api/*": {"origins": "*"}})

    health.register(app)
    auth_config.register(app)
    account.register(app)
    access_requests.register(app)
    admin_access.register(app)
    monero.register(app)
    lab.register(app)
    ai.register(app)

    @app.route("/", defaults={"path": ""})
    @app.route("/<path:path>")
    def serve_frontend(path: str) -> Any:
        """Serve the compiled SPA assets or return a JSON build hint."""

        dist_path = Path(app.static_folder)
        index_path = dist_path / "index.html"

        if dist_path.exists() and index_path.exists():
            target = dist_path / path
            if path and target.exists():
                return send_from_directory(app.static_folder, path)
            return send_from_directory(app.static_folder, "index.html")

        return jsonify(
            {
                "message": "Frontend not built yet. Run `npm install && npm run build` inside frontend/, then restart Flask.",
                "available_endpoints": ["/api/healthz", "/api/monero/get_info"],
            }
        )

    return app
