from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

from ... import errors
from ...client import AuthenticatedClient, Client
from ...models.bulk_update_documents_request import BulkUpdateDocumentsRequest
from ...models.bulk_update_documents_response import BulkUpdateDocumentsResponse
from ...models.error_response import ErrorResponse
from ...models.http_validation_error import HTTPValidationError
from ...types import UNSET, Response, Unset


def _get_kwargs(
    collection_identifier: str,
    *,
    body: BulkUpdateDocumentsRequest,
    authorization: str | Unset = UNSET,
    x_namespace: str | Unset = UNSET,
) -> dict[str, Any]:
    headers: dict[str, Any] = {}
    if not isinstance(authorization, Unset):
        headers["Authorization"] = authorization

    if not isinstance(x_namespace, Unset):
        headers["X-Namespace"] = x_namespace

    _kwargs: dict[str, Any] = {
        "method": "patch",
        "url": "/v1/collections/{collection_identifier}/documents/bulk".format(
            collection_identifier=quote(str(collection_identifier), safe=""),
        ),
    }

    _kwargs["json"] = body.to_dict()

    headers["Content-Type"] = "application/json"

    _kwargs["headers"] = headers
    return _kwargs


def _parse_response(
    *, client: AuthenticatedClient | Client, response: httpx.Response
) -> BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError | None:
    if response.status_code == 200:
        response_200 = BulkUpdateDocumentsResponse.from_dict(response.json())

        return response_200

    if response.status_code == 400:
        response_400 = ErrorResponse.from_dict(response.json())

        return response_400

    if response.status_code == 401:
        response_401 = ErrorResponse.from_dict(response.json())

        return response_401

    if response.status_code == 403:
        response_403 = ErrorResponse.from_dict(response.json())

        return response_403

    if response.status_code == 404:
        response_404 = ErrorResponse.from_dict(response.json())

        return response_404

    if response.status_code == 422:
        response_422 = HTTPValidationError.from_dict(response.json())

        return response_422

    if response.status_code == 500:
        response_500 = ErrorResponse.from_dict(response.json())

        return response_500

    if client.raise_on_unexpected_status:
        raise errors.UnexpectedStatus(response.status_code, response.content)
    else:
        return None


def _build_response(
    *, client: AuthenticatedClient | Client, response: httpx.Response
) -> Response[BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError]:
    return Response(
        status_code=HTTPStatus(response.status_code),
        content=response.content,
        headers=response.headers,
        parsed=_parse_response(client=client, response=response),
    )


def sync_detailed(
    collection_identifier: str,
    *,
    client: AuthenticatedClient | Client,
    body: BulkUpdateDocumentsRequest,
    authorization: str | Unset = UNSET,
    x_namespace: str | Unset = UNSET,
) -> Response[BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError]:
    """Bulk Update Documents

     Bulk update documents matching filter conditions.

    Partially updates all documents in the collection that match the provided filters.
    If no filters are provided, updates all documents in the collection.

    This endpoint applies the SAME update_data to ALL documents matching the filters.
    For per-document updates with different values, use POST /batch endpoint instead.

    Args:
        collection_identifier (str): The ID of the collection to update documents in.
        authorization (str | Unset): REQUIRED: Bearer token authentication using your API key.
            Format: 'Bearer sk_xxxxxxxxxxxxx'. You can create API keys in the Mixpeek dashboard under
            Organization Settings.
        x_namespace (str | Unset): REQUIRED: Namespace identifier for scoping this request. All
            resources (collections, buckets, taxonomies, etc.) are scoped to a namespace. You can
            provide either the namespace name or namespace ID. Format: ns_xxxxxxxxxxxxx (ID) or a
            custom name like 'my-namespace'
        body (BulkUpdateDocumentsRequest): Request model for bulk updating documents by filters.

            Updates ALL documents matching the provided filters with the SAME update_data.
            For updating specific documents by ID or different values per document, use
            BatchUpdateDocumentsRequest.

            Use Cases:
                - Update all pending documents to processed
                - Update all documents from a specific date range
                - Apply uniform changes across filtered document sets

            Requirements:
                - update_data: REQUIRED - fields to update on all matching documents
                - filters: OPTIONAL - if omitted, updates ALL documents in collection

    Raises:
        errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
        httpx.TimeoutException: If the request takes longer than Client.timeout.

    Returns:
        Response[BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError]
    """

    kwargs = _get_kwargs(
        collection_identifier=collection_identifier,
        body=body,
        authorization=authorization,
        x_namespace=x_namespace,
    )

    response = client.get_httpx_client().request(
        **kwargs,
    )

    return _build_response(client=client, response=response)


