# This file was generated by liblab | https://liblab.com/

from .utils.validator import Validator
from .utils.base_service import BaseService
from ..net.transport.serializer import Serializer
from ..models.utils.cast_models import cast_models
from ..models.review_scores_input_dto import ReviewScoresInputDto
from ..models.response_output_v2_review_scores_output_dto import (
    ResponseOutputV2ReviewScoresOutputDto,
)
from ..models.response_output_v2_hotels_output_dto import (
    ResponseOutputV2HotelsOutputDto,
)
from ..models.response_output_v2_hotel_types_output_dto import (
    ResponseOutputV2HotelTypesOutputDto,
)
from ..models.response_output_v2_hotel_theme_types_output_dto import (
    ResponseOutputV2HotelThemeTypesOutputDto,
)
from ..models.response_output_v2_hotel_facility_type_output_dto import (
    ResponseOutputV2HotelFacilityTypeOutputDto,
)
from ..models.response_output_v2_hotel_availability_output_dto import (
    ResponseOutputV2HotelAvailabilityOutputDto,
)
from ..models.response_output_v2_block_availability_output_dto import (
    ResponseOutputV2BlockAvailabilityOutputDto,
)
from ..models.hotels_input_dto import HotelsInputDto
from ..models.hotel_type_input_dto import HotelTypeInputDto
from ..models.hotel_theme_type_input_dto import HotelThemeTypeInputDto
from ..models.hotel_facility_input_dto import HotelFacilityInputDto
from ..models.hotel_availability_input_dto import HotelAvailabilityInputDto
from ..models.get_room_facility_types_accept import GetRoomFacilityTypesAccept
from ..models.get_hotels_review_scores_accept import GetHotelsReviewScoresAccept
from ..models.get_hotels_accept import GetHotelsAccept
from ..models.get_hotel_types_accept import GetHotelTypesAccept
from ..models.get_hotel_theme_types_accept import GetHotelThemeTypesAccept
from ..models.get_hotel_availability_accept import GetHotelAvailabilityAccept
from ..models.get_block_availability_accept import GetBlockAvailabilityAccept
from ..models.block_availability_input_dto import BlockAvailabilityInputDto


