import {
  BookingPackageFlight
} from "@qite/tide-client/build/types";
import { Link, navigate } from "@reach/router";
import React, { useContext, useEffect } from "react";
import { useSelector } from "react-redux";
import { buildClassName } from "../../../shared/utils/class-util";
import SettingsContext from "../../settings-context";
import { useAppDispatch } from "../../store";
import {
  setCurrentStep,
  setPackage,
  setPackageRooms
} from "../booking/booking-slice";
import { FLIGHT_OPTIONS_FORM_STEP, OPTIONS_FORM_STEP } from "../booking/constants";
import {
  selectAccommodationViews,
  selectAvailabilities,
  selectBookingQueryString,
  selectIsFetchingProductOptions,
  selectPackageDetails,
  selectPackageRooms,
  selectTranslations
} from "../booking/selectors";
import { fetchPriceDetails } from "../price-details/price-details-slice";
import { buildSelectableRooms, updatePackageRooms } from "./room-utils";
import TravelerRooms from "./traveler-rooms";

interface RoomOptionsFormProps { }

const RoomOptionsForm: React.FC<RoomOptionsFormProps> = () => {
  const settings = useContext(SettingsContext);

  const translations = useSelector(selectTranslations);
  const dispatch = useAppDispatch();
  const packageDetails = useSelector(selectPackageDetails);
  const packageRooms = useSelector(selectPackageRooms);
  const availabilities = useSelector(selectAvailabilities);
  const bookingQueryString = useSelector(selectBookingQueryString);
  const accommodationViews = useSelector(selectAccommodationViews);
  const isLoading = useSelector(selectIsFetchingProductOptions);

  const rooms = buildSelectableRooms(packageRooms!, settings.accommodations, settings.regimes, accommodationViews);

  const goPrevious = () => {
    dispatch(setCurrentStep(FLIGHT_OPTIONS_FORM_STEP));
  };

  const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
    if (settings.skipRouter) {
      dispatch(setCurrentStep(OPTIONS_FORM_STEP));
    } else {
      navigate(`${settings.basePath}${settings.options.pathSuffix}?${bookingQueryString}`);
    }

    e.preventDefault();
  };

  const handleOnRoomChange = (
    index: number,
    accommodationCode: string,
    regimeCode: string | null
  ) => {
    if (!packageRooms) return;

    const updatedPackageRooms = updatePackageRooms(packageRooms, index, accommodationCode, regimeCode, availabilities!);

    dispatch(setPackageRooms(updatedPackageRooms));
    dispatch(fetchPriceDetails());
  };

  useEffect(() => {
    if (packageDetails) {
      const params = new URLSearchParams(location.search);

      const outwardFlight = params.get("outwardflight") ?? undefined;
      const returnFlight = params.get("returnflight") ?? undefined;

      if (outwardFlight && returnFlight) {
        const desiredOutwardFlight = packageDetails.outwardFlights.find(
          (x) => x.entryLineGuid == outwardFlight
        );
        const desiredReturnFlight = packageDetails.returnFlights.find(
          (x) => x.entryLineGuid == returnFlight
        );

        if (desiredOutwardFlight && desiredReturnFlight) {
          dispatch(
            setPackage({
              ...packageDetails,
              outwardFlights: packageDetails.outwardFlights.map((flight) => {
                return {
                  ...flight,
                  isSelected:
                    flight.entryLineGuid == desiredOutwardFlight.entryLineGuid
                      ? true
                      : false,
                } as BookingPackageFlight;
              }),
              returnFlights: packageDetails.returnFlights.map((flight) => {
                return {
                  ...flight,
                  isSelected:
                    flight.entryLineGuid == desiredReturnFlight.entryLineGuid
                      ? true
                      : false,
                } as BookingPackageFlight;
              }),
            })
          );
        }
      }
    }
    dispatch(fetchPriceDetails());
  }, []);

  return (
    <>
      <form
        className="form"
        name="booking--options"
        id="booking--options"
        noValidate
        onSubmit={handleSubmit}
      >
        <div className="form__wrapper">
          {rooms.map(room => (
            <TravelerRooms
              key={room.index}
              index={room.index}
              room={room}
              onRoomChange={handleOnRoomChange} />
          ))}
        </div>
        <div className="booking__navigator">
          {!settings.flightOptions.isHidden && (
            <>
              {settings.skipRouter ? (
                <button
                  type="button"
                  title={translations.STEPS.PREVIOUS}
                  onClick={() => goPrevious()}
                  className="cta cta--secondary"
                >
                  {translations.STEPS.PREVIOUS}
                </button>
              ) : (
                <Link
                  to={`${settings.basePath}${settings.flightOptions.pathSuffix}?${bookingQueryString}`}
                  title={translations.STEPS.PREVIOUS}
                  className="cta cta--secondary"
                >
                  {translations.STEPS.PREVIOUS}
                </Link>
              )}
            </>
          )}
          <button
            type="submit"
            title={translations.STEPS.NEXT}
            disabled={isLoading}
            className={buildClassName(["cta", isLoading && "cta--disabled"])}
          >
            {translations.STEPS.NEXT}
          </button>
        </div>
      </form>
    </>
  );
};

export default RoomOptionsForm;
