import {
  BookingOptionPax,
  BookingPackagePax,
  BookingPackageRoom,
} from "@qite/tide-client/build/types";
import { compact, first, sortBy, uniqBy } from "lodash";
import React from "react";
import { useSelector } from "react-redux";
import { buildClassName } from "../../../shared/utils/class-util";
import { formatPrice } from "../../../shared/utils/localization-util";
import { selectProductAttributes, selectTranslations } from "../booking/selectors";
import { getDatePeriodText, getDateText } from "../sidebar/sidebar-util";

interface OptionRoomProps {
  packageRoom: BookingPackageRoom;
  pax: BookingPackagePax[];
  optionPax?: BookingOptionPax[];
  onRoomChange: (
    index: number,
    accommodationCode: string,
    regimeCode: string | null
  ) => void;
}

const OptionRoom: React.FC<OptionRoomProps> = ({
  packageRoom,
  pax,
  optionPax,
  onRoomChange,
}) => {
  const selectedOption = packageRoom?.options.find((x) => x.isSelected);
  const translations = useSelector(selectTranslations);  

  let daysAndNightsText = "";
  let startDate = "";
  let endDate = "";
  let productName = "";

  if (packageRoom.index === 0) {
    const selectedOption = packageRoom.options.find((x) => x.isSelected);

    if (selectedOption) {
      startDate = getDateText(selectedOption.from, true) ?? "";
      endDate = getDateText(selectedOption.to, true) ?? "";
      daysAndNightsText =
        getDatePeriodText(selectedOption.from, selectedOption.to) ?? "";

      const productAttributes = useSelector(selectProductAttributes);
      productName = productAttributes?.productName ?? "";
    }
  }

  const accommodations = uniqBy(
    compact(
      packageRoom &&
        packageRoom.options
        .filter(x => x.accommodationCode && !x.isLocked)
        .map((option) => {
          return {
            accommodationCode: option.accommodationCode,
            accommodationName: option.accommodationName,
          };
        })
    ),
    "accommodationCode"
  );

  const regimes = uniqBy(
    compact(
      packageRoom &&
        packageRoom.options
            .filter(x => !selectedOption || x.accommodationCode == selectedOption.accommodationCode)
            .map((option) => {
                return {
                    regimeCode: option.regimeCode,
                    regimeName: option.regimeName,
                };
            })
    ),
    "regimeCode"
  );

  const handleAccommodationChange: React.FormEventHandler<HTMLSelectElement> = (
    e
  ) => {
    const accommodationCode = e.currentTarget.value;
    var accommodationOptions = packageRoom?.options.filter(
      (x) => x.accommodationCode == accommodationCode
    );

    if (accommodationOptions) {
      const option =
        accommodationOptions.find(
          (x) => x.regimeCode == selectedOption?.regimeCode
        ) ?? accommodationOptions[0];

      if (option) {
        onRoomChange(
          packageRoom.index,
          option.accommodationCode,
          option.regimeCode
        );
      }
    }

    e.preventDefault();
  };

  const handleRegimeChange: React.FormEventHandler<HTMLSelectElement> = (e) => {
    const regime = regimes.find((x) => x.regimeCode == e.currentTarget.value);

    if (selectedOption) {
      onRoomChange(
        packageRoom.index,
        selectedOption.accommodationCode,
        regime ? regime.regimeCode : null
      );
    }

    e.preventDefault();
  };

  const getPriceDifferenceText = (price: number) => {
    return price > 0
      ? `+ ${formatPrice(Math.abs(price))}`
      : `- ${formatPrice(Math.abs(price))}`;
  };

  const getAccommodationPriceDifference = (accommodation: {
    accommodationCode: string;
    accommodationName: string;
  }) => {
    const selectedOption = packageRoom.options.find((x) => x.isSelected);
    if (selectedOption?.accommodationCode === accommodation.accommodationCode)
      return "";

    var currentPrice = selectedOption?.price;
    var accommodationPrice = first(
      sortBy(
        packageRoom.options.filter(
          (x) =>
            x.regimeCode === selectedOption?.regimeCode &&
            x.accommodationCode === accommodation.accommodationCode
        ),
        (x) => x.price
      )
    )?.price;

    var priceDifference = (accommodationPrice ?? 0) - (currentPrice ?? 0);
    if (priceDifference !== 0) {
      return `(${getPriceDifferenceText(priceDifference)})`;
    } else {
      return "";
    }
  };

  const getRegimePriceDifference = (regime: {
    regimeCode: string;
    regimeName: string;
  }) => {
    const selectedOption = packageRoom.options.find((x) => x.isSelected);
    if (selectedOption?.regimeCode === regime.regimeCode) return "";

    var currentPrice = selectedOption?.price;
    var regimePrice = packageRoom.options.find(
      (x) =>
        x.accommodationCode === selectedOption?.accommodationCode &&
        x.regimeCode === regime.regimeCode
    )?.price;

    var priceDifference = (regimePrice ?? 0) - (currentPrice ?? 0);
    if (priceDifference !== 0) {
      return `(${getPriceDifferenceText(priceDifference)})`;
    } else {
      return "";
    }
  };

  const getPaxName = (id: number) => {
    const item = pax.find((x) => x.id === id);
    if (!item?.firstName && !item?.lastName) {
      const optionPaxItem = optionPax?.find((x) => x.id === id);
      return optionPaxItem?.paxName;
    }
    return `${item?.firstName} ${item?.lastName[0]}`;
  };

  return (
    <tr>
      <td>
        <div className="tree">
          <div className="tree__level">
            <div className="tree__header">
              <div className="tree__description-collapse">
                <div
                  className={buildClassName([
                    "radiobutton",
                    "radiobutton--label",
                    "radiobutton--package-label",
                  ])}
                >
                  <div className="radiobutton__label">
                    <span
                      className={buildClassName([
                        "radiobutton__input",
                        "radiobutton__input--parent",
                      ])}
                    ></span>
                    <span className="radiobutton__label-text">
                      <div className="date-list">
                        {startDate && endDate && (
                          <>
                            <span className="date-list__item">{startDate}</span>
                            <span className="date-list__item">{endDate}</span>
                          </>
                        )}
                      </div>
                      <p>{daysAndNightsText}</p>
                    </span>
                    <div className="tree__columns-actions">
                      <div className="tree__columns">
                        <div className="tree__column">
                          <span className="tree__product-name">
                            {productName}
                          </span>
                        </div>
                        <div className="tree__column">
                          <span className="tree__package-label">
                            {translations.OPTIONS_FORM.UNIT_TITLE}{" "}
                            {packageRoom.index + 1}:{" "}
                            <span className="tree__package-label-pax">
                              {pax.map((p, i) => (
                                <span
                                  key={i}
                                  title={`${p.firstName} ${p.lastName}`}
                                >
                                  {i > 0 && ", "} {getPaxName(p.id)}
                                </span>
                              ))}
                            </span>
                          </span>
                          <div className="select-wrapper">
                            <div className="select-wrapper__select">
                              <select
                                defaultValue={selectedOption?.accommodationCode}
                                onChange={handleAccommodationChange}
                              >
                                {accommodations.map((accommodation) => (
                                  <option
                                    key={accommodation.accommodationCode}
                                    value={accommodation.accommodationCode}
                                  >
                                    {accommodation.accommodationName}{" "}
                                    {getAccommodationPriceDifference(
                                      accommodation
                                    )}
                                  </option>
                                ))}
                              </select>
                            </div>
                          </div>
                        </div>
                        <div className="tree__column">
                          <div className="select-wrapper">
                            {regimes.length > 1 && (
                              <div className="select-wrapper__select">
                                <select
                                  defaultValue={selectedOption?.regimeCode}
                                  onChange={handleRegimeChange}
                                >
                                  {regimes.map((regime) => (
                                    <option
                                      key={regime.regimeCode}
                                      value={regime.regimeCode}
                                    >
                                      {regime.regimeName}{" "}
                                      {getRegimePriceDifference(regime)}
                                    </option>
                                  ))}
                                </select>
                              </div>
                            )}
                            {regimes.length === 1 && (
                              <>
                                {
                                  regimes.find(
                                    (x) =>
                                      x.regimeCode == selectedOption?.regimeCode
                                  )?.regimeName
                                }
                              </>
                            )}
                          </div>
                        </div>
                        <div
                          className={buildClassName([
                            "tree__column",
                            "tree__column--price",
                          ])}
                        ></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </td>
    </tr>
  );
};

export default OptionRoom;
