import React, { useContext, useState } from 'react';
import { Filter, FilterOption } from '../../types';
import MultiRangeFilter from '../multi-range-filter';
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
import Spinner from '../spinner/spinner';
import Icon from '../../../shared/components/icon';
import { getTranslations } from '../../../shared/utils/localization-util';

interface FiltersProps {
  initialFilters: Filter[];
  filters: Filter[];
  isOpen: boolean;
  handleSetIsOpen: () => void;
  isLoading?: boolean;
  setFilters: (filters: Filter[]) => void;
  resetFilters: (filters: Filter[]) => void;
}

const Filters: React.FC<FiltersProps> = ({ initialFilters, filters, isOpen, handleSetIsOpen, isLoading, setFilters, resetFilters }) => {
  const context = useContext(SearchResultsConfigurationContext);

  if (!context || !context.showFilters) {
    return null;
  }

  const translations = getTranslations(context?.languageCode ?? 'en-GB');
  const [visibleFilters, setVisibleFilters] = useState<Record<string, boolean>>({});

  const toggleFilterVisibility = (filterId: string) => {
    setVisibleFilters((prev) => ({
      ...prev,
      [filterId]: !prev[filterId]
    }));
  };

  const handleCheckBoxFilter = (filter: Filter, option: FilterOption) => {
    const updated = filters.map((f) => {
      if (f.property !== filter.property) return f;

      return {
        ...f,
        options: f.options?.map((opt) => (opt.value === option.value ? { ...opt, isChecked: !opt.isChecked } : opt))
      };
    });

    setFilters(updated);
  };

  const handleStarRatingFilter = (filter: Filter, rating: number) => {
    const updated = filters.map((f) => {
      if (f.property !== filter.property) return f;

      return {
        ...f,
        selectedRating: f.selectedRating === rating ? 0 : rating
      };
    });

    setFilters(updated);
  };

  const handleSliderChange = (filter: Filter, newMin: number, newMax: number) => {
    const updated = filters.map((f) => {
      if (f.property !== filter.property) return f;

      return {
        ...f,
        selectedMin: newMin,
        selectedMax: newMax
      };
    });

    setFilters(updated);
  };

  const handleFullReset = () => {
    if (!isLoading) {
      resetFilters(initialFilters);
    }
  };

  return (
    <div className={`search__filters--modal ${isOpen ? 'is-open' : ''}`}>
      <div className="search__filters--background" onClick={() => handleSetIsOpen()}></div>
      <button className="search__filters--close" onClick={() => handleSetIsOpen()}>
        <Icon name="ui-close" height={24} />
      </button>
      <div className="search__filters">
        <div className="search__filter-row search__filter__header">
          <div className="search__filter-row-flex-title">
            <p className="search__filter-small-title">{translations.SRP.FILTERS}</p>
          </div>
          {!isLoading && (
            <a className="search__filter-reset" onClick={() => handleFullReset()}>
              {translations.SRP.RESET}
            </a>
          )}
        </div>
        {isLoading ? (
          <Spinner />
        ) : (
          <>
            <div className="search__filters__group-container">
              {filters.map((filter, index) => {
                const isVisible = visibleFilters[filter.property] ?? true;

                return (
                  <div key={`${filter.property}-${index}`} className="search__filter-group">
                    <div
                      className="search__filter-row search__filter-row--underline"
                      onClick={() => toggleFilterVisibility(filter.property)}
                      role="button"
                      tabIndex={0}>
                      <h6 className="search__filter-large-title">{filter.label}</h6>
                      <svg
                        id="search-chevron-up-icon"
                        className={`search__filter-chevron-icon ${isVisible ? 'search__filter-chevron-icon--flipped' : ''} `}
                        viewBox="0 0 10 6.063"
                        width={10}
                        height={6.063}>
                        <path
                          id="Path_62"
                          data-name="Path 62"
                          d="M245-617.937l-5-5L241.063-624,245-620.062,248.938-624,250-622.937Z"
                          transform="translate(-240 624)"
                          fill="#707070"
                        />
                      </svg>
                    </div>

                    {isVisible && filter.type === 'checkbox' && (
                      <div className="search__filter-rows">
                        {filter.options &&
                          filter.options.map((option: FilterOption, optionIndex) => (
                            <div className="search__filter-row search__filter-row--checkbox" key={`${option.label}-${optionIndex}`}>
                              <div className="checkbox">
                                <label className="checkbox__label">
                                  <input
                                    type="checkbox"
                                    className="checkbox__input checkbox__input--parent"
                                    checked={option.isChecked}
                                    onChange={(e) => handleCheckBoxFilter(filter, option)}
                                  />
                                  <span className="radiobutton__label-text">{option.label}</span>
                                </label>
                              </div>
                            </div>
                          ))}
                      </div>
                    )}

                    {isVisible && filter.type === 'toggle' && (
                      <div className="search__filter-rows">
                        {filter.options?.map((option: FilterOption, optionIndex) => (
                          <div className="search__filter-row" key={`${option.label}-${optionIndex}`}>
                            <span className="search__filter-toggle-label">{option.label}</span>
                            <div className="checkbox"></div>
                            <label className="checkbox__label">
                              <input
                                type="checkbox"
                                className="checkbox__input"
                                checked={option.isChecked}
                                onChange={() => handleCheckBoxFilter(filter, option)}
                              />
                            </label>
                          </div>
                        ))}
                      </div>
                    )}

                    {isVisible &&
                      filter &&
                      filter.type === 'slider' &&
                      (() => {
                        const min = filter.min ?? 0;
                        const max = filter.max ?? 100;
                        const selectedMin = filter.selectedMin ?? min;
                        const selectedMax = filter.selectedMax ?? max;
                        const range = max - min || 1;

                        return (
                          <MultiRangeFilter
                            min={min}
                            max={max}
                            selectedMin={selectedMin}
                            selectedMax={selectedMax}
                            valueFormatter={(value) => `${value}`}
                            onChange={(newMin, newMax) => {
                              handleSliderChange(filter, newMin, newMax);
                            }}
                          />
                        );
                      })()}

                    {isVisible &&
                      filter.property === 'rating' &&
                      filter.type === 'star-rating' &&
                      (() => {
                        const selectedRating = filter.selectedRating ?? 0;
                        return (
                          <div className="search__filter-row star-rating-filter">
                            {[5, 4, 3, 2, 1].map((star) => (
                              <span
                                key={star}
                                className={`star ${star <= selectedRating ? 'filled' : ''}`}
                                onClick={() => handleStarRatingFilter(filter, star)}
                                role="button"
                                tabIndex={0}
                                onKeyDown={(e) => {
                                  if (e.key === 'Enter' || e.key === ' ') handleStarRatingFilter(filter, star);
                                }}>
                                ★
                              </span>
                            ))}
                          </div>
                        );
                      })()}
                  </div>
                );
              })}
            </div>
          </>
        )}
      </div>
    </div>
  );
};

export default Filters;
