import React, { useState, useEffect, useRef } from "react";
import { useSelector } from "react-redux";
import { buildClassName } from "../../../shared/utils/class-util";
import Icon from "../../components/icon";
import MultiRangeFilter from "../../components/multi-range-filter";
import { FlightFilterOptions } from "../../types";
import { selectTranslations } from "../booking/selectors";
import { formatMinutes } from "./flight-utils";

interface FlightFilterProps {
  filterOptions: FlightFilterOptions;
  resultCount: number;

  applyFilter: (options: FlightFilterOptions) => void;
}

const FlightFilter: React.FC<FlightFilterProps> = ({
  filterOptions,
  resultCount,
  applyFilter
}) => {
  const translations = useSelector(selectTranslations);

  const [filtersVisible, setFiltersVisible] = useState<boolean>(false);
  const filterRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (filterRef.current && !filterRef.current.contains(event.target as Node)) {
        setFiltersVisible(false);
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  const updateAirportFilter = (code: string) => {
    const updatedFilterOptions = {
      ...filterOptions,
      airports: filterOptions.airports.map(x => {
        if (x.value !== code) return x;

        return {
          ...x,
          isSelected: !x.isSelected
        }
      })
    };

    applyFilter(updatedFilterOptions);
  }

  const updateAirlineFilter = (code: string) => {
    const updatedFilterOptions = {
      ...filterOptions,
      airlines: filterOptions.airlines.map(x => {
        if (x.value !== code) return x;

        return {
          ...x,
          isSelected: !x.isSelected
        }
      })
    };

    applyFilter(updatedFilterOptions);
  }

  const updateStopsFilter = (count: string) => {
    const updatedFilterOptions = {
      ...filterOptions,
      numberOfStops: filterOptions.numberOfStops.map(x => {
        if (x.value !== count) return x;

        return {
          ...x,
          isSelected: !x.isSelected
        }
      })
    };

    applyFilter(updatedFilterOptions);
  }

  const updateOutwardDeparture = (period: string) => {
    const updatedFilterOptions = {
      ...filterOptions,
      outward: {
        ...filterOptions.outward,
        departurePeriod: filterOptions.outward.departurePeriod.map(x => {
          if (x.value !== period) return x;

          return {
            ...x,
            isSelected: !x.isSelected
          }
        })
      }
    };

    applyFilter(updatedFilterOptions);
  }

  const updateOutwardTravelDuration = (min: number, max: number) => {
    const updatedFilterOptions = {
      ...filterOptions,
      outward: {
        ...filterOptions.outward,
        travelDuration: {
          ...filterOptions.outward.travelDuration,
          selectedMin: min,
          selectedMax: max
        }
      }
    };

    applyFilter(updatedFilterOptions);
  }

  const updateOutwardChangeDuration = (min: number, max: number) => {
    const updatedFilterOptions = {
      ...filterOptions,
      outward: {
        ...filterOptions.outward,
        changeDuration: {
          ...filterOptions.outward.changeDuration,
          selectedMin: min,
          selectedMax: max
        }
      }
    };

    applyFilter(updatedFilterOptions);
  }

  const updateReturnDeparture = (period: string) => {
    const updatedFilterOptions = {
      ...filterOptions,
      return: {
        ...filterOptions.return,
        departurePeriod: filterOptions.return.departurePeriod.map(x => {
          if (x.value !== period) return x;

          return {
            ...x,
            isSelected: !x.isSelected
          }
        })
      }
    };

    applyFilter(updatedFilterOptions);
  }

  const updateReturnTravelDuration = (min: number, max: number) => {
    const updatedFilterOptions = {
      ...filterOptions,
      return: {
        ...filterOptions.return,
        travelDuration: {
          ...filterOptions.return.travelDuration,
          selectedMin: min,
          selectedMax: max
        }
      }
    };

    applyFilter(updatedFilterOptions);
  }

  const updateReturnChangeDuration = (min: number, max: number) => {
    const updatedFilterOptions = {
      ...filterOptions,
      return: {
        ...filterOptions.return,
        changeDuration: {
          ...filterOptions.return.changeDuration,
          selectedMin: min,
          selectedMax: max
        }
      }
    };

    applyFilter(updatedFilterOptions);
  }

  return (
    <>
      <button type="button" className="cta cta--filter" onClick={() => setFiltersVisible(!filtersVisible)}>
        <Icon name="ui-filter" width={11} height={10} />
        <span>{translations.FLIGHTS_FORM.FILTER_OPTIONS}</span>
        {filtersVisible}
      </button>

      <div ref={filterRef} className={buildClassName(["flight__filter", filtersVisible && "flight__filter--active"])}>
        <div className="flight__filter__header">
          <div className="flight__filter__header__title">
            <h3>{translations.FLIGHTS_FORM.FILTER_OPTIONS}</h3>
            <p>{translations.FLIGHTS_FORM.FLIGHTS_FOUND_1} <strong>{resultCount} {translations.FLIGHTS_FORM.FLIGHTS_FOUND_2}</strong> {translations.FLIGHTS_FORM.FLIGHTS_FOUND_3}</p>
          </div>
        </div>
        <div className="flight__filter__body">
          <div className="flight__filter__group">
            <div className="flight__filter__group__title">
              {translations.FLIGHTS_FORM.AIRLINES}
            </div>
            <div className="flight__filter__group__wrapper">
              {filterOptions.airlines.map((option, k) => (
                <div className="tree" key={k}>
                  <div className="checkbox flight__filter__checkbox">
                    <label htmlFor={'airline_' + option.value} className="checkbox__label">
                      <input type="checkbox" id={'airline_' + option.value} className="checkbox__input checkbox__input--parent"
                        onClick={() => updateAirlineFilter(option.value)} />
                      <span className="radiobutton__label-text">
                        {option.label} {option.count > 0 && (<span className="amount">({option.count})</span>)}
                      </span>
                    </label>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="flight__filter__group">
            <div className="flight__filter__group__title">
              {translations.FLIGHTS_FORM.AIRPORTS}
            </div>
            <div className="flight__filter__group__wrapper">
              {filterOptions.airports.map((option, k) => (
                <div className="tree" key={k}>
                  <div className="checkbox flight__filter__checkbox">
                    <label htmlFor={'airport_' + option.value} className="checkbox__label">
                      <input type="checkbox" id={'airport_' + option.value} className="checkbox__input checkbox__input--parent"
                        onClick={() => updateAirportFilter(option.value)} />
                      <span className="radiobutton__label-text">
                        {option.label} {option.count > 0 && (<span className="amount">({option.count})</span>)}
                      </span>
                    </label>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="flight__filter__group">
            <div className="flight__filter__group__title">
              {translations.FLIGHTS_FORM.NUMBER_OF_STOPS}
            </div>
            <div className="flight__filter__group__wrapper">
              {filterOptions.numberOfStops.map((option, k) => (
                <div className="tree" key={k}>
                  <div className="checkbox flight__filter__checkbox">
                    <label htmlFor={'stops_' + option.value} className="checkbox__label">
                      <input type="checkbox" id={'stops_' + option.value} className="checkbox__input checkbox__input--parent"
                        onClick={() => updateStopsFilter(option.value)} />
                      <span className="radiobutton__label-text">
                        {option.label} {option.count > 0 && (<span className="amount">({option.count})</span>)}
                      </span>
                    </label>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="flight__filter__group">
            <div className="flight__filter__group__title">
              {translations.FLIGHTS_FORM.FLIGHT_OUTWARD}
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.DEPARTURE_TIME}</p>
              {filterOptions.outward.departurePeriod.map((option, k) => (
                <div className="tree" key={k}>
                  <div className="checkbox flight__filter__checkbox">
                    <label htmlFor={'outward_time_' + option.value} className="checkbox__label">
                      <input type="checkbox" id={'outward_time_' + option.value} className="checkbox__input checkbox__input--parent"
                        onClick={() => updateOutwardDeparture(option.value)} />
                      <span className="radiobutton__label-text">
                        {option.label} {option.count > 0 && (<span className="amount">({option.count})</span>)}
                      </span>
                    </label>
                  </div>
                </div>
              ))}
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.TRAVEL_DURATION}</p>
              <MultiRangeFilter
                min={filterOptions.outward.travelDuration.min}
                max={filterOptions.outward.travelDuration.max}
                selectedMin={filterOptions.outward.travelDuration.selectedMin}
                selectedMax={filterOptions.outward.travelDuration.selectedMax}
                valueFormatter={formatMinutes}
                onChange={updateOutwardTravelDuration}
              />
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.CHANGE_TIME}</p>
              <MultiRangeFilter
                min={filterOptions.outward.changeDuration.min}
                max={filterOptions.outward.changeDuration.max}
                selectedMin={filterOptions.outward.changeDuration.selectedMin}
                selectedMax={filterOptions.outward.changeDuration.selectedMax}
                valueFormatter={formatMinutes}
                onChange={updateOutwardChangeDuration}
              />
            </div>
          </div>
          <div className="flight__filter__group">
            <div className="flight__filter__group__title">
              {translations.FLIGHTS_FORM.FLIGHT_RETURN}
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.DEPARTURE_TIME}</p>
              {filterOptions.return.departurePeriod.map((option, k) => (
                <div className="tree" key={k}>
                  <div className="checkbox flight__filter__checkbox">
                    <label htmlFor={'return_time_' + option.value} className="checkbox__label">
                      <input type="checkbox" id={'return_time_' + option.value} className="checkbox__input checkbox__input--parent"
                        onClick={() => updateReturnDeparture(option.value)} />
                      <span className="radiobutton__label-text">
                        {option.label} {option.count > 0 && (<span className="amount">({option.count})</span>)}
                      </span>
                    </label>
                  </div>
                </div>
              ))}
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.TRAVEL_DURATION}</p>
              <MultiRangeFilter
                min={filterOptions.return.travelDuration.min}
                max={filterOptions.return.travelDuration.max}
                selectedMin={filterOptions.return.travelDuration.selectedMin}
                selectedMax={filterOptions.return.travelDuration.selectedMax}
                valueFormatter={formatMinutes}
                onChange={updateReturnTravelDuration}
              />
            </div>
            <div className="flight__filter__group__wrapper">
              <p>{translations.FLIGHTS_FORM.CHANGE_TIME}</p>
              <MultiRangeFilter
                min={filterOptions.return.changeDuration.min}
                max={filterOptions.return.changeDuration.max}
                selectedMin={filterOptions.return.changeDuration.selectedMin}
                selectedMax={filterOptions.return.changeDuration.selectedMax}
                valueFormatter={formatMinutes}
                onChange={updateReturnChangeDuration}
              />
            </div>
          </div>
        </div>
      </div>
    </>
  )
}

export default FlightFilter;