class DemandApiV2CompatibleService(BaseService):

    @cast_models
    def get_hotels_review_scores(
        self,
        review_scores_input_dto: ReviewScoresInputDto,
        accept: GetHotelsReviewScoresAccept = None,
    ) -> ResponseOutputV2ReviewScoresOutputDto:
        """Gives information about review scores for specified hotel_ids and filter.
        The information consists of score breakdown per reviewer_type and review questions,
        and overall score distribution per score value (1 - 10).

        The available filter is input parameter reviewer_type=... .
        It allows generating review score information for just one reviewer type.

        Language in which the response is rendered can be controlled with the input parameter language=...
        (default: 'en'). Setting the language will reflect on the output fields question and review_score_word.

        One additional output field can be requested with input parameter extras=review_score_word.

        :param review_scores_input_dto: review_scores_input_dto
        :type review_scores_input_dto: ReviewScoresInputDto
        :param accept: accept, defaults to None
        :type accept: GetHotelsReviewScoresAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2ReviewScoresOutputDto
        """

        Validator(ReviewScoresInputDto).validate(review_scores_input_dto)
        Validator(GetHotelsReviewScoresAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/reviewScores",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("reviewScoresInputDto", review_scores_input_dto)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2ReviewScoresOutputDto._unmap(response)

    @cast_models
    def get_hotels(
        self, hotels_input: HotelsInputDto, accept: GetHotelsAccept = None
    ) -> ResponseOutputV2HotelsOutputDto:
        """This call returns the hotel and room data. By default, only hotel_id is returned in the output.

        One of the argument: hotel_ids, city_ids, country_ids, region_ids, district_ids, chain_ids is mandatory.

        Additional data needs to be requested via extras parameter.

        The data is returned in English by default.

        :param hotels_input: hotels_input
        :type hotels_input: HotelsInputDto
        :param accept: accept, defaults to None
        :type accept: GetHotelsAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2HotelsOutputDto
        """

        Validator(HotelsInputDto).validate(hotels_input)
        Validator(GetHotelsAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/hotels",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("hotelsInput", hotels_input)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2HotelsOutputDto._unmap(response)

    @cast_models
    def get_hotel_types(
        self,
        hotel_type_input_dto: HotelTypeInputDto,
        accept: GetHotelTypesAccept = None,
    ) -> ResponseOutputV2HotelTypesOutputDto:
        """This endpoint returns hotel types names and their translations. (EN is default)

        :param hotel_type_input_dto: hotel_type_input_dto
        :type hotel_type_input_dto: HotelTypeInputDto
        :param accept: accept, defaults to None
        :type accept: GetHotelTypesAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2HotelTypesOutputDto
        """

        Validator(HotelTypeInputDto).validate(hotel_type_input_dto)
        Validator(GetHotelTypesAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/hotelTypes",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("hotelTypeInputDTO", hotel_type_input_dto)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2HotelTypesOutputDto._unmap(response)

    @cast_models
    def get_hotel_theme_types(
        self,
        hotel_theme_type_input_dto: HotelThemeTypeInputDto,
        accept: GetHotelThemeTypesAccept = None,
    ) -> ResponseOutputV2HotelThemeTypesOutputDto:
        """This endpoint returns a list of hotel theme types (in English).

        :param hotel_theme_type_input_dto: hotel_theme_type_input_dto
        :type hotel_theme_type_input_dto: HotelThemeTypeInputDto
        :param accept: accept, defaults to None
        :type accept: GetHotelThemeTypesAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2HotelThemeTypesOutputDto
        """

        Validator(HotelThemeTypeInputDto).validate(hotel_theme_type_input_dto)
        Validator(GetHotelThemeTypesAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/hotelThemeTypes",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("hotelThemeTypeInputDTO", hotel_theme_type_input_dto)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2HotelThemeTypesOutputDto._unmap(response)

    @cast_models
    def get_room_facility_types(
        self,
        hotel_facility_input_dto: HotelFacilityInputDto,
        accept: GetRoomFacilityTypesAccept = None,
    ) -> ResponseOutputV2HotelFacilityTypeOutputDto:
        """This endpoint returns room facility types names and their translations (EN is default).

        :param hotel_facility_input_dto: hotel_facility_input_dto
        :type hotel_facility_input_dto: HotelFacilityInputDto
        :param accept: accept, defaults to None
        :type accept: GetRoomFacilityTypesAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2HotelFacilityTypeOutputDto
        """

        Validator(HotelFacilityInputDto).validate(hotel_facility_input_dto)
        Validator(GetRoomFacilityTypesAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/hotelFacilityTypes",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("hotelFacilityInputDto", hotel_facility_input_dto)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2HotelFacilityTypeOutputDto._unmap(response)

    @cast_models
    def get_hotel_availability(
        self,
        hotel_availability_input_dto: HotelAvailabilityInputDto,
        accept: GetHotelAvailabilityAccept = None,
    ) -> ResponseOutputV2HotelAvailabilityOutputDto:
        """This endpoint returns the cheapest available room for each hotel matching your check-in and check-out dates.
        You can search for hotels in a city, or for a specific list of (upto 300) hotels by hotel_ids.
        Here you will find whether the price included breakfast or other meals, as well as whether it is possible to cancel for free.
        It is possible to have a breakdown of the price returned by this endpoint and to filter by property types and/or hotel facilities.

        :param hotel_availability_input_dto: hotel_availability_input_dto
        :type hotel_availability_input_dto: HotelAvailabilityInputDto
        :param accept: accept, defaults to None
        :type accept: GetHotelAvailabilityAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2HotelAvailabilityOutputDto
        """

        Validator(HotelAvailabilityInputDto).validate(hotel_availability_input_dto)
        Validator(GetHotelAvailabilityAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/hotelAvailability",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("hotelAvailabilityInputDto", hotel_availability_input_dto)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2HotelAvailabilityOutputDto._unmap(response)

    @cast_models
    def get_block_availability(
        self,
        block_input: BlockAvailabilityInputDto,
        accept: GetBlockAvailabilityAccept = None,
    ) -> ResponseOutputV2BlockAvailabilityOutputDto:
        """This endpoint is where you find a list of all bookable or available rooms at a property.
        A room can have multiple blocks, as a block is a combination of the meal, cancellation policy, occupancy and other things.
        You can find detailed information about one hotel per search (detail_level)
        which will return most of the information needed to replicate the booking.com property page.

        If you want to search multiple hotels, you can, but you get less detail.
        For searching multiple hotels, it is recommended to use hotelAvailability.

        :param block_input: block_input
        :type block_input: BlockAvailabilityInputDto
        :param accept: accept, defaults to None
        :type accept: GetBlockAvailabilityAccept, optional
        ...
        :raises RequestError: Raised when a request fails, with optional HTTP status code and details.
        ...
        :return: OK
        :rtype: ResponseOutputV2BlockAvailabilityOutputDto
        """

        Validator(BlockAvailabilityInputDto).validate(block_input)
        Validator(GetBlockAvailabilityAccept).is_optional().validate(accept)

        serialized_request = (
            Serializer(
                f"{self.base_url}/demand-api-v2-compatible/blockAvailability",
                self.get_default_headers(),
            )
            .add_header("Accept", accept)
            .add_query("blockInput", block_input)
            .serialize()
            .set_method("GET")
        )

        response = self.send_request(serialized_request)

        return ResponseOutputV2BlockAvailabilityOutputDto._unmap(response)
