/*
 * Solidarity Mobility API
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * API version: 1.0.0
 * Generated by: OpenAPI Generator (https://openapi-generator.tech)
 */

package openapi

import (
	"context"
	"errors"
	"github.com/paulmach/orb"
	"github.com/paulmach/orb/geojson"
	"github.com/spf13/viper"
	"net/http"
	"solidarity-service/handler"
	"solidarity-service/internal"
	"solidarity-service/storage"
)

// DriverAvailabilityAndScheduleAPIService is a service that implements the logic for the DriverAvailabilityAndScheduleAPIServicer
// This service should implement the business logic for every endpoint for the DriverAvailabilityAndScheduleAPI API.
// Include any external packages or services that will be required by this service.
type DriverAvailabilityAndScheduleAPIService struct {
	config  *viper.Viper
	handler *handler.SolidarityServiceHandler
	storage storage.Storage
}

// NewDriverAvailabilityAndScheduleAPIService creates a default api service
func NewDriverAvailabilityAndScheduleAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) DriverAvailabilityAndScheduleAPIServicer {
	return &DriverAvailabilityAndScheduleAPIService{
		config:  config,
		handler: handler,
		storage: storage,
	}
}

// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities
func (s *DriverAvailabilityAndScheduleAPIService) DriverPunctualAvailabilitiesPost(ctx context.Context, driverPunctualAvailabilitiesRequest DriverPunctualAvailabilitiesRequest) (ImplResponse, error) {
	driver := internal.Driver{}
	driver.Driver.ID = driverPunctualAvailabilitiesRequest.User.Id
	driver.Driver.Operator = driverPunctualAvailabilitiesRequest.User.Operator
	driver.Driver.Alias = driverPunctualAvailabilitiesRequest.User.Alias
	driver.Driver.Grade = int64(driverPunctualAvailabilitiesRequest.User.Grade)
	driver.Driver.Picture = driverPunctualAvailabilitiesRequest.User.Picture
	driver.Driver.LastName = driverPunctualAvailabilitiesRequest.User.LastName
	driver.Driver.FirstName = driverPunctualAvailabilitiesRequest.User.FirstName
	driver.Driver.VerifiedIdentity = driverPunctualAvailabilitiesRequest.User.VerifiedIdentity
	driver.Driver.Gender = driverPunctualAvailabilitiesRequest.User.Gender
	driver.Preferences.Music = driverPunctualAvailabilitiesRequest.Preferences.Music
	driver.Preferences.Is_talker = driverPunctualAvailabilitiesRequest.Preferences.IsTalker
	driver.Preferences.Luggage_size = int64(driverPunctualAvailabilitiesRequest.Preferences.LuggageSize)
	driver.Preferences.Smoking = driverPunctualAvailabilitiesRequest.Preferences.Smoking
	driver.Preferences.Animals = driverPunctualAvailabilitiesRequest.Preferences.Animals

	driver.Driver_departure_address = &geojson.Feature{
		Type:     "Feature",
		Geometry: orb.Geometry(orb.Point{driverPunctualAvailabilitiesRequest.Latitude, driverPunctualAvailabilitiesRequest.Longitude}),
		Properties: geojson.Properties{
			"name": driverPunctualAvailabilitiesRequest.Address,
		},
	}
	driver.Radius = driverPunctualAvailabilitiesRequest.Radius
	driver.AvailabilitiesType = internal.Punctual
	for _, v := range driverPunctualAvailabilitiesRequest.Availabilities {
		driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{
			Date:      int64(v.Date),
			StartTime: v.StartTime,
			EndTime:   v.EndTime,
		})
	}
	driver.Car.Brand = driverPunctualAvailabilitiesRequest.Car.Brand
	driver.Car.Model = driverPunctualAvailabilitiesRequest.Car.Model
	err := s.storage.CreateDriver(driver)
	if err != nil {
		return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
	} else {
		return Response(201, "Punctual driver availabilities set successfully"), nil
	}
}

// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities
func (s *DriverAvailabilityAndScheduleAPIService) DriverRegularAvailabilitiesPost(ctx context.Context, driverRegularAvailabilitiesRequest DriverRegularAvailabilitiesRequest) (ImplResponse, error) {
	driver := internal.Driver{}
	driver.Driver.ID = driverRegularAvailabilitiesRequest.User.Id
	driver.Driver.Operator = driverRegularAvailabilitiesRequest.User.Operator
	driver.Driver.Alias = driverRegularAvailabilitiesRequest.User.Alias
	driver.Driver.Grade = int64(driverRegularAvailabilitiesRequest.User.Grade)
	driver.Driver.Picture = driverRegularAvailabilitiesRequest.User.Picture
	driver.Driver.LastName = driverRegularAvailabilitiesRequest.User.LastName
	driver.Driver.FirstName = driverRegularAvailabilitiesRequest.User.FirstName
	driver.Driver.VerifiedIdentity = driverRegularAvailabilitiesRequest.User.VerifiedIdentity
	driver.Driver.Gender = driverRegularAvailabilitiesRequest.User.Gender
	driver.Driver_departure_address = &geojson.Feature{
		Type:     "Feature",
		Geometry: orb.Geometry(orb.Point{driverRegularAvailabilitiesRequest.Latitude, driverRegularAvailabilitiesRequest.Longitude}),
		Properties: geojson.Properties{
			"name": driverRegularAvailabilitiesRequest.Address,
		},
	}
	driver.Preferences.Music = driverRegularAvailabilitiesRequest.Preferences.Music
	driver.Preferences.Is_talker = driverRegularAvailabilitiesRequest.Preferences.IsTalker
	driver.Preferences.Luggage_size = int64(driverRegularAvailabilitiesRequest.Preferences.LuggageSize)
	driver.Preferences.Smoking = driverRegularAvailabilitiesRequest.Preferences.Smoking
	driver.Preferences.Animals = driverRegularAvailabilitiesRequest.Preferences.Animals
	driver.Radius = driverRegularAvailabilitiesRequest.Radius
	driver.AvailabilitiesType = internal.Regular
	for _, v := range driverRegularAvailabilitiesRequest.Availabilities {
		driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{
			DayOfWeek: v.DayOfWeek,
			StartTime: v.StartTime,
			EndTime:   v.EndTime,
		})
	}
	driver.Car.Brand = driverRegularAvailabilitiesRequest.Car.Brand
	driver.Car.Model = driverRegularAvailabilitiesRequest.Car.Model
	err := s.storage.CreateDriver(driver)
	if err != nil {
		return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
	} else {
		return Response(201, "Regular driver availabilities set successfully"), nil
	}
}
