# Standard library imports
import json
import os

# Third party imports
import flask
import flask_cors  # type: ignore[import-untyped]
import opengeode
from opengeodeweb_back import geode_functions, utils_functions
from opengeodeweb_back.geode_objects.geode_structural_model import GeodeStructuralModel
from opengeodeweb_back.geode_objects.geode_brep import GeodeBRep
from opengeodeweb_microservice.schemas import get_schemas_dict
import geode_simplex as simplex

# Local application imports
from vease_modeling_back.models import schemas

schemas_dict = get_schemas_dict(os.path.join(os.path.dirname(__file__), "schemas"))

routes = flask.Blueprint("remesh_routes", __name__)
flask_cors.CORS(routes)


@routes.route(
    schemas_dict["remesh"]["route"], methods=schemas_dict["remesh"]["methods"]
)
def brep_remesh() -> flask.Response:
    utils_functions.validate_request(flask.request, schemas_dict["remesh"])
    params = schemas.Remesh.from_dict(flask.request.get_json())

    model_object = geode_functions.load_geode_object(params.id)
    if not isinstance(model_object, GeodeBRep):
        flask.abort(
            400,
            f"Model with id {params.id} is not a valid model type BRep",
        )
    model = model_object.brep

    constraints = simplex.BRepIsotropicMetricConstraints(model)
    remesh_constraints = flask.request.get_json()
    tmp_file_path = geode_functions.upload_file_path("constraints.json")
    try:
        with open(tmp_file_path, "w") as tmp_file:
            json.dump(remesh_constraints, tmp_file)
        constraints.import_constraints(tmp_file_path)
    finally:
        if os.path.exists(tmp_file_path):
            os.remove(tmp_file_path)

    metric = constraints.build_metric()
    simplex.brep_simplex_remesh(model, metric)

    model_object.builder().set_name(params.name)

    result = utils_functions.generate_native_viewable_and_light_viewable_from_object(
        model_object
    )
    return flask.make_response(result, 200)
