import copy
from typing import Any

import jsonref
from openapi_pydantic import OpenAPI
from openapi_pydantic.util import PydanticSchema, construct_open_api_with_schema_class
from pydantic import BaseModel


def construct_dummy_open_api(model: type[BaseModel]) -> OpenAPI:
    return OpenAPI.model_validate(
        {
            "info": {"title": "My own API", "version": "v0.0.1"},
            "paths": {
                "/": {
                    "post": {
                        "requestBody": {
                            "content": {"application/json": {"schema": PydanticSchema(schema_class=model)}}
                        },
                        "responses": {
                            "200": {
                                "description": "pong",
                                "content": {"application/json": {"schema": PydanticSchema(schema_class=model)}},
                            }
                        },
                    }
                }
            },
        }
    )


def make_openapi_from_pydantic_model(model: type[BaseModel]) -> dict[str, Any]:
    model = copy.deepcopy(model)
    model.__name__ = model.__name__.replace(" ", "_").replace("`", "_")
    dummy_open_api_original = construct_dummy_open_api(model)
    dummy_open_api_original = construct_open_api_with_schema_class(dummy_open_api_original).model_dump_json(
        by_alias=True, exclude_none=True
    )
    dummy_open_api: dict = jsonref.loads(dummy_open_api_original, lazy_load=False)  # type: ignore
    if "components" not in dummy_open_api:
        raise ValueError("No components found in the OpenAPI object")
    if "schemas" not in dummy_open_api["components"] is None:
        raise ValueError("No components found in the OpenAPI object")
    dummy_open_api["components"]["schemas"][model.__name__].pop("title")
    return dummy_open_api["components"]["schemas"][model.__name__]
