import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
  closeMobileFilter,
  setActiveSearchField,
  setFieldValue,
  setFromDate,
  setToDate,
  setSearchResults as setSearchResultsAction,
  setSearchResults
} from '../../store/qsm-slice';
import { QSMRootState } from '../../store/qsm-store';
import SearchInput from '../search-input';
import DateRangePicker from '../date-range-picker';
import TravelInput from '../travel-input';
import { format } from 'date-fns';
import QSMConfigurationContext from '../../qsm-configuration-context';
import { BaseFieldConfig, TypeaheadOption } from '../../types';
import { getTranslations } from '../../../shared/utils/localization-util';

const MobileFilterModal: React.FC = () => {
  const { datesIcon, languageCode } = useContext(QSMConfigurationContext);
  const translations = getTranslations(languageCode ?? 'en-GB');
  const dispatch = useDispatch();
  const {
    mobileFilterType,
    mobileDatePickerMode,
    activeSearchFieldProps,
    fromDate,
    toDate,
    searchResults,
    departureAirport,
    destinationAirport,
    returnAirport,
    destination
  } = useSelector((state: QSMRootState) => state.qsm);

  const searchInputRef = useRef<HTMLInputElement>(null);

  const [inputValue, setInputValue] = useState('');

  /* ---------------------------------------------------------------- */
  /* Sync local state when a new field is opened                       */
  /* ---------------------------------------------------------------- */
  useEffect(() => {
    if (activeSearchFieldProps) {
      setInputValue(activeSearchFieldProps.value || '');
      // setSearchResultsLocal([]);
      // hasTypedRef.current = false;
    }
  }, [activeSearchFieldProps]);

  useEffect(() => {
    if (mobileFilterType !== 'search') return;

    requestAnimationFrame(() => {
      const input = searchInputRef.current;
      if (!input) return;

      input.focus();
      input.setSelectionRange(input.value.length, input.value.length);
    });
  }, [mobileFilterType, activeSearchFieldProps?.fieldKey]);

  /* ---------------------------------------------------------------- */
  /* Helpers                                                          */
  /* ---------------------------------------------------------------- */
  const closeModal = () => {
    // hasTypedRef.current = false;
    dispatch(closeMobileFilter());
  };

  const findConfig = (all: BaseFieldConfig[], key: string): BaseFieldConfig | undefined => {
    for (const config of all) {
      if (config.fieldKey === key) {
        return config;
      }
    }
    return undefined;
  };

  const config = useMemo<BaseFieldConfig | undefined>(() => {
    if (!activeSearchFieldProps) return undefined;
    const searchFields = [departureAirport, destinationAirport, returnAirport, destination].filter((field): field is BaseFieldConfig => field !== undefined);
    return findConfig(searchFields, activeSearchFieldProps.fieldKey);
  }, [departureAirport, destinationAirport, returnAirport, destination, activeSearchFieldProps]);

  const match = useCallback(
    (input: string) => {
      if (!input) {
        return [];
      }

      const lowered = input.toLowerCase();
      return activeSearchFieldProps?.options.filter(
        (option) => option.value.toLowerCase().includes(lowered) || option.iataCode?.toLowerCase().includes(lowered)
      );
    },
    [activeSearchFieldProps?.options]
  );

  const handleInputChange = useCallback(
    (input: string) => {
      setInputValue(input);
      if (!activeSearchFieldProps) return;

      dispatch(setFieldValue({ fieldKey: activeSearchFieldProps.fieldKey, value: input }));
      dispatch(setSearchResults([]));
      dispatch(setActiveSearchField(activeSearchFieldProps.fieldKey));

      if (config?.onChange) {
        config.onChange(input);
        return;
      }

      const filtered = match(input) ?? [];
      dispatch(setSearchResults(filtered));
    },
    [dispatch, activeSearchFieldProps, match]
  );

  useEffect(() => {
    if (!activeSearchFieldProps) return;
    if (!inputValue) return;

    dispatch(setSearchResults(match(inputValue) ?? []));
  }, [activeSearchFieldProps?.options]);

  const handleLocationSelect = (option: TypeaheadOption) => {
    if (activeSearchFieldProps) {
      const { fieldKey } = activeSearchFieldProps;

      dispatch(setFieldValue({ fieldKey, value: option.value }));
      dispatch(setSearchResultsAction([]));
      dispatch(setActiveSearchField(null));
    }

    dispatch(closeMobileFilter());
  };

  /* ---------------------------------------------------------------- */
  /* Render helpers                                                   */
  /* ---------------------------------------------------------------- */
  const renderDatePickerModal = () => {
    const hasValidDates = mobileDatePickerMode === 'single' ? Boolean(fromDate) : Boolean(fromDate && toDate);

    return (
      <div className="mobile-qsm-filter__modal">
        {/* header */}
        <div className="mobile-qsm-filter__modal-header">
          <div className="mobile-qsm-filter__modal-header-row">
            <span className="mobile-qsm-filter__modal-header-title">{translations.QSM.CHOOSE_DATES}</span>
            <span className="mobile-qsm-filter__modal-header-close" onClick={closeModal}></span>
          </div>
        </div>

        {/* date inputs + picker */}
        <div className="qsm__double-input qsm__double-input--date-modal">
          {/* Departure */}
          <div className="qsm__double-input__wrapper">
            <label className="qsm__input-wrapper">
              {datesIcon && <span className="qsm__input-icon">{datesIcon}</span>}
              <span className="qsm__label">{translations.QSM.DEPARTURE_DATE}</span>
              <input
                type="text"
                id="vertrek"
                className="qsm__input u-ps-2"
                placeholder={translations.QSM.DEPARTURE_DATE}
                readOnly
                value={fromDate ? format(new Date(fromDate), 'dd/MM/yyyy') : ''}
              />
              {mobileDatePickerMode === 'range' && <div className="qsm__input-line qsm__input-line--datepicker" />}
            </label>

            {/* Return (range mode) */}
            {mobileDatePickerMode === 'range' && (
              <label className="qsm__input-wrapper">
                {datesIcon && <span className="qsm__input-icon">{datesIcon}</span>}
                <span className="qsm__label qsm__label--second-input-label">{translations.QSM.RETURN_DATE}</span>
                <input
                  type="text"
                  id="retour"
                  className="qsm__input"
                  placeholder={translations.QSM.RETURN_DATE}
                  readOnly
                  value={toDate ? format(new Date(toDate), 'dd/MM/yyyy') : ''}
                />
              </label>
            )}
          </div>

          <DateRangePicker
            fromDate={fromDate ? new Date(fromDate) : undefined}
            toDate={mobileDatePickerMode === 'range' && toDate ? new Date(toDate) : undefined}
            isSingleDate={mobileDatePickerMode === 'single'}
            onSelectionChange={(from, to) => {
              if (from) {
                dispatch(setFromDate(from.toISOString()));
              }

              if (mobileDatePickerMode === 'range' && to) {
                dispatch(setToDate(to.toISOString()));
              } else {
                dispatch(setToDate(undefined));
              }
            }}
          />
        </div>

        {/* footer */}
        <div className="mobile-qsm-filter__modal-footer">
          <button
            className={`cta ${hasValidDates ? '' : 'cta--disabled'}`}
            disabled={!hasValidDates}
            onClick={() => {
              if (hasValidDates) {
                closeModal();
              }
            }}>
            {translations.QSM.CONFIRM}
          </button>
        </div>
      </div>
    );
  };

  const renderSearchInputModal = () => {
    if (!activeSearchFieldProps) {
      return null;
    }

    return (
      <div className="mobile-qsm-filter__modal">
        {/* header */}
        <div className="mobile-qsm-filter__modal-header">
          <div className="mobile-qsm-filter__modal-header-row">
            <span className="mobile-qsm-filter__modal-header-title">{activeSearchFieldProps.label}</span>
            <span className="mobile-qsm-filter__modal-header-close" onClick={closeModal}></span>
          </div>
        </div>
        {/* <div className="mobile-qsm-filter__modal-wrapper"> */}
        {/* input + dropdown */}
        <div className="qsm__double-input qsm__double-input--search-modal">
          <label className="qsm__input-wrapper">
            <input
              ref={searchInputRef}
              type="text"
              id="search"
              value={inputValue}
              onClick={(e) => e.stopPropagation()}
              onChange={(e) => handleInputChange(e.target.value)}
              className="qsm__input qsm__input--modal qsm__from-to u-ps-2"
              placeholder={activeSearchFieldProps.placeholder}
            />
            <SearchInput
              onChange={handleInputChange}
              searchResults={searchResults}
              onOptionSelect={handleLocationSelect}
              highlightTarget={inputValue}
              label={activeSearchFieldProps.label}
            />
          </label>
        </div>
        <div className="mobile-qsm-filter__modal-footer">
          <button className="cta" onClick={closeModal}>
            {translations.QSM.CONFIRM}
          </button>
        </div>
        {/* </div> */}

        {/* empty state */}
        {/* {searchResultsLocal.length === 0 && (
          <div className="mobile-qsm-filter__background-content">
            <span className="mobile-qsm-filter__background-title">Geen resultaten</span>
            <span className="mobile-qsm-filter__background-subtitle">Typ een plaatsnaam om te zoeken</span>
          </div>
        )} */}
      </div>
    );
  };

  const renderTravelerModal = () => (
    <div className="mobile-qsm-filter__modal">
      {/* header */}
      <div className="mobile-qsm-filter__modal-header">
        <div className="mobile-qsm-filter__modal-header-row">
          <span className="mobile-qsm-filter__modal-header-title">{translations.QSM.TRAVELERS}</span>
          <span className="mobile-qsm-filter__modal-header-close" onClick={closeModal}></span>
        </div>
      </div>

      <div className="qsm__double-input qsm__double-input--travel-modal">
        <div className="qsm__input-wrapper qsm__input-wrapper--rooms">
          <TravelInput />
        </div>
      </div>

      <div className="mobile-qsm-filter__modal-footer">
        <button className="cta" onClick={closeModal}>
          {translations.QSM.CONFIRM}
        </button>
      </div>
    </div>
  );

  /* ---------------------------------------------------------------- */
  /* Switch modal type                                                */
  /* ---------------------------------------------------------------- */
  switch (mobileFilterType) {
    case 'search':
      return renderSearchInputModal();
    case 'date':
      return renderDatePickerModal();
    case 'traveler':
      return renderTravelerModal();
    default:
      return null;
  }
};

export default MobileFilterModal;
