import { BookingOptionPax, BookingPackagePax, BookingPackageRoom } from '@qite/tide-client/build/types';
import { ServiceType } from '@qite/tide-client';
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 { selectCurrencyCode, 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;
  includedServiceTypes?: number[];
}

const OptionRoom: React.FC<OptionRoomProps> = ({ packageRoom, pax, optionPax, onRoomChange, includedServiceTypes }) => {
  const selectedOption = packageRoom?.options.find((x) => x.isSelected);
  const translations = useSelector(selectTranslations);
  const currencyCode = useSelector(selectCurrencyCode);

  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(translations, selectedOption.from, selectedOption.to) ?? '';

      const productAttributes = useSelector(selectProductAttributes);
      productName = productAttributes?.productName ?? '';
    }
  }

  const isFlightOnly = includedServiceTypes?.length === 1 && includedServiceTypes.includes(ServiceType.flight);

  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), currencyCode)}` : `- ${formatPrice(Math.abs(price), currencyCode)}`;
  };

  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>
                      {!isFlightOnly && <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;
