import React, { useEffect, useState } from 'react'

import ExposedFilter from '../ExposedFilter/ExposedFilter'
import Button from '../Button/Button'
import { hasValue } from '../../services/HelperServiceTyped'
import styles from './_exposedFilterGroup.module.scss'
import { c } from '../../translations/LibraryTranslationService'
import { type MultiSelectDataItemBase } from '../MultiSelect/MultiSelect'
import {
  type ExposedFilterNameType,
  type ExposedFilterProps,
} from '../ExposedFilter/ExposedFilter.models'

export interface ExposedFilterGroupProps<
  FilterType extends MultiSelectDataItemBase & ExposedFilterNameType,
> {
  /** Array of filter configurations */
  filters: ExposedFilterProps<FilterType>[]
  /** Function to reset filter options to default */
  resetCallout: () => void
  /** Function to update filter values */
  onChangeCallout?: ExposedFilterProps<FilterType>['onChangeCallout']
}

const ExposedFilterGroup = <
  FilterType extends MultiSelectDataItemBase & ExposedFilterNameType,
>({
  filters,
  onChangeCallout,
  resetCallout,
}: ExposedFilterGroupProps<FilterType>): React.JSX.Element => {
  const [activeFilters, setActiveFilters] = useState<Record<string, boolean>>(
    {},
  )
  const [isClearFilter, setIsClearFilter] = useState(false)

  const hasActiveFilters = Object.values(activeFilters).some(
    (isActive) => isActive,
  )

  useEffect(() => {
    // Initialize activeFilters based on default filter values
    const initialActiveFilters = filters.reduce(
      (acc, filter) => {
        const hasFilterValue =
          (filter.type === 'multi-select' &&
            filter.multiSelectProps.selectedOptions?.length > 0) ||
          (filter.type === 'date' &&
            (filter.dateProps.selectedDate ||
              filter.dateProps.selectedDateRange)) ||
          (filter.type === 'search' && filter.searchBarProps?.value) ||
          (filter.type === 'range' &&
            (hasValue(filter.rangeProps?.selectedValues.min) ||
              hasValue(filter.rangeProps?.selectedValues.max))) ||
          (filter.type === 'select' && filter.selectProps?.selectedOption) ||
          (filter.type === 'modal' &&
            (Array.isArray(filter.selectedOption)
              ? filter.selectedOption.length > 0
              : false))
        acc[filter.stateName] = !!hasFilterValue
        return acc
      },
      {} as Record<string, boolean>,
    )
    setActiveFilters(initialActiveFilters)
  }, [filters])

  if (!filters || filters.length === 0) {
    return <></>
  }

  return (
    <div className={styles.filtersContainer}>
      {filters.map((filter, index) => {
        return (
          <div key={index} className={styles.filterWrapper}>
            <ExposedFilter
              {...filter}
              onChangeCallout={onChangeCallout}
              isClearFilter={isClearFilter}
              setIsClearFilter={setIsClearFilter}
            />
          </div>
        )
      })}
      {hasActiveFilters ? (
        <Button
          as='unstyled'
          onClick={() => {
            setIsClearFilter(true)
            resetCallout()
            setActiveFilters({})
          }}
          className={styles.clearButton}
        >
          {c('clearAll')}
        </Button>
      ) : null}
    </div>
  )
}

export default ExposedFilterGroup
