using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using SepehrHotelApiSampleClient.Booking.Book.WebApi;
using SepehrHotelApiSampleClient.Booking.Book.WinForms.InMemoryDatabase.BookedPnrs.Repository;
using SepehrHotelApiSampleClient.Booking.Book.WinForms.InMemoryDatabase.FailedRequests.Model;
using SepehrHotelApiSampleClient.Booking.Book.WinForms.InMemoryDatabase.FailedRequests.Repository;
using SepehrHotelApiSampleClient.Booking.Book.WinForms.PassengerUserControls;
using SepehrHotelApiSampleClient.BuiltinTypeExtensions;
using BookRequestModel = Sepehr.ApiGateway.Partners.Contracts.Hotel.Booking.V5.Book.RequestModel;
// ReSharper disable InconsistentNaming

namespace SepehrHotelApiSampleClient.Booking.Book.WinForms
{
    public partial class BookForm : Form
    {
        private readonly MainForm _mainForm;
        private readonly BookCommand.Command _command;

        public BookForm(
            MainForm mainForm,
            BookCommand.Command command)
        {
            _mainForm = mainForm;
            _command = command;
            
            InitializeComponent();

            SyncSelectedHotel();

            cmbIncomingTransferType.SelectedIndex = 0;
            cmbOutgoingTransferType.SelectedIndex = 0;
        }

        private void SyncSelectedHotel()
        {
            txtBookYourLocalInventoryPnr.Text = Guid.NewGuid().ToString();
            txtTotalNetPrice.Text = _command.TotalNetPrice_TaxIncluded.ToString(CultureInfo.InvariantCulture);
            lblHotelName.Text = _command.HotelName;
            lblCheckin.Text = _command.CheckinDate.ToString("yyyy-MM-dd");
            lblCheckout.Text = _command.CheckoutDate.ToString("yyyy-MM-dd");


            roomsPanel.Controls.Clear();

            for (var roomIndex = _command.RoomList.Count - 1; roomIndex >= 0; roomIndex--)
            {
                var room = _command.RoomList[roomIndex];

                var roomUserControl = new RoomUserControl();
                roomUserControl.Dock = DockStyle.Top;
                roomUserControl.lblRoomNumber.Text = $"Room {roomIndex + 1} - {room.RoomTypeName} {room.BoardTypeCode}";
                roomsPanel.Controls.Add(roomUserControl);

                foreach (var childAge in room.ChildAgeList)
                {
                    var childUserControl = new ChildUserControl(
                        childAge,
                        _command.CheckinDate);
                    childUserControl.Dock = DockStyle.Top;
                    roomUserControl.passengersPanel.Controls.Add(childUserControl);
                }

                for (int counter = 0; counter < room.AdultCount; counter++)
                {
                    var adultUserControl = new AdultUserControl();
                    adultUserControl.Dock = DockStyle.Top;
                    roomUserControl.passengersPanel.Controls.Add(adultUserControl);
                }
            }
        }

        private void btnBook_Click(object sender, EventArgs e)
        {
            var request = new BookRequestModel.Request
            {
                Username = _mainForm.txtUsername.Text,
                Password = _mainForm.txtPassword.Text,
                LockId = _command.LockId,
                YourLocalInventoryPnr = txtBookYourLocalInventoryPnr.Text,
                MobileNumber = txtBookMobileNumber.Text,
                Email = txtBookEmail.Text,
                Remarks = string.Empty,
                RoomList = GetRequestRoomList(),
                TotalPayable = decimal.Parse(txtTotalNetPrice.Text, CultureInfo.InvariantCulture),
                IncomingTransfer = GetIncomingTransfer(),
                OutgoingTransfer = GetOutgoingTransfer(),
            };

            try
            {
                var response = BookApi.Post(_mainForm.txtUrl.Text, request);

                var repositoryModel = ApiResponseModelToRepositoryModelConvertor.Convert(
                    response,
                    txtBookYourLocalInventoryPnr.Text);
                BookedPnrRepository.Add(repositoryModel);

                var bookResponseForm = new BookResponseForm();
                bookResponseForm.txtResponse.Text = response.SerializeToJsonWithFormatIndented();
                bookResponseForm.Show();
            }
            catch
            {
                FailedRequestRepository.Add(new FailedRequest
                {
                    Pnr = txtBookYourLocalInventoryPnr.Text,
                });
                throw;
            }
        }

        private BookRequestModel.Transfer.Incoming.IncomingTransfer GetIncomingTransfer()
        {
            if (cmbIncomingTransferType.SelectedIndex == 1)
            {
                var flightUserControl = (TransferUserControls.Incoming.FlightUserControl)incomingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Incoming.IncomingTransfer
                {
                    FlightTransfer = new BookRequestModel.Transfer.Incoming.FlightTransfer
                    {
                        FlightNumber = flightUserControl.txtFlightNumber.Text,
                        DepartureTime = flightUserControl.txtDepartureTime.Text,
                        OriginCity = flightUserControl.txtOriginCity.Text,
                        AirlineName = flightUserControl.txtAirlineName.Text,
                    }
                };
            }
            else if (cmbIncomingTransferType.SelectedIndex == 2)
            {
                var trainUserControl = (TransferUserControls.Incoming.TrainUserControl)incomingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Incoming.IncomingTransfer
                {
                    TrainTransfer = new BookRequestModel.Transfer.Incoming.TrainTransfer
                    {
                        TrainNumber = trainUserControl.txtTrainNumber.Text,
                        ArrivalTime = trainUserControl.txtArrivalTime.Text,
                        OriginCity = trainUserControl.txtOriginCity.Text,
                        CarrierName = trainUserControl.txtCarrierName.Text,
                    }
                };
            }
            else if (cmbIncomingTransferType.SelectedIndex == 3)
            {
                var busUserControl = (TransferUserControls.Incoming.BusUserControl)incomingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Incoming.IncomingTransfer
                {
                    BusTransfer = new BookRequestModel.Transfer.Incoming.BusTransfer
                    {
                        Terminal = busUserControl.txtTerminal.Text,
                        ArrivalTime = busUserControl.txtArrivalTime.Text,
                        OriginCity = busUserControl.txtOriginCity.Text,
                        CarrierName = busUserControl.txtCarrierName.Text,
                    }
                };
            }

            return null;
        }

