import { format, isBefore, startOfDay, isSameDay } from 'date-fns';
import React, { useContext, useEffect, useState } from 'react';
import { usePopper } from 'react-popper';
import { buildClassName } from '../../shared/utils/class-util';
import { getTranslations } from '../../shared/utils/localization-util';
import SettingsContext from '../settings-context';
import { DateRange } from '../types';
import DateRangePicker from './date-range-picker';
import Icon from '../../shared/components/icon';

interface DatesProps {
  value?: DateRange;
  duration?: number;
  onChange?: (value: DateRange) => void;
  availableDatePairs?: { fromDate: Date; toDate: Date }[];
  isLoading?: boolean;
}

const Dates: React.FC<DatesProps> = ({ value, duration, onChange, availableDatePairs, isLoading }) => {
  const { language } = useContext(SettingsContext);
  const translations = getTranslations(language);
  const mql = typeof window !== 'undefined' ? window.matchMedia('(min-width: 992px)') : undefined;
  const mqm = typeof window !== 'undefined' ? window.matchMedia('(min-width: 768px)') : undefined;

  const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null);
  const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
  const [panelActive, setPanelActive] = useState<boolean>(false);
  const { searchType = 0 } = useContext(SettingsContext);

  const { styles, attributes } = usePopper(referenceElement, popperElement, {
    placement: mql?.matches ? 'top' : 'bottom',
    modifiers: [
      {
        name: 'flip',
        enabled: false
      },
      {
        name: 'offset',
        options: {
          offset: [0, -40]
        }
      },
      {
        name: 'preventOverflow',
        options: {
          padding: 40
        }
      }
    ]
  });

  const handleInputFocus = () => {
    if (!panelActive) setPanelActive(true);
  };

  // Only allow selecting fromDates that are in availableDatePairs
  const disabledDaysFunction = (date: Date) => {
    if (!availableDatePairs || availableDatePairs.length === 0) {
      return isBefore(date, startOfDay(new Date()));
    }
    return !availableDatePairs.some((pair) => isSameDay(pair.fromDate, date));
  };

  // Given a fromDate, find the corresponding toDate
  const findToDateByFromDate = (fromDate?: Date) => {
    if (!fromDate || !availableDatePairs) return undefined;
    const found = availableDatePairs.find((pair) => isSameDay(pair.fromDate, fromDate));
    return found ? found.toDate : undefined;
  };

  const handleSelectionChange = (fromDate?: Date, toDate?: Date) => {
    if (onChange) {
      onChange({ fromDate, toDate });
      setPanelActive(false);
    }
  };

  useEffect(() => {
    document.addEventListener('mousedown', handleDocumentClick);
    return () => {
      document.removeEventListener('mousedown', handleDocumentClick);
    };
  });

  const handleDocumentClick: EventListener = (event) => {
    if (referenceElement && !referenceElement.contains(event.target as Node)) {
      if (panelActive) setPanelActive(false);
    }
  };

  return (
    <div className="booking-product__dates" ref={setReferenceElement}>
      <div className="booking-product__dates-title">
        <Icon name="ui-calendar" width={25} height={25} />
        {translations.PRODUCT.TRAVEL_PERIOD}
      </div>
      <div className="form__group form__group--datepicker form__group--icon">
        <div
          className={
            'form__group-input' +
            ((searchType === 1 && availableDatePairs && availableDatePairs.length === 0) || isLoading ? ' form__group-input--disabled' : '')
          }>
          <label className="form__label">{translations.PRODUCT.DEPARTURE}</label>
          <input
            type="text"
            readOnly
            value={value?.fromDate ? format(value.fromDate, 'dd/MM/yyyy') : ''}
            className="form__input"
            placeholder={translations.PRODUCT.DEPARTURE_DATE}
            onClick={handleInputFocus}
          />
        </div>

        <div className={'form__group-input' + (searchType === 1 || isLoading ? ' form__group-input--disabled' : '')}>
          <label className="form__label">{translations.PRODUCT.RETURN}</label>
          <input
            type="text"
            readOnly
            value={value?.toDate ? format(value.toDate, 'dd/MM/yyyy') : ''}
            className="form__input"
            placeholder={translations.PRODUCT.RETURN_DATE}
            onClick={handleInputFocus}
          />
        </div>
        <div
          ref={setPopperElement}
          className={buildClassName([
            'qsm__panel qsm__panel--bordered qsm__panel--dates-pricing',
            panelActive && 'qsm__panel--active',
            !mqm?.matches && 'qsm__panel--mobile'
          ])}
          style={mqm?.matches ? (styles.popper as any) : undefined}
          {...attributes.popper}>
          <DateRangePicker
            fromDate={value?.fromDate}
            toDate={value?.toDate}
            duration={duration}
            disabledDaysFunction={disabledDaysFunction}
            toDateByFromDate={findToDateByFromDate}
            onSelectionChange={handleSelectionChange}
          />
          {!mql?.matches && (
            <div className="qsm__close" onClick={() => setPanelActive(false)}>
              <Icon name="ui-close" height={25} width={25} />
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default Dates;
