﻿using MiX.Integrate.API.Client.Base;
using MiX.Integrate.Shared.Constants;
using MiX.Integrate.Shared.Entities.Carriers;
using MiX.Integrate.Shared.Entities.Drivers;
using MiX.Integrate.Shared.Entities.Trips;
using MiX.Integrate.Shared.Helpers;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace MiX.Integrate.API.Client
{
  public class TripsClient : BaseClient, ITripsClient
	{

		#region constructors

		public TripsClient(string url, bool setTestRequestHeader = false) : base(url, setTestRequestHeader) { }
		public TripsClient(string url, IdServerResourceOwnerClientSettings settings, bool setTestRequestHeader = false) : base(url, settings, setTestRequestHeader) { }

		#endregion

		#region Latest

		public IList<Trip> GetLatestForAssets(List<long> assetIds, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetLatestForAssetsAsync(List<long> assetIds, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetLatestForDrivers(List<long> driverIds, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetLatestForDriversAsync(List<long> driverIds, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetLatestForGroups(List<long> groupIds, string entityType, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddUrlSegment("entityType", entityType);
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetLatestForGroupsAsync(List<long> groupIds, string entityType, byte quantity = 1, DateTime? cachedSince = null, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETLATESTFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddUrlSegment("entityType", entityType);
			if (cachedSince.HasValue)
				request.AddQueryParameter("cachedSince", cachedSince.Value.ToUniversalTime().ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region Range

		public IList<Trip> GetRangeForAssets(List<long> assetIds, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetRangeForAssetsAsync(List<long> assetIds, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetRangeForDrivers(List<long> driverIds, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetRangeForDriversAsync(List<long> driverIds, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetRangeForGroups(List<long> groupIds, string entityType, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetRangeForGroupsAsync(List<long> groupIds, string entityType, DateTime from, DateTime to, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETRANGEFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region Since

		public IList<Trip> GetSinceForAssets(List<long> assetIds, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetSinceForAssetsAsync(List<long> assetIds, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORASSETS, HttpMethod.Post);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetSinceForDrivers(List<long> driverIds, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetSinceForDriversAsync(List<long> driverIds, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		public IList<Trip> GetSinceForGroups(List<long> groupIds, string entityType, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			return response.Data;
		}

		public async Task<IList<Trip>> GetSinceForGroupsAsync(List<long> groupIds, string entityType, DateTime since, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETSINCEFORGROUPS, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("since", since.ToString(DataFormats.DateTime_Format));
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region Created Since

		public CreatedSinceResult<Trip> GetCreatedSinceForAssets(List<long> assetIds, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORASSETSASYNC, HttpMethod.Post);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public async Task<CreatedSinceResult<Trip>> GetCreatedSinceForAssetsAsync(List<long> assetIds, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORASSETSASYNC, HttpMethod.Post);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(assetIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public CreatedSinceResult<Trip> GetCreatedSinceForDrivers(List<long> driverIds, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORDRIVERSASYNC, HttpMethod.Post);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public async Task<CreatedSinceResult<Trip>> GetCreatedSinceForDriversAsync(List<long> driverIds, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORDRIVERSASYNC, HttpMethod.Post);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public CreatedSinceResult<Trip> GetCreatedSinceForGroups(List<long> groupIds, string entityType, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORGROUPSASYNC, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public async Task<CreatedSinceResult<Trip>> GetCreatedSinceForGroupsAsync(List<long> groupIds, string entityType, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORGROUPSASYNC, HttpMethod.Post);
			request.AddUrlSegment("entityType", entityType);
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			request.AddJsonBody(groupIds);
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public CreatedSinceResult<Trip> GetCreatedSinceForOrganisation(long organisationId, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORORGANISATION, HttpMethod.Get);
			request.AddUrlSegment("organisationId", organisationId.ToString());
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			IHttpRestResponse<List<Trip>> response = Execute<List<Trip>>(request);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		public async Task<CreatedSinceResult<Trip>> GetCreatedSinceForOrganisationAsync(long organisationId, string sinceToken, int quantity, bool includeSubTrips = false)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETCREATEDSINCEFORORGANISATION, HttpMethod.Get);
			request.AddUrlSegment("organisationId", organisationId.ToString());
			request.AddUrlSegment("sinceToken", sinceToken);
			request.AddUrlSegment("quantity", quantity.ToString());
			request.AddQueryParameter("includeSubTrips", includeSubTrips.ToString());
			IHttpRestResponse<List<Trip>> response = await ExecuteAsync<List<Trip>>(request).ConfigureAwait(false);
			string sHasMoreItems = GetResponseHeader(response.Headers, "HasMoreItems");
			string getSinceToken = GetResponseHeader(response.Headers, "GetSinceToken");
			bool hasMoreItems = false;
			if (!bool.TryParse(sHasMoreItems, out hasMoreItems))
				throw new Exception("Could not read the HasMoreItems header");
			return new CreatedSinceResult<Trip>() { HasMoreItems = hasMoreItems, GetSinceToken = getSinceToken, Items = response.Data };
		}

		#endregion

		#region RIBAS Metrics

		public List<TripRibasMetrics> GetRibasMetricsForDrivers(List<long> driverIds, DateTime @from, DateTime to)
		{
			if ((driverIds?.Count ?? 0) == 0 ) throw new ArgumentException("No driver ids specified",nameof(driverIds));
			if (from.CompareTo(to) > 0) throw new ArgumentException("Invalid date range specified");
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETTRIPRIBASMETRICSBYDATERANGEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<TripRibasMetrics>> response =  Execute<List<TripRibasMetrics>>(request);
			return response.Data;
		}

		public async Task<List<TripRibasMetrics>> GetRibasMetricsForDriversAsync(List<long> driverIds, DateTime @from, DateTime to)
		{
			if ((driverIds?.Count ?? 0) == 0 ) throw new ArgumentException("No driver ids specified",nameof(driverIds));
			if (from.CompareTo(to) > 0) throw new ArgumentException("Invalid date range specified");
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETTRIPRIBASMETRICSBYDATERANGEFORDRIVERS, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<TripRibasMetrics>> response = await ExecuteAsync<List<TripRibasMetrics>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region DriverScores

		public List<DriverScore> GetDriverScores(List<long> driverIds, DateTime from, DateTime to)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETDRIVERSCORES, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<DriverScore>> response = Execute<List<DriverScore>>(request);
			return response.Data;
		}

		public async Task<List<DriverScore>> GetDriverScoresAsync(List<long> driverIds, DateTime from, DateTime to)
		{
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETDRIVERSCORES, HttpMethod.Post);
			request.AddUrlSegment("from", from.ToString(DataFormats.DateTime_Format));
			request.AddUrlSegment("to", to.ToString(DataFormats.DateTime_Format));
			request.AddJsonBody(driverIds);
			IHttpRestResponse<List<DriverScore>> response = await ExecuteAsync<List<DriverScore>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region DEMT amendments

		public List<TripAmendment> GetTripAmendmentsForOrganisation(long organisationId, string from, string to)
		{
			if (!from.TryParseUtcDateString(out var dateFrom))
				throw new ArgumentException("The date range start value must be a valid date in the form YYYYMMDD", nameof(from));
			if (!to.TryParseUtcDateString(out var dateTo))
				throw new ArgumentException("The date range end value must be a valid date in the form YYYYMMDD", nameof(to));
			if (dateTo.CompareTo(dateFrom) < 0)
				throw new ArgumentException("The date range end may not precede the start", nameof(to));
			if (dateTo.CompareTo(dateFrom.AddDays(6)) > 0)
				throw new ArgumentException("The date range may not exceed 7 days", nameof(to));
			
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETDEMTTRIPAMENDMENTS, HttpMethod.Get);
			request.AddUrlSegment("organisationId", organisationId.ToString());
			request.AddUrlSegment("from", from);
			request.AddUrlSegment("to", to);
			IHttpRestResponse<List<TripAmendment>> response = Execute<List<TripAmendment>>(request);
			return response.Data;
		}

		public async Task<List<TripAmendment>> GetTripAmendmentsForOrganisationAsync(long organisationId, string from, string to)
		{
			if (!from.TryParseUtcDateString(out var dateFrom))
				throw new ArgumentException("The date range start value must be a valid date in the form YYYYMMDD", nameof(from));
			if (!to.TryParseUtcDateString(out var dateTo))
				throw new ArgumentException("The date range end value must be a valid date in the form YYYYMMDD", nameof(to));
			if (dateTo.CompareTo(dateFrom) < 0)
				throw new ArgumentException("The date range end may not precede the start", nameof(to));
			if (dateTo.CompareTo(dateFrom.AddDays(6)) > 0)
				throw new ArgumentException("The date range may not exceed 7 days", nameof(to));
			
			IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.GETDEMTTRIPAMENDMENTS, HttpMethod.Get);
			request.AddUrlSegment("organisationId", organisationId.ToString());
			request.AddUrlSegment("from", from);
			request.AddUrlSegment("to", to);
			IHttpRestResponse<List<TripAmendment>> response = await ExecuteAsync<List<TripAmendment>>(request).ConfigureAwait(false);
			return response.Data;
		}

		#endregion

		#region TripClassification
		//public void UpdateTripClassification(long tripId, TripClassificationForUpdate classification)
		//{
		//	IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.UPDATETRIPCLASSIFICATION, HttpMethod.Put);
		//	request.AddUrlSegment("tripId", tripId.ToString());
		//	request.AddJsonBody(classification);
		//	Execute(request);
		//}

		//public async Task UpdateTripClassificationAsync(long tripId, TripClassificationForUpdate classification)
		//{
		//	IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.UPDATETRIPCLASSIFICATION, HttpMethod.Put);
		//	request.AddUrlSegment("tripId", tripId.ToString());
		//	request.AddJsonBody(classification);
		//	await ExecuteAsync(request).ConfigureAwait(false);
		//}

		//public void UpdateTripClassificationComment(long tripId, string comment)
		//{
		//	IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.UPDATETRIPCLASSIFICATIONCOMMENT, HttpMethod.Put);
		//	request.AddUrlSegment("tripId", tripId.ToString());
		//	request.AddJsonBody(new TripClassificationComment { Comment = comment });
		//	Execute(request);
		//}

		//public async Task UpdateTripClassificationCommentAsync(long tripId, string comment)
		//{
		//	IHttpRestRequest request = GetRequest(APIControllerRoutes.TripsController.UPDATETRIPCLASSIFICATIONCOMMENT, HttpMethod.Put);
		//	request.AddUrlSegment("tripId", tripId.ToString());
		//	request.AddJsonBody(new TripClassificationComment { Comment = comment });
		//	await ExecuteAsync(request).ConfigureAwait(false);
		//}
		#endregion
	}
}
