using SepehrFlightApiSampleClient.Availability.WinForms.SearchByRouteAndDate.ViewModels;

namespace SepehrFlightApiSampleClient.Booking.WinForms.Book.BookCommand.Factory
{
    public class FactoryBasedOnSearchByRouteAndDateResult
    {
        public static Command Create(
            Flight selectedDepartureFlight,
            FlightClass selectedDepartureFlightClass,
            int? departureLockId,
            Flight selectedReturningFlight,
            FlightClass selectedReturningFlightClass,
            int? returningLockId)
        {
            var isJourneyRoundtrip = GetIsJourneyRoundtrip(
                selectedDepartureFlight, 
                selectedReturningFlight);

            var journeyOriginIataCode = selectedDepartureFlight.Origin;

            bool isSupplierSameOnDepartureAndReturningFlight = 
                GetIsSupplierSameOnDepartureAndReturningFlight(
                    selectedDepartureFlight, 
                    selectedReturningFlight);

            var command = new Command
            {
                Departure = Convert(
                    selectedDepartureFlight, 
                    selectedDepartureFlightClass,
                    departureLockId,
                    isJourneyRoundtrip,
                    journeyOriginIataCode,
                    isSupplierSameOnDepartureAndReturningFlight),
                Returning = Convert(
                    selectedReturningFlight, 
                    selectedReturningFlightClass,
                    returningLockId,
                    isJourneyRoundtrip,
                    journeyOriginIataCode,
                    isSupplierSameOnDepartureAndReturningFlight),
            };

            return command;
        }

        private static bool GetIsSupplierSameOnDepartureAndReturningFlight(
            Flight selectedDepartureFlight, 
            Flight selectedReturningFlight)
        {
            return selectedDepartureFlight?.SupplierId == selectedReturningFlight?.SupplierId;
        }

        private static bool GetIsJourneyRoundtrip(
            Flight selectedDepartureFlight, 
            Flight selectedReturningFlight)
        {
            return 
                selectedDepartureFlight != null 
                && 
                selectedReturningFlight != null;
        }

        private static FlightSegment Convert(
            Flight selectedFlight,
            FlightClass selectedFlightClass,
            int? lockId,
            bool isJourneyRoundtrip,
            string journeyOriginIataCode,
            bool isSupplierSameOnDepartureAndReturningFlight)
        {
            if (selectedFlight == null) return null;

            if (selectedFlight.SupplierId == null)
            {
                return new FlightSegment
                {
                    FlightNumber = selectedFlight.FlightNumber,
                    DepartureDateTime = selectedFlight.DepartureDateTime,
                    OriginIataCode = selectedFlight.Origin,
                    DestinationIataCode = selectedFlight.Destination,
                    FareName = selectedFlightClass.FareName,
                    AdultPayable = selectedFlightClass.CharterFare.Adult_Fare.Payable,
                    ChildPayable = selectedFlightClass.CharterFare.Child_Fare.Payable,
                    InfantPayable = selectedFlightClass.CharterFare.Infant_Fare.Payable,
                    LockId = lockId,
                };
            }

            var commandFlightSegment = new FlightSegment
            {
                FlightNumber = selectedFlight.FlightNumber,
                DepartureDateTime = selectedFlight.DepartureDateTime,
                OriginIataCode = selectedFlight.Origin,
                DestinationIataCode = selectedFlight.Destination,
                FareName = selectedFlightClass.FareName,
                LockId = lockId,
            };

            if (
                isJourneyRoundtrip
                &&
                //check if supplier of departure and returning flight are same.
                //because we cannot book roundtrip fares on different suppliers.
                isSupplierSameOnDepartureAndReturningFlight
                &&
                // check if roudtrip fare is available on selected class
                selectedFlightClass.WebserviceFare.RoundtripFare_FromOrigin != null
            )
            {
                if (journeyOriginIataCode == selectedFlight.Origin)
                {
                    commandFlightSegment.AdultPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromOrigin.Adult_Fare.Payable;
                    commandFlightSegment.ChildPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromOrigin.Child_Fare.Payable;
                    commandFlightSegment.InfantPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromOrigin.Infant_Fare.Payable;
                }
                else
                {
                    commandFlightSegment.AdultPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromDestination.Adult_Fare.Payable;
                    commandFlightSegment.ChildPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromDestination.Child_Fare.Payable;
                    commandFlightSegment.InfantPayable = selectedFlightClass.WebserviceFare.RoundtripFare_FromDestination.Infant_Fare.Payable;
                }
            }
            else
            {
                commandFlightSegment.AdultPayable = selectedFlightClass.WebserviceFare.OnewayFare.Adult_Fare.Payable;
                commandFlightSegment.ChildPayable = selectedFlightClass.WebserviceFare.OnewayFare.Child_Fare.Payable;
                commandFlightSegment.InfantPayable = selectedFlightClass.WebserviceFare.OnewayFare.Infant_Fare.Payable;
            }

            return commandFlightSegment;
        }
    }
}
