/**
 * PostNL Ecommerce APIsLib
 *
 * This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
 */

import { ApiResponse, RequestOptions } from '../core';
import { LocationsResponseError } from '../errors/locationsResponseError';
import {
  LocationsResponseInvalidError,
} from '../errors/locationsResponseInvalidError';
import {
  PostCIFLocationMethodNotAllowedError,
} from '../errors/postCIFLocationMethodNotAllowedError';
import {
  PostCIFLocationTooManyRequestError,
} from '../errors/postCIFLocationTooManyRequestError';
import {
  PostCIFLocationUnauthorizedError,
} from '../errors/postCIFLocationUnauthorizedError';
import {
  CountryCode1Enum,
  countryCode1EnumSchema,
} from '../models/countryCode1Enum';
import {
  DeliveryOption1Enum,
  deliveryOption1EnumSchema,
} from '../models/deliveryOption1Enum';
import {
  DeliveryOptions1Enum,
  deliveryOptions1EnumSchema,
} from '../models/deliveryOptions1Enum';
import {
  LocationResponse,
  locationResponseSchema,
} from '../models/locationResponse';
import {
  LocationsResponse,
  locationsResponseSchema,
} from '../models/locationsResponse';
import { array, number, optional, string } from '../schema';
import { BaseController } from './baseController';

