import React, { useContext, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import ItemPicker from '../../../qsm/components/item-picker';
import { SearchResultsRootState } from '../../../search-results/store/search-results-store';
import SearchResultsConfigurationContext from '../../../search-results/search-results-configuration-context';
import { getTranslations } from '../../utils/localization-util';
import { setPackagingAccoSearchDetails } from '../../../search-results/store/search-results-slice';
import { PackageMainRoom, PortalQsmType } from '@qite/tide-client';
import { PickerItem } from '../../types';
import { first } from 'lodash';
import Spinner from '../../../search-results/components/spinner/spinner';

type AccommodationFlyInProps = {
  isLoading: boolean;
  handleConfirm: () => void;
};

type PackagingAccommodationResponse = {
  code: string;
  name: string;
  price: number;
  currencyCode: string;
  rooms: PackageMainRoom[];
};

type GroupedAccommodation = {
  accommodationCode: string;
  accommodationName: string;
  regimes: PickerItem[];
};

const formatPrice = (price?: number, currencyCode?: string | null) => {
  if (typeof price !== 'number') return '';

  const safeCurrency = currencyCode ?? 'EUR';

  return new Intl.NumberFormat('nl-BE', {
    style: 'currency',
    currency: safeCurrency
  }).format(price);
};

const AccommodationFlyIn: React.FC<AccommodationFlyInProps> = ({ isLoading, handleConfirm }) => {
  const dispatch = useDispatch();
  const context = useContext(SearchResultsConfigurationContext);
  const language = context?.languageCode ?? 'en-GB';
  const translations = getTranslations(language);

  if (isLoading) {
    return <>{context?.customSpinner ?? <Spinner label={translations.SRP.LOADING_ACCOMMODATIONS} />}</>;
  }

  const { packagingAccoSearchDetails, selectedPackagingAccoResultCode } = useSelector((state: SearchResultsRootState) => state.searchResults);

  const selectedPackagingAccoSearchDetails = useMemo<PackagingAccommodationResponse | undefined>(() => {
    return packagingAccoSearchDetails?.find((x) => x.code === selectedPackagingAccoResultCode);
  }, [packagingAccoSearchDetails, selectedPackagingAccoResultCode]);

  const groupedRooms = useMemo(() => {
    if (!selectedPackagingAccoSearchDetails?.rooms) return [];

    return selectedPackagingAccoSearchDetails.rooms.map((room) => {
      const groupedMap = new Map<string, GroupedAccommodation>();

      room.options.forEach((option) => {
        const key = option.accommodationCode;

        if (!groupedMap.has(key)) {
          groupedMap.set(key, {
            accommodationCode: option.accommodationCode,
            accommodationName: option.accommodationName,
            regimes: []
          });
        }

        groupedMap.get(key)?.regimes.push({
          id: option.guid,
          label: option.regimeName
        });
      });

      return Array.from(groupedMap.values());
    });
  }, [selectedPackagingAccoSearchDetails]);

  const getSelectedOptionForRoom = (roomIndex: number) => {
    return selectedPackagingAccoSearchDetails?.rooms?.[roomIndex]?.options?.find((option) => option.isSelected);
  };

  const getSelectedOptionForAccommodation = (roomIndex: number, accommodationCode: string) => {
    return selectedPackagingAccoSearchDetails?.rooms?.[roomIndex]?.options?.find(
      (option) => option.accommodationCode === accommodationCode && option.isSelected
    );
  };

  const handlePick = (roomIndex: number, selectedGuid?: string) => {
    if (!packagingAccoSearchDetails || !selectedPackagingAccoSearchDetails) return;

    const updatedPackagingAccoSearchDetails = packagingAccoSearchDetails.map((product) => {
      if (product.code !== selectedPackagingAccoSearchDetails.code) {
        return product;
      }

      const updatedRooms = product.rooms.map((room, currentRoomIndex) => {
        if (currentRoomIndex !== roomIndex) {
          return room;
        }

        return {
          ...room,
          options: room.options.map((option) => ({
            ...option,
            isSelected: option.guid === selectedGuid
          }))
        };
      });

      return {
        ...product,
        rooms: updatedRooms
      };
    });

    dispatch(setPackagingAccoSearchDetails(updatedPackagingAccoSearchDetails));
  };

  if (!selectedPackagingAccoSearchDetails) {
    return null;
  }

  const calculateTotalPrice = () => {
    const selectedOptions = selectedPackagingAccoSearchDetails.rooms.flatMap((room) => room.options.filter((option) => option.isSelected));
    const totalPrice = selectedOptions.reduce((total, option) => total + (option.price || 0), 0);
    return formatPrice(totalPrice, selectedPackagingAccoSearchDetails.currencyCode);
  };

  const getPriceDifference = (currentSelectedPrice: number | undefined, roomIndex: number, accommodationCode: string, regimeId?: string) => {
    let targetPrice = 0;

    const selectedOption = getSelectedOptionForAccommodation(roomIndex, accommodationCode);

    if (selectedOption?.price) {
      targetPrice = selectedOption.price;
    } else {
      const firstOption = selectedPackagingAccoSearchDetails.rooms[roomIndex].options.find((option) => option.accommodationCode === accommodationCode);
      targetPrice = firstOption?.price || 0;
    }

    if (regimeId) {
      const regimeOption = selectedPackagingAccoSearchDetails.rooms[roomIndex].options.find((option) => option.guid === regimeId);
      targetPrice = regimeOption?.price || 0;
    }

    return targetPrice - (currentSelectedPrice || 0);
  };

  const formatPriceDifference = (difference: number, currencyCode: string) => {
    if (difference === 0) {
      return null;
    }

    const formattedAbsoluteValue = formatPrice(Math.abs(difference), currencyCode);
    return `${difference > 0 ? '+' : '-'} ${formattedAbsoluteValue}`;
  };

  const getPriceDifferenceClassName = (difference: number) => {
    if (difference < 0) {
      return 'flyin__acco__price flyin__acco__price--decrease';
    }

    if (difference > 0) {
      return 'flyin__acco__price flyin__acco__price--increase';
    }

    return 'flyin__acco__price';
  };

  const regimeFormatter = (roomIndex: number, accommodation: GroupedAccommodation, regimeId: string, label: string) => {
    const roomOption = getSelectedOptionForRoom(roomIndex);

    const difference = getPriceDifference(roomOption?.price, roomIndex, accommodation.accommodationCode, regimeId);

    return `${label} ${difference !== 0 ? `(${formatPriceDifference(difference, selectedPackagingAccoSearchDetails.currencyCode)})` : ''}`;
  };

  return (
    <>
      <div className="flyin__content">
        {groupedRooms.map((roomAccommodations, roomIndex) => {
          const selectedRoomOption = getSelectedOptionForRoom(roomIndex);

          return (
            <div className="flyin__acco" key={`room-${roomIndex}`}>
              <h3 className="flyin__acco__room-title">Room {roomIndex + 1}</h3>
              <div className="flyin__acco__cards">
                {roomAccommodations.map((accommodation) => {
                  const selectedOption = getSelectedOptionForAccommodation(roomIndex, accommodation.accommodationCode);

                  const priceDifference = getPriceDifference(selectedRoomOption?.price, roomIndex, accommodation.accommodationCode);
                  return (
                    <div className="flyin__acco__card" key={`${roomIndex}-${accommodation.accommodationCode}`}>
                      <div className="flyin__acco__content">
                        <h4 className="flyin__acco__title">{accommodation.accommodationName}</h4>
                      </div>

                      <div className="flyin__acco__footer">
                        <ItemPicker
                          items={accommodation.regimes}
                          selection={selectedOption?.regimeName}
                          label={''}
                          placeholder={'Select regime'}
                          classModifier=""
                          onPick={(selected, selectedGuid) => handlePick(roomIndex, selectedGuid)}
                          valueFormatter={(id, label) => regimeFormatter(roomIndex, accommodation, id, label)}
                        />

                        <div className="flyin__acco__footer__actions">
                          <button
                            className={
                              selectedRoomOption?.accommodationCode == accommodation.accommodationCode ? 'cta cta--select cta--selected' : 'cta cta--select'
                            }
                            onClick={() => {
                              handlePick(roomIndex, selectedOption ? selectedOption.guid : first(accommodation.regimes)?.id);
                            }}>
                            {selectedRoomOption?.accommodationCode == accommodation.accommodationCode
                              ? translations?.SHARED.SELECTED
                              : translations?.SHARED.SELECT}
                          </button>

                          <div className="flyin__acco__price__wrapper">
                            <span className={getPriceDifferenceClassName(priceDifference)}>
                              {formatPriceDifference(priceDifference, selectedPackagingAccoSearchDetails.currencyCode)}
                            </span>
                          </div>
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>

      <div className="flyin__footer">
        <div className="flyin__footer__price">
          {translations.SHARED.TOTAL_PRICE}: {calculateTotalPrice()}
        </div>

        <div className="flyin__button-wrapper">
          <button className="cta cta--select" onClick={handleConfirm}>
            {context?.searchConfiguration.qsmType == PortalQsmType.AccommodationAndFlight ? translations.QSM.CONFIRM : translations.PRODUCT.BOOK_NOW}
          </button>
        </div>
      </div>
    </>
    // Slicing with image and usps, not available in the current API response.
    // <>
    //   <div className="flyin__content">
    //     <div className="flyin__acco">
    //       <div className="flyin__acco__cards">
    //         <div className="flyin__acco__card">
    //           <div className="flyin__acco__img__wrapper">
    //             <img src="https://cdn.pixabay.com/photo/2024/05/15/12/31/lake-8763490_1280.jpg" alt="river" className="flyin__acco__img" />
    //             <div className="flyin__acco__price__wrapper">
    //               <span className="flyin__acco__price__label">{translations?.SHARED.TOTAL_PRICE}</span>
    //               <span className="flyin__acco__price flyin__acco__price--increase">+1.764,00</span>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__content">
    //             <div className="flyin__acco__header">
    //               <h4 className="flyin__acco__title">Deluxe Balcony Room</h4>
    //               <div className="flyin__acco__usps">
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Sea sight</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Free wifi</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Breakfast included</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Air conditioning</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Private bathroom</span>
    //                 </div>
    //               </div>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__footer">
    //             <ItemPicker
    //               items={travelClasses}
    //               selection={selectedTravelClass}
    //               label=" "
    //               placeholder={translations.QSM.TRAVEL_CLASS_PLACEHOLDER}
    //               classModifier="travel-class-picker__items"
    //               onPick={(item) => setSelectedTravelClass(item)}
    //             />
    //             <button className="cta cta--select">{translations?.SHARED.SELECT}</button>
    //           </div>
    //         </div>

    //         <div className="flyin__acco__card">
    //           <div className="flyin__acco__img__wrapper">
    //             <img src="https://cdn.pixabay.com/photo/2024/05/15/12/31/lake-8763490_1280.jpg" alt="river" className="flyin__acco__img" />
    //             <div className="flyin__acco__price__wrapper">
    //               <span className="flyin__acco__price__label">{translations?.SHARED.TOTAL_PRICE}</span>
    //               <span className="flyin__acco__price flyin__acco__price--increase">+1.764,00</span>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__content">
    //             <div className="flyin__acco__header">
    //               <h4 className="flyin__acco__title">Standard Room</h4>
    //               <div className="flyin__acco__usps">
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Garden view</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Free wifi</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Double bed</span>
    //                 </div>
    //               </div>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__footer">
    //             <ItemPicker
    //               items={travelClasses}
    //               selection={selectedTravelClass}
    //               label=" "
    //               placeholder={translations.QSM.TRAVEL_CLASS_PLACEHOLDER}
    //               classModifier="travel-class-picker__items"
    //               onPick={setSelectedTravelClass}
    //             />
    //             <button className="cta cta--select">{translations?.SHARED.SELECT}</button>
    //           </div>
    //         </div>

    //         <div className="flyin__acco__card">
    //           <div className="flyin__acco__img__wrapper">
    //             <img src="https://cdn.pixabay.com/photo/2024/05/15/12/31/lake-8763490_1280.jpg" alt="river" className="flyin__acco__img" />
    //             <div className="flyin__acco__price__wrapper">
    //               <span className="flyin__acco__price__label">{translations?.SHARED.TOTAL_PRICE}</span>
    //               <span className="flyin__acco__price flyin__acco__price--increase">+1.764,00</span>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__content">
    //             <div className="flyin__acco__header">
    //               <h4 className="flyin__acco__title">Suite</h4>
    //               <div className="flyin__acco__usps">
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Sea sight</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Free wifi</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Breakfast included</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Jacuzzi</span>
    //                 </div>
    //                 <div className="flyin__acco__usp">
    //                   <Icon name="ui-check" width={16} />
    //                   <span className="flyin__acco__usp__text">Private terrace</span>
    //                 </div>
    //               </div>
    //             </div>
    //           </div>

    //           <div className="flyin__acco__footer">
    //             <ItemPicker
    //               items={travelClasses}
    //               selection={selectedTravelClass}
    //               label=" "
    //               placeholder={translations.QSM.TRAVEL_CLASS_PLACEHOLDER}
    //               classModifier="travel-class-picker__items"
    //               onPick={setSelectedTravelClass}
    //             />
    //             <button className="cta cta--select">{translations?.SHARED.SELECT}</button>
    //           </div>
    //         </div>
    //       </div>
    //     </div>

    //     {/* {isLoading && (
    //       <Spinner />
    //     )} */}
    //   </div>

    //   <div className="flyin__footer">
    //     <div className="flyin__footer__price">{translations.SHARED.TOTAL_PRICE}: €</div>
    //     <div className="flyin__button-wrapper">
    //       <button className="cta cta--select" onClick={handleConfirm}>
    //         Toevoegen
    //       </button>
    //     </div>
    //   </div>
    // </>
  );
};

export default AccommodationFlyIn;
