# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
import urllib.parse
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.datetime_utils import serialize_datetime
from ...core.jsonable_encoder import jsonable_encoder
from ...core.remove_none_from_dict import remove_none_from_dict
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.edit_suggestion import EditSuggestion
from ...types.http_validation_error import HttpValidationError
from ...types.llama_index_core_base_llms_types_chat_message import LlamaIndexCoreBaseLlmsTypesChatMessage
from ...types.paginated_report_response import PaginatedReportResponse
from ...types.report import Report
from ...types.report_create_response import ReportCreateResponse
from ...types.report_event_item import ReportEventItem
from ...types.report_metadata import ReportMetadata
from ...types.report_plan import ReportPlan
from ...types.report_response import ReportResponse
from ...types.report_state import ReportState
from .types.update_report_plan_api_v_1_reports_report_id_plan_patch_request_action import (
    UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction,
)

try:
    import pydantic
    if pydantic.__version__.startswith("1."):
        raise ImportError
    import pydantic.v1 as pydantic  # type: ignore
except ImportError:
    import pydantic  # type: ignore

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class ReportsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create_report_api_v_1_reports_post(
        self,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        name: str,
        template_text: str,
        template_instructions: typing.Optional[str] = OMIT,
        existing_retriever_id: typing.Optional[str] = OMIT,
        files: typing.List[str],
        template_file: typing.Optional[str] = OMIT,
    ) -> ReportCreateResponse:
        """
        Create a new report.

        Parameters:
            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - name: str.

            - template_text: str.

            - template_instructions: typing.Optional[str].

            - existing_retriever_id: typing.Optional[str].

            - files: typing.List[str].

            - template_file: typing.Optional[str].
        """
        _request: typing.Dict[str, typing.Any] = {"name": name, "template_text": template_text, "files": files}
        if template_instructions is not OMIT:
            _request["template_instructions"] = template_instructions
        if existing_retriever_id is not OMIT:
            _request["existing_retriever_id"] = existing_retriever_id
        if template_file is not OMIT:
            _request["template_file"] = template_file
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v1/reports"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportCreateResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_reports(
        self,
        *,
        state: typing.Optional[ReportState] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> PaginatedReportResponse:
        """
        List all reports for a project.

        Parameters:
            - state: typing.Optional[ReportState].

            - limit: typing.Optional[int].

            - offset: typing.Optional[int].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud import ReportState
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.list_reports(
            state=ReportState.PENDING,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v1/reports/list"),
            params=remove_none_from_dict(
                {
                    "state": state,
                    "limit": limit,
                    "offset": offset,
                    "project_id": project_id,
                    "organization_id": organization_id,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PaginatedReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report(
        self,
        report_id: str,
        *,
        version: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> ReportResponse:
        """
        Get a specific report.

        Parameters:
            - report_id: str.

            - version: typing.Optional[int].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict(
                {"version": version, "project_id": project_id, "organization_id": organization_id}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report_metadata(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        name: str,
    ) -> ReportMetadata:
        """
        Update metadata for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - name: str. The name of the report
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report_metadata(
            report_id="string",
            name="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"name": name}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_report(
        self,
        report_id: str,
        *,
        cascade_delete: typing.Optional[bool] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> typing.Any:
        """
        Delete a report.

        Parameters:
            - report_id: str.

            - cascade_delete: typing.Optional[bool]. Whether to delete associated retriever and pipeline data

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.delete_report(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "DELETE",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict(
                {"cascade_delete": cascade_delete, "project_id": project_id, "organization_id": organization_id}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        content: Report,
    ) -> ReportResponse:
        """
        Update a report's content.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - content: Report. The content of the report version
        ---
        from llama_cloud import Report
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report(
            report_id="string",
            content=Report(
                id="string",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"content": content}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_plan(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> ReportPlan:
        """
        Get the plan for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_plan(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/plan"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportPlan, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_report_plan(
        self,
        report_id: str,
        *,
        action: UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request: typing.Optional[ReportPlan] = None,
    ) -> ReportResponse:
        """
        Update the plan of a report, including approval, rejection, and editing.

        Parameters:
            - report_id: str.

            - action: UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - request: typing.Optional[ReportPlan].
        ---
        from llama_cloud import (
            ReportPlan,
            UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction,
        )
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.update_report_plan(
            report_id="string",
            action=UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction.APPROVE,
            request=ReportPlan(),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/plan"),
            params=remove_none_from_dict(
                {"action": action, "project_id": project_id, "organization_id": organization_id}
            ),
            json=jsonable_encoder(request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_events(
        self,
        report_id: str,
        *,
        after: typing.Optional[dt.datetime] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> typing.List[ReportEventItem]:
        """
        Get all historical events for a report.

        Parameters:
            - report_id: str.

            - after: typing.Optional[dt.datetime].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_events(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/events"),
            params=remove_none_from_dict(
                {
                    "after": serialize_datetime(after) if after is not None else None,
                    "project_id": project_id,
                    "organization_id": organization_id,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ReportEventItem], _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_report_metadata(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> ReportMetadata:
        """
        Get metadata for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.get_report_metadata(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/metadata"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def suggest_edits_endpoint(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        user_query: str,
        chat_history: typing.List[LlamaIndexCoreBaseLlmsTypesChatMessage],
    ) -> typing.List[EditSuggestion]:
        """
        Suggest edits to a report based on user query and chat history.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - user_query: str.

            - chat_history: typing.List[LlamaIndexCoreBaseLlmsTypesChatMessage].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.suggest_edits_endpoint(
            report_id="string",
            user_query="string",
            chat_history=[],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/suggest_edits"
            ),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"user_query": user_query, "chat_history": chat_history}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[EditSuggestion], _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def restart_report(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> typing.Any:
        """
        Restart a report from scratch.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import LlamaCloud

        client = LlamaCloud(
            token="YOUR_TOKEN",
        )
        client.reports.restart_report(
            report_id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/restart"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncReportsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create_report_api_v_1_reports_post(
        self,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        name: str,
        template_text: str,
        template_instructions: typing.Optional[str] = OMIT,
        existing_retriever_id: typing.Optional[str] = OMIT,
        files: typing.List[str],
        template_file: typing.Optional[str] = OMIT,
    ) -> ReportCreateResponse:
        """
        Create a new report.

        Parameters:
            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - name: str.

            - template_text: str.

            - template_instructions: typing.Optional[str].

            - existing_retriever_id: typing.Optional[str].

            - files: typing.List[str].

            - template_file: typing.Optional[str].
        """
        _request: typing.Dict[str, typing.Any] = {"name": name, "template_text": template_text, "files": files}
        if template_instructions is not OMIT:
            _request["template_instructions"] = template_instructions
        if existing_retriever_id is not OMIT:
            _request["existing_retriever_id"] = existing_retriever_id
        if template_file is not OMIT:
            _request["template_file"] = template_file
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v1/reports"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportCreateResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_reports(
        self,
        *,
        state: typing.Optional[ReportState] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> PaginatedReportResponse:
        """
        List all reports for a project.

        Parameters:
            - state: typing.Optional[ReportState].

            - limit: typing.Optional[int].

            - offset: typing.Optional[int].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud import ReportState
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.list_reports(
            state=ReportState.PENDING,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "api/v1/reports/list"),
            params=remove_none_from_dict(
                {
                    "state": state,
                    "limit": limit,
                    "offset": offset,
                    "project_id": project_id,
                    "organization_id": organization_id,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PaginatedReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report(
        self,
        report_id: str,
        *,
        version: typing.Optional[int] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> ReportResponse:
        """
        Get a specific report.

        Parameters:
            - report_id: str.

            - version: typing.Optional[int].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.get_report(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict(
                {"version": version, "project_id": project_id, "organization_id": organization_id}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report_metadata(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        name: str,
    ) -> ReportMetadata:
        """
        Update metadata for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - name: str. The name of the report
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.update_report_metadata(
            report_id="string",
            name="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"name": name}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_report(
        self,
        report_id: str,
        *,
        cascade_delete: typing.Optional[bool] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> typing.Any:
        """
        Delete a report.

        Parameters:
            - report_id: str.

            - cascade_delete: typing.Optional[bool]. Whether to delete associated retriever and pipeline data

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.delete_report(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "DELETE",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict(
                {"cascade_delete": cascade_delete, "project_id": project_id, "organization_id": organization_id}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        content: Report,
    ) -> ReportResponse:
        """
        Update a report's content.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - content: Report. The content of the report version
        ---
        from llama_cloud import Report
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.update_report(
            report_id="string",
            content=Report(
                id="string",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"content": content}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_plan(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> ReportPlan:
        """
        Get the plan for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.get_report_plan(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/plan"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportPlan, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_report_plan(
        self,
        report_id: str,
        *,
        action: UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        request: typing.Optional[ReportPlan] = None,
    ) -> ReportResponse:
        """
        Update the plan of a report, including approval, rejection, and editing.

        Parameters:
            - report_id: str.

            - action: UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - request: typing.Optional[ReportPlan].
        ---
        from llama_cloud import (
            ReportPlan,
            UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction,
        )
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.update_report_plan(
            report_id="string",
            action=UpdateReportPlanApiV1ReportsReportIdPlanPatchRequestAction.APPROVE,
            request=ReportPlan(),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/plan"),
            params=remove_none_from_dict(
                {"action": action, "project_id": project_id, "organization_id": organization_id}
            ),
            json=jsonable_encoder(request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_events(
        self,
        report_id: str,
        *,
        after: typing.Optional[dt.datetime] = None,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
    ) -> typing.List[ReportEventItem]:
        """
        Get all historical events for a report.

        Parameters:
            - report_id: str.

            - after: typing.Optional[dt.datetime].

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.get_report_events(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/events"),
            params=remove_none_from_dict(
                {
                    "after": serialize_datetime(after) if after is not None else None,
                    "project_id": project_id,
                    "organization_id": organization_id,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ReportEventItem], _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_report_metadata(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> ReportMetadata:
        """
        Get metadata for a report.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.get_report_metadata(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/metadata"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ReportMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def suggest_edits_endpoint(
        self,
        report_id: str,
        *,
        project_id: typing.Optional[str] = None,
        organization_id: typing.Optional[str] = None,
        user_query: str,
        chat_history: typing.List[LlamaIndexCoreBaseLlmsTypesChatMessage],
    ) -> typing.List[EditSuggestion]:
        """
        Suggest edits to a report based on user query and chat history.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].

            - user_query: str.

            - chat_history: typing.List[LlamaIndexCoreBaseLlmsTypesChatMessage].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.suggest_edits_endpoint(
            report_id="string",
            user_query="string",
            chat_history=[],
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/suggest_edits"
            ),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            json=jsonable_encoder({"user_query": user_query, "chat_history": chat_history}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[EditSuggestion], _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def restart_report(
        self, report_id: str, *, project_id: typing.Optional[str] = None, organization_id: typing.Optional[str] = None
    ) -> typing.Any:
        """
        Restart a report from scratch.

        Parameters:
            - report_id: str.

            - project_id: typing.Optional[str].

            - organization_id: typing.Optional[str].
        ---
        from llama_cloud.client import AsyncLlamaCloud

        client = AsyncLlamaCloud(
            token="YOUR_TOKEN",
        )
        await client.reports.restart_report(
            report_id="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"api/v1/reports/{report_id}/restart"),
            params=remove_none_from_dict({"project_id": project_id, "organization_id": organization_id}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