export class LocationsController extends BaseController {
  /**
   * Request example:
   * ```
   * curl -X GET "https://api-sandbox.postnl.nl/shipment/v2_1/locations/nearest?
   * CountryCode=NL&PostalCode=2132WT&City=Hoofddorp&Street=Siriusdreef&HouseNumber=42&HouseNumberExtensi
   * on=-60&DeliveryDate=24-12-2022&OpeningTime=09%3A00%3A00" \
   * -H "Accept: application/json" \
   * -H "apikey: APIKEY-HERE" \
   * ```
   *
   *
   * @param countryCode          The country of the recipient's address
   * @param postalCode           The zipcode of the recipient's address
   * @param city                 The city of the recipient's address
   * @param street               The street name of the recipient's address
   * @param houseNumber          The house number of the recipient's address
   * @param houseNumberExtension The house number extension of the recipient's address
   * @param deliveryDate         The date of the earliest delivery date at the pickup
   *                                                      location. Format:  dd-MM-yyyy. Note: this date cannot be in
   *                                                      the past, otherwise an error is returned. If not provided,
   *                                                      the present day is used as a default
   * @param openingTime          Opening time filter. Format: hh:mm:ss. This field will be
   *                                                      used to filter out locations that are closed at the time
   *                                                      provided. If no opening time is provided all locations will
   *                                                      be returned regardless of their opening times.
   * @param deliveryOptions      The pickup location types for which locations should be
   *                                                      filtered. By default all location types are returned (PG =
   *                                                      Retail points and parcel lockers). This can be used to filter
   *                                                      on only parcel lockers (PA) or specifically exclude parcel
   *                                                      lockers from the response (PG_EX).
   * @return Response from the API call
   */
  async returnsPickupLocationsNearestToTheProvidedAddress(
    countryCode: CountryCode1Enum,
    postalCode: string,
    city?: string,
    street?: string,
    houseNumber?: number,
    houseNumberExtension?: string,
    deliveryDate?: string,
    openingTime?: string,
    deliveryOptions?: DeliveryOption1Enum[],
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<LocationsResponse>> {
    const req = this.createRequest('GET', '/shipment/v2_1/locations/nearest');
    const mapped = req.prepareArgs({
      countryCode: [countryCode, countryCode1EnumSchema],
      postalCode: [postalCode, string()],
      city: [city, optional(string())],
      street: [street, optional(string())],
      houseNumber: [houseNumber, optional(number())],
      houseNumberExtension: [houseNumberExtension, optional(string())],
      deliveryDate: [deliveryDate, optional(string())],
      openingTime: [openingTime, optional(string())],
      deliveryOptions: [
        deliveryOptions,
        optional(array(deliveryOption1EnumSchema)),
      ],
    });
    req.query('CountryCode', mapped.countryCode);
    req.query('PostalCode', mapped.postalCode);
    req.query('City', mapped.city);
    req.query('Street', mapped.street);
    req.query('HouseNumber', mapped.houseNumber);
    req.query('HouseNumberExtension', mapped.houseNumberExtension);
    req.query('DeliveryDate', mapped.deliveryDate);
    req.query('OpeningTime', mapped.openingTime);
    req.query('DeliveryOptions', mapped.deliveryOptions);
    req.throwOn(400, LocationsResponseInvalidError, 'Invalid request');
    req.throwOn(401, PostCIFLocationUnauthorizedError, 'Unauthorized');
    req.throwOn(405, PostCIFLocationMethodNotAllowedError, 'Method not allowed');
    req.throwOn(429, PostCIFLocationTooManyRequestError, 'Too many requests');
    req.throwOn(500, LocationsResponseError, 'Internal server error');
    return req.callAsJson(locationsResponseSchema, requestOptions);
  }

  /**
   * Request example:
   * ```
   * curl -X GET "https://api-sandbox.postnl.nl/shipment/v2_1/locations/nearest/geocode?Latitude=52.
   * 2864669620795&Longitude=4.68239055845954&CountryCode=NL&DeliveryDate=24-12-
   * 2022&OpeningTime=09%3A00%3A00" \
   * -H "Accept: application/json" \
   * -H "apikey: APIKEY-HERE" \
   * ```
   *
   *
   * @param latitude        The latitude of the location
   * @param longitude       The longitude of the location
   * @param countryCode     The coutry for which the coordinates are provided
   * @param deliveryDate    The date of the earliest delivery date. Format:  dd-MM-yyyy.
   *                                                  Note: this date cannot be in the past, otherwise an error is
   *                                                  returned.
   * @param openingTime     Opening time filter. Format: hh:mm:ss. This field will be used
   *                                                  to filter out locations that are closed at the time provided.
   * @param deliveryOptions The pickup location types for which locations should be filtered.
   *                                                  By default all location types are returned (PG = Retail points
   *                                                  and parcel lockers). This can be used to filter on only parcel
   *                                                  lockers (PA) or specifically exclude parcel lockers from the
   *                                                  response (PG_EX).
   * @return Response from the API call
   */
  async returnsPickupLocationsNearestToTheProvidedCoordinates(
    latitude: number,
    longitude: number,
    countryCode: CountryCode1Enum,
    deliveryDate?: string,
    openingTime?: string,
    deliveryOptions?: DeliveryOptions1Enum[],
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<LocationsResponse>> {
    const req = this.createRequest(
      'GET',
      '/shipment/v2_1/locations/nearest/geocode'
    );
    const mapped = req.prepareArgs({
      latitude: [latitude, number()],
      longitude: [longitude, number()],
      countryCode: [countryCode, countryCode1EnumSchema],
      deliveryDate: [deliveryDate, optional(string())],
      openingTime: [openingTime, optional(string())],
      deliveryOptions: [
        deliveryOptions,
        optional(array(deliveryOptions1EnumSchema)),
      ],
    });
    req.query('Latitude', mapped.latitude);
    req.query('Longitude', mapped.longitude);
    req.query('CountryCode', mapped.countryCode);
    req.query('DeliveryDate', mapped.deliveryDate);
    req.query('OpeningTime', mapped.openingTime);
    req.query('DeliveryOptions', mapped.deliveryOptions);
    req.throwOn(400, LocationsResponseInvalidError, 'Invalid request');
    req.throwOn(401, PostCIFLocationUnauthorizedError, 'Unauthorized');
    req.throwOn(405, PostCIFLocationMethodNotAllowedError, 'Method not allowed');
    req.throwOn(429, PostCIFLocationTooManyRequestError, 'Too many requests');
    req.throwOn(500, LocationsResponseError, 'Internal server error');
    return req.callAsJson(locationsResponseSchema, requestOptions);
  }

  /**
   * Request example:
   * ```
   * curl -X GET "https://api-sandbox.postnl.nl/shipment/v2_1/locations/area?LatitudeNorth=52.
   * 156439&LongitudeWest=5.015643&LatitudeSouth=52.017473&LongitudeEast=5.
   * 065254&CountryCode=NL&DeliveryDate=24-12-2023&OpeningTime=09%3A00%3A00" \
   * -H "Accept: application/json" \
   * -H "apikey: APIKEY-HERE" \
   * ```
   *
   *
   * @param latitudeNorth   The northmost coordinates of the area
   * @param longitudeWest   The westmost coordinates of the area
   * @param latitudeSouth   The southmost coordinates of the area
   * @param longitudeEast   The eastmost coordinates of the area
   * @param countryCode
   * @param deliveryDate    The date of the earliest delivery date. Format:  dd-MM-yyyy.
   *                                                  Note: this date cannot be in the past, otherwise an error is
   *                                                  returned.
   * @param openingTime     Opening time filter. Format: hh:mm:ss. This field will be used
   *                                                  to filter out locations that are closed at the time provided.
   * @param deliveryOptions The pickup location types for which locations should be filtered.
   *                                                  By default all location types are returned (PG = Retail points
   *                                                  and parcel lockers). This can be used to filter on only parcel
   *                                                  lockers (PA) or specifically exclude parcel lockers from the
   *                                                  response (PG_EX).
   * @return Response from the API call
   */
  async returnsPickupLocationsWithinAProvidedArea(
    latitudeNorth: number,
    longitudeWest: number,
    latitudeSouth: number,
    longitudeEast: number,
    countryCode: CountryCode1Enum,
    deliveryDate?: string,
    openingTime?: string,
    deliveryOptions?: DeliveryOptions1Enum[],
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<LocationsResponse>> {
    const req = this.createRequest('GET', '/shipment/v2_1/locations/area');
    const mapped = req.prepareArgs({
      latitudeNorth: [latitudeNorth, number()],
      longitudeWest: [longitudeWest, number()],
      latitudeSouth: [latitudeSouth, number()],
      longitudeEast: [longitudeEast, number()],
      countryCode: [countryCode, countryCode1EnumSchema],
      deliveryDate: [deliveryDate, optional(string())],
      openingTime: [openingTime, optional(string())],
      deliveryOptions: [
        deliveryOptions,
        optional(array(deliveryOptions1EnumSchema)),
      ],
    });
    req.query('LatitudeNorth', mapped.latitudeNorth);
    req.query('LongitudeWest', mapped.longitudeWest);
    req.query('LatitudeSouth', mapped.latitudeSouth);
    req.query('LongitudeEast', mapped.longitudeEast);
    req.query('CountryCode', mapped.countryCode);
    req.query('DeliveryDate', mapped.deliveryDate);
    req.query('OpeningTime', mapped.openingTime);
    req.query('DeliveryOptions', mapped.deliveryOptions);
    req.throwOn(400, LocationsResponseInvalidError, 'Invalid request');
    req.throwOn(401, PostCIFLocationUnauthorizedError, 'Unauthorized');
    req.throwOn(405, PostCIFLocationMethodNotAllowedError, 'Method not allowed');
    req.throwOn(429, PostCIFLocationTooManyRequestError, 'Too many requests');
    req.throwOn(500, LocationsResponseError, 'Internal server error');
    return req.callAsJson(locationsResponseSchema, requestOptions);
  }

  /**
   * Request example:
   * ```
   * curl -X GET "https://api-sandbox.postnl.nl/shipment/v2_1/locations/lookup?LocationCode=216877" \
   * -H "Accept: application/json" \
   * -H "apikey: APIKEY-HERE"
   * ```
   *
   *
   * @param locationCode LocationCode information
   * @return Response from the API call
   */
  async returnsASpecificPickupLocation(
    locationCode: string,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<LocationResponse>> {
    const req = this.createRequest('GET', '/shipment/v2_1/locations/lookup');
    const mapped = req.prepareArgs({ locationCode: [locationCode, string()] });
    req.query('LocationCode', mapped.locationCode);
    req.throwOn(400, LocationsResponseInvalidError, 'Invalid request');
    req.throwOn(401, PostCIFLocationUnauthorizedError, 'Unauthorized');
    req.throwOn(405, PostCIFLocationMethodNotAllowedError, 'Method not allowed');
    req.throwOn(429, PostCIFLocationTooManyRequestError, 'Too many requests');
    req.throwOn(500, LocationsResponseError, 'Invalid request');
    return req.callAsJson(locationResponseSchema, requestOptions);
  }
}