        private BookRequestModel.Transfer.Outgoing.OutgoingTransfer GetOutgoingTransfer()
        {
            if (cmbOutgoingTransferType.SelectedIndex == 1)
            {
                var flightUserControl = (TransferUserControls.Outgoing.FlightUserControl)outgoingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Outgoing.OutgoingTransfer
                {
                    FlightTransfer = new BookRequestModel.Transfer.Outgoing.FlightTransfer
                    {
                        FlightNumber = flightUserControl.txtFlightNumber.Text,
                        DepartureTime = flightUserControl.txtDepartureTime.Text,
                    }
                };
            }
            else if (cmbOutgoingTransferType.SelectedIndex == 2)
            {
                var trainUserControl = (TransferUserControls.Outgoing.TrainUserControl)outgoingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Outgoing.OutgoingTransfer
                {
                    TrainTransfer = new BookRequestModel.Transfer.Outgoing.TrainTransfer
                    {
                        TrainNumber = trainUserControl.txtTrainNumber.Text,
                        DepartureTime = trainUserControl.txtDepartureTime.Text,
                    }
                };
            }
            else if (cmbOutgoingTransferType.SelectedIndex == 3)
            {
                var busUserControl = (TransferUserControls.Outgoing.BusUserControl)outgoingTransferPanel.Controls[0];

                return new BookRequestModel.Transfer.Outgoing.OutgoingTransfer
                {
                    BusTransfer = new BookRequestModel.Transfer.Outgoing.BusTransfer
                    {
                        Terminal = busUserControl.txtTerminal.Text,
                        DepartureTime = busUserControl.txtDepartureTime.Text,
                    }
                };
            }

            return null;
        }

        private List<BookRequestModel.Room> GetRequestRoomList()
        {
            var result = new List<BookRequestModel.Room>();

            for (var roomIndex = roomsPanel.Controls.Count - 1; roomIndex >= 0; roomIndex--)
            {
                var roomUserControl = (RoomUserControl)roomsPanel.Controls[roomIndex];

                var requestAdultList = new List<BookRequestModel.Guest>();
                for (
                    var index = roomUserControl.passengersPanel.Controls.Count - 1; 
                    index >= 0; 
                    index--
                    )
                {
                    var passengerUserControl = roomUserControl.passengersPanel.Controls[index];
                    var adultUserControl = passengerUserControl as AdultUserControl;
                    if (adultUserControl != null)
                    {
                        requestAdultList.Add(adultUserControl.GetGuestInfo());
                    }
                }

                var requestChildList = new List<BookRequestModel.Guest>();
                for (
                    var index = roomUserControl.passengersPanel.Controls.Count - 1;
                    index >= 0;
                    index--
                )
                {
                    var passengerUserControl = roomUserControl.passengersPanel.Controls[index];
                    var childUserControl = passengerUserControl as ChildUserControl;
                    if (childUserControl != null)
                    {
                        requestChildList.Add(childUserControl.GetGuestInfo());
                    }
                }

                result.Add(new BookRequestModel.Room
                {
                    AdultGuestList = requestAdultList,
                    ChildGuestList = requestChildList,
                });
            }

            return result;
        }

        private void cmbIncomingTransferType_SelectedIndexChanged(object sender, EventArgs e)
        {
            incomingTransferPanel.Controls.Clear();

            if (cmbIncomingTransferType.SelectedIndex == 1)
            {
                var flightUserControl = new TransferUserControls.Incoming.FlightUserControl();
                flightUserControl.Dock = DockStyle.Top;
                incomingTransferPanel.Controls.Add(flightUserControl);
            }
            else if (cmbIncomingTransferType.SelectedIndex == 2)
            {
                var trainUserControl = new TransferUserControls.Incoming.TrainUserControl();
                trainUserControl.Dock = DockStyle.Top;
                incomingTransferPanel.Controls.Add(trainUserControl);
            }
            else if (cmbIncomingTransferType.SelectedIndex == 3)
            {
                var busUserControl = new TransferUserControls.Incoming.BusUserControl();
                busUserControl.Dock = DockStyle.Top;
                incomingTransferPanel.Controls.Add(busUserControl);
            }
        }

        private void cmbOutgoingTransferType_SelectedIndexChanged(object sender, EventArgs e)
        {
            outgoingTransferPanel.Controls.Clear();

            if (cmbOutgoingTransferType.SelectedIndex == 1)
            {
                var flightUserControl = new TransferUserControls.Outgoing.FlightUserControl();
                flightUserControl.Dock = DockStyle.Top;
                outgoingTransferPanel.Controls.Add(flightUserControl);
            }
            else if (cmbOutgoingTransferType.SelectedIndex == 2)
            {
                var trainUserControl = new TransferUserControls.Outgoing.TrainUserControl();
                trainUserControl.Dock = DockStyle.Top;
                outgoingTransferPanel.Controls.Add(trainUserControl);
            }
            else if (cmbOutgoingTransferType.SelectedIndex == 3)
            {
                var busUserControl = new TransferUserControls.Outgoing.BusUserControl();
                busUserControl.Dock = DockStyle.Top;
                outgoingTransferPanel.Controls.Add(busUserControl);
            }
        }
    }
}
