import React, { useContext, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { SearchResultsRootState } from '../../store/search-results-store';
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
import { getDatesBetween, getLocale, getTranslations } from '../../../shared/utils/localization-util';
import { selectSelectedPackagingAccoResult } from '../../store/search-results-selectors';
import { removeConfirmedExcursionForDay, setExcursionSearchParams, setFlyInIsOpen, setFlyInType } from '../../store/search-results-slice';
import { ExcursionSearchParams } from '../../types';
import { format } from 'date-fns';
import he from 'he';
import Icon from '../../../shared/components/icon';
import { PackagingAccommodationResponse } from '@qite/tide-client';

interface DayByDayExcursionsProps {}

const getExcursionContentWithUpdatedPrice = (contents: string | null | undefined, totalPrice: number, currencyCode?: string | null) => {
  if (!contents) return '';

  const decodedHtml = he.decode(contents);
  const parser = new DOMParser();
  const doc = parser.parseFromString(decodedHtml, 'text/html');

  const priceElement = doc.querySelector('[data-excursion-price]');

  if (priceElement) {
    priceElement.textContent = new Intl.NumberFormat('nl-BE', {
      style: 'currency',
      currency: currencyCode ?? 'EUR'
    }).format(totalPrice);
  }

  return doc.body.innerHTML;
};

const DayByDayExcursions: React.FC<DayByDayExcursionsProps> = () => {
  const context = useContext(SearchResultsConfigurationContext);
  const translations = getTranslations(context?.languageCode ?? 'en-GB');
  const dispatch = useDispatch();

  const { confirmedExcursionsByDay } = useSelector((state: SearchResultsRootState) => state.searchResults);
  const selectedPackagingAccoResult = useSelector(selectSelectedPackagingAccoResult);

  const stayDates = useMemo(() => {
    if (!selectedPackagingAccoResult?.fromDate || !selectedPackagingAccoResult?.toDate) {
      return [];
    }

    return getDatesBetween(selectedPackagingAccoResult.fromDate, selectedPackagingAccoResult.toDate);
  }, [selectedPackagingAccoResult?.fromDate, selectedPackagingAccoResult?.toDate]);

  const handleSearchExcursions = (day: Date) => {
    if (!selectedPackagingAccoResult) {
      return;
    }

    const searchParams: ExcursionSearchParams = {
      date: day.toISOString(),
      fromDate: day.toISOString(),
      toDate: day.toISOString(),
      countryId: selectedPackagingAccoResult.countryId,
      regionId: selectedPackagingAccoResult.regionId,
      oordId: selectedPackagingAccoResult.oordId,
      locationId: selectedPackagingAccoResult.locationId,
      locationName: selectedPackagingAccoResult.locationName,
      accommodationCode: selectedPackagingAccoResult.rooms?.[0]?.options?.find((option) => option.isSelected)?.accommodationCode ?? null,
      accommodationName: selectedPackagingAccoResult.rooms?.[0]?.options?.find((option) => option.isSelected)?.accommodationName ?? null,
      hotelCode: selectedPackagingAccoResult.code,
      hotelName: selectedPackagingAccoResult.name,
      rooms: selectedPackagingAccoResult?.rooms ?? []
    };

    dispatch(setExcursionSearchParams(searchParams));
    dispatch(setFlyInIsOpen(true));
    dispatch(setFlyInType('excursion-results'));
  };

  const getSelectedOptionsSummary = (excursion: PackagingAccommodationResponse) => {
    const options = excursion.rooms.flatMap((room) => room.options ?? []);
    return options.filter((option) => option.isSelected);
  };

  if (!selectedPackagingAccoResult || stayDates.length === 0) {
    return null;
  }

  return (
    <>
      {stayDates.map((day) => {
        const dayKey = format(day, 'yyyy-MM-dd');
        const confirmedExcursions = confirmedExcursionsByDay[dayKey] ?? [];

        return (
          <React.Fragment key={dayKey}>
            <div className="search__results__label search__results__label--secondary">
              <div className="search__results__label__date">
                <p className="search__results__label__date-date">{format(day, 'd', { locale: getLocale(context?.languageCode ?? 'en-GB') })}</p>
                <p>{format(day, 'MMM', { locale: getLocale(context?.languageCode ?? 'en-GB') })}</p>
              </div>
              <div className="search__results__label__text">
                <Icon name="ui-excursion" height={16} />
                <h3>
                  {translations.SRP.SELECT} <strong>{translations.SRP.EXCURSION}</strong>
                </h3>
              </div>
            </div>

            <div className="search__results__cards__actions">
              <span>Accommodation for this day: {selectedPackagingAccoResult.name}</span>

              <button type="button" className="cta cta--secondary" onClick={() => handleSearchExcursions(day)}>
                {confirmedExcursions.length > 0 ? 'Add another excursion' : `${translations.SRP.SELECT} ${translations.SRP.EXCURSION}`}
              </button>
            </div>

            <div className="search__results__cards search__results__cards--compact">
              {confirmedExcursions &&
                confirmedExcursions.length > 0 &&
                confirmedExcursions.map((excursion) => {
                  const selectedOptions = getSelectedOptionsSummary(excursion);
                  const totalPrice = selectedOptions.reduce((sum: number, option: any) => sum + (option.price || 0), 0);
                  const updatedContents = getExcursionContentWithUpdatedPrice(excursion.contents, totalPrice, excursion.currencyCode);
                  return (
                    <div
                      key={excursion.code}
                      className="search__result-card__wrapper search__result-card__wrapper--custom"
                      onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.02)')}
                      onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}>
                      <div dangerouslySetInnerHTML={{ __html: updatedContents }}></div>
                      <div className="search__result-card__content--extra">
                        <div className="search__result-card__content__wrapper">
                          <div className="search__result-card__options">
                            {selectedOptions.length > 0 &&
                              selectedOptions.map((option) => (
                                <div className="search__result-card__option" key={option.guid}>
                                  <Icon name="ui-ticket" width={14} height={14} aria-hidden="true" />
                                  <span>
                                    {option.accommodationName}
                                    {/* {option.paxIds?.length > 0 && (
                                    <>
                                      {' '}(Traveller{option.paxIds.length > 1 ? 's' : ''}{' '}{option.paxIds.map((id) => id + 1).join(', ')})
                                    </>
                                  )} */}
                                  </span>
                                </div>
                              ))}
                          </div>
                        </div>
                      </div>
                      <div className="search__result-card__footer">
                        <button
                          type="button"
                          className="cta cta--remove"
                          onClick={() => dispatch(removeConfirmedExcursionForDay({ dayKey, excursionCode: excursion.code }))}>
                          Remove
                        </button>
                      </div>
                    </div>
                  );
                })}
            </div>
          </React.Fragment>
        );
      })}
    </>
  );
};

export default DayByDayExcursions;
