from typing import Any

from .._base import LONG_TIMEOUT, AsyncBaseResource, AsyncPageIterator, BaseResource, PageIterator
from ..models import OrderChange, OrderChangeOffer, OrderChangeRequest


class OrderChangeRequests(BaseResource):
    _path = "/air/order_change_requests"

    def get(self, id: str) -> OrderChangeRequest:
        return self._get(id, OrderChangeRequest)

    def create(
        self,
        *,
        order_id: str,
        slices: dict[str, Any],
        private_fares: dict[str, Any] | None = None,
    ) -> OrderChangeRequest:
        data: dict[str, Any] = {"order_id": order_id, "slices": slices}
        if private_fares is not None:
            data["private_fares"] = private_fares
        return self._create(OrderChangeRequest, data)


class OrderChangeOffers(BaseResource):
    _path = "/air/order_change_offers"

    def list(
        self,
        order_change_request_id: str,
        *,
        limit: int | None = None,
        sort: str | None = None,
        max_connections: int | None = None,
    ) -> PageIterator[OrderChangeOffer]:
        return self._list(
            OrderChangeOffer,
            params={
                "order_change_request_id": order_change_request_id,
                "limit": limit,
                "sort": sort,
                "max_connections": max_connections,
            },
        )

    def get(self, id: str) -> OrderChangeOffer:
        return self._get(id, OrderChangeOffer)


class OrderChanges(BaseResource):
    _path = "/air/order_changes"

    def get(self, id: str) -> OrderChange:
        return self._get(id, OrderChange)

    def create(self, *, selected_order_change_offer: str) -> OrderChange:
        return self._create(OrderChange, {"selected_order_change_offer": selected_order_change_offer})

    def confirm(self, id: str, *, payment: dict[str, Any] | None = None) -> OrderChange:
        return self._action(id, "confirm", OrderChange, data={"payment": payment} if payment else None,
                            timeout=LONG_TIMEOUT)


class AsyncOrderChangeRequests(AsyncBaseResource):
    _path = "/air/order_change_requests"

    async def get(self, id: str) -> OrderChangeRequest:
        return await self._get(id, OrderChangeRequest)

    async def create(
        self,
        *,
        order_id: str,
        slices: dict[str, Any],
        private_fares: dict[str, Any] | None = None,
    ) -> OrderChangeRequest:
        data: dict[str, Any] = {"order_id": order_id, "slices": slices}
        if private_fares is not None:
            data["private_fares"] = private_fares
        return await self._create(OrderChangeRequest, data)


class AsyncOrderChangeOffers(AsyncBaseResource):
    _path = "/air/order_change_offers"

    def list(
        self,
        order_change_request_id: str,
        *,
        limit: int | None = None,
        sort: str | None = None,
        max_connections: int | None = None,
    ) -> AsyncPageIterator[OrderChangeOffer]:
        return self._list(
            OrderChangeOffer,
            params={
                "order_change_request_id": order_change_request_id,
                "limit": limit,
                "sort": sort,
                "max_connections": max_connections,
            },
        )

    async def get(self, id: str) -> OrderChangeOffer:
        return await self._get(id, OrderChangeOffer)


class AsyncOrderChanges(AsyncBaseResource):
    _path = "/air/order_changes"

    async def get(self, id: str) -> OrderChange:
        return await self._get(id, OrderChange)

    async def create(self, *, selected_order_change_offer: str) -> OrderChange:
        return await self._create(OrderChange, {"selected_order_change_offer": selected_order_change_offer})

    async def confirm(self, id: str, *, payment: dict[str, Any] | None = None) -> OrderChange:
        return await self._action(id, "confirm", OrderChange, data={"payment": payment} if payment else None,
                                  timeout=LONG_TIMEOUT)