def sync(
    collection_identifier: str,
    *,
    client: AuthenticatedClient | Client,
    body: BulkUpdateDocumentsRequest,
    authorization: str | Unset = UNSET,
    x_namespace: str | Unset = UNSET,
) -> BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError | None:
    """Bulk Update Documents

     Bulk update documents matching filter conditions.

    Partially updates all documents in the collection that match the provided filters.
    If no filters are provided, updates all documents in the collection.

    This endpoint applies the SAME update_data to ALL documents matching the filters.
    For per-document updates with different values, use POST /batch endpoint instead.

    Args:
        collection_identifier (str): The ID of the collection to update documents in.
        authorization (str | Unset): REQUIRED: Bearer token authentication using your API key.
            Format: 'Bearer sk_xxxxxxxxxxxxx'. You can create API keys in the Mixpeek dashboard under
            Organization Settings.
        x_namespace (str | Unset): REQUIRED: Namespace identifier for scoping this request. All
            resources (collections, buckets, taxonomies, etc.) are scoped to a namespace. You can
            provide either the namespace name or namespace ID. Format: ns_xxxxxxxxxxxxx (ID) or a
            custom name like 'my-namespace'
        body (BulkUpdateDocumentsRequest): Request model for bulk updating documents by filters.

            Updates ALL documents matching the provided filters with the SAME update_data.
            For updating specific documents by ID or different values per document, use
            BatchUpdateDocumentsRequest.

            Use Cases:
                - Update all pending documents to processed
                - Update all documents from a specific date range
                - Apply uniform changes across filtered document sets

            Requirements:
                - update_data: REQUIRED - fields to update on all matching documents
                - filters: OPTIONAL - if omitted, updates ALL documents in collection

    Raises:
        errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
        httpx.TimeoutException: If the request takes longer than Client.timeout.

    Returns:
        BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError
    """

    return sync_detailed(
        collection_identifier=collection_identifier,
        client=client,
        body=body,
        authorization=authorization,
        x_namespace=x_namespace,
    ).parsed


async def asyncio_detailed(
    collection_identifier: str,
    *,
    client: AuthenticatedClient | Client,
    body: BulkUpdateDocumentsRequest,
    authorization: str | Unset = UNSET,
    x_namespace: str | Unset = UNSET,
) -> Response[BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError]:
    """Bulk Update Documents

     Bulk update documents matching filter conditions.

    Partially updates all documents in the collection that match the provided filters.
    If no filters are provided, updates all documents in the collection.

    This endpoint applies the SAME update_data to ALL documents matching the filters.
    For per-document updates with different values, use POST /batch endpoint instead.

    Args:
        collection_identifier (str): The ID of the collection to update documents in.
        authorization (str | Unset): REQUIRED: Bearer token authentication using your API key.
            Format: 'Bearer sk_xxxxxxxxxxxxx'. You can create API keys in the Mixpeek dashboard under
            Organization Settings.
        x_namespace (str | Unset): REQUIRED: Namespace identifier for scoping this request. All
            resources (collections, buckets, taxonomies, etc.) are scoped to a namespace. You can
            provide either the namespace name or namespace ID. Format: ns_xxxxxxxxxxxxx (ID) or a
            custom name like 'my-namespace'
        body (BulkUpdateDocumentsRequest): Request model for bulk updating documents by filters.

            Updates ALL documents matching the provided filters with the SAME update_data.
            For updating specific documents by ID or different values per document, use
            BatchUpdateDocumentsRequest.

            Use Cases:
                - Update all pending documents to processed
                - Update all documents from a specific date range
                - Apply uniform changes across filtered document sets

            Requirements:
                - update_data: REQUIRED - fields to update on all matching documents
                - filters: OPTIONAL - if omitted, updates ALL documents in collection

    Raises:
        errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
        httpx.TimeoutException: If the request takes longer than Client.timeout.

    Returns:
        Response[BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError]
    """

    kwargs = _get_kwargs(
        collection_identifier=collection_identifier,
        body=body,
        authorization=authorization,
        x_namespace=x_namespace,
    )

    response = await client.get_async_httpx_client().request(**kwargs)

    return _build_response(client=client, response=response)


async def asyncio(
    collection_identifier: str,
    *,
    client: AuthenticatedClient | Client,
    body: BulkUpdateDocumentsRequest,
    authorization: str | Unset = UNSET,
    x_namespace: str | Unset = UNSET,
) -> BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError | None:
    """Bulk Update Documents

     Bulk update documents matching filter conditions.

    Partially updates all documents in the collection that match the provided filters.
    If no filters are provided, updates all documents in the collection.

    This endpoint applies the SAME update_data to ALL documents matching the filters.
    For per-document updates with different values, use POST /batch endpoint instead.

    Args:
        collection_identifier (str): The ID of the collection to update documents in.
        authorization (str | Unset): REQUIRED: Bearer token authentication using your API key.
            Format: 'Bearer sk_xxxxxxxxxxxxx'. You can create API keys in the Mixpeek dashboard under
            Organization Settings.
        x_namespace (str | Unset): REQUIRED: Namespace identifier for scoping this request. All
            resources (collections, buckets, taxonomies, etc.) are scoped to a namespace. You can
            provide either the namespace name or namespace ID. Format: ns_xxxxxxxxxxxxx (ID) or a
            custom name like 'my-namespace'
        body (BulkUpdateDocumentsRequest): Request model for bulk updating documents by filters.

            Updates ALL documents matching the provided filters with the SAME update_data.
            For updating specific documents by ID or different values per document, use
            BatchUpdateDocumentsRequest.

            Use Cases:
                - Update all pending documents to processed
                - Update all documents from a specific date range
                - Apply uniform changes across filtered document sets

            Requirements:
                - update_data: REQUIRED - fields to update on all matching documents
                - filters: OPTIONAL - if omitted, updates ALL documents in collection

    Raises:
        errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
        httpx.TimeoutException: If the request takes longer than Client.timeout.

    Returns:
        BulkUpdateDocumentsResponse | ErrorResponse | HTTPValidationError
    """

    return (
        await asyncio_detailed(
            collection_identifier=collection_identifier,
            client=client,
            body=body,
            authorization=authorization,
            x_namespace=x_namespace,
        )
    ).parsed
