import logging
import os

from dotenv import load_dotenv
from flask import Flask
from flask.json.provider import DefaultJSONProvider
from pydantic import ValidationError

from backends.explorer.utils.launch_utils import run_create_app
from backends.utils import strtobool
from solutions.graph.models import (
    FeatureUnavailableError,
    GraphAlreadyExistsError,
    GraphDoesNotExistError,
    ModelValidationError,
    SnapshotDoesNotExistError,
)

DEFAULT_PROJECT_KEY = "TESTVGE"


def get_remote_webapp_config() -> dict:
    from dataiku import api_client

    project_key = os.getenv("PROJECT_KEY", DEFAULT_PROJECT_KEY)
    webapp_key = os.getenv("WEBAPP_KEY")

    dss_project = api_client().get_project(project_key)
    dss_webapp = dss_project.get_webapp(webapp_key)
    webapp_settings = dss_webapp.get_settings()

    return {
        "webapp_config": webapp_settings.data["config"],
        "default_project_key": project_key,
    }


def get_default_config() -> dict:
    return {
        "webapp_config": {"db_explorer_folder_path": "giSb968h"},
        "default_project_key": "VGE",
    }


def get_setup_for_dataiku_client():
    use_remote_webapp_settings = strtobool(os.getenv("USE_REMOTE_WEBAPP_SETTINGS", "False"))
    if use_remote_webapp_settings:
        config = get_remote_webapp_config()
    else:
        config = get_default_config()

    return {
        "webapp_config": config.get("webapp_config"),
        "default_project_key": config.get("default_project_key"),
    }


def setup_dataiku_client():
    from backends.explorer.utils.webapp_config import webapp_config

    dataiku_setup = get_setup_for_dataiku_client()
    webapp_config.setup(dataiku_setup["webapp_config"], dataiku_setup["default_project_key"])  # type: ignore


def create_app(testing_context: bool = False) -> Flask:
    # temp logging config before proper setup
    logging.basicConfig(level=logging.INFO)

    app = Flask(__name__)
    json_provider = DefaultJSONProvider(app)
    json_provider.compact = True
    json_provider.sort_keys = False
    app.json = json_provider
    if not testing_context:
        load_dotenv()
        setup_dataiku_client()

    run_create_app(app, testing_context)

    from backends.middlewares import (
        handle_feature_unavailable_error,
        handle_graph_already_exists_error,
        handle_graph_does_not_exist_error,
        handle_model_validation_error,
        handle_snapshot_does_not_exist_error,
        handle_unexpected_error,
        handle_validation_error,
    )

    app.register_error_handler(ValidationError, handle_validation_error)
    app.register_error_handler(GraphDoesNotExistError, handle_graph_does_not_exist_error)
    app.register_error_handler(GraphAlreadyExistsError, handle_graph_already_exists_error)
    app.register_error_handler(SnapshotDoesNotExistError, handle_snapshot_does_not_exist_error)
    app.register_error_handler(FeatureUnavailableError, handle_feature_unavailable_error)
    app.register_error_handler(ModelValidationError, handle_model_validation_error)
    app.register_error_handler(Exception, handle_unexpected_error)

    return app


if __name__ == "__main__":
    app = create_app()
    app.run(host="127.0.0.1", port=5000, debug=True)
