import { useCallback } from 'react';
import { Select } from '@/components/ui/select';
import { DatePicker } from '@/components/ui/date-picker';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { cn } from '@/lib/utils';
import { RotateCcw } from 'lucide-react';

export interface FilterOption {
  id: string;
  label: string;
  type: 'select' | 'checkbox' | 'range' | 'date';
  options?: { value: string; label: string }[];
  placeholder?: string;
  min?: number;
  max?: number;
  step?: number;
  minDate?: Date;
  maxDate?: Date;
  disabled?: boolean;
}

export interface FiltersProps {
  filters: FilterOption[];
  values: Record<string, any>;
  onChange: (values: Record<string, any>) => void;
  onReset?: () => void;
  className?: string;
  showReset?: boolean;
  resetLabel?: string;
}

/**
 * Composant Filters pour filtrer les résultats avec plusieurs critères.
 */
export function Filters({
  filters,
  values,
  onChange,
  onReset,
  className,
  showReset = true,
  resetLabel = 'Réinitialiser',
}: FiltersProps) {
  const handleFilterChange = useCallback(
    (filterId: string, value: any) => {
      onChange({ ...values, [filterId]: value });
    },
    [values, onChange],
  );

  const handleReset = useCallback(() => {
    const resetValues: Record<string, any> = {};
    filters.forEach((filter) => {
      switch (filter.type) {
        case 'select':
          resetValues[filter.id] = undefined;
          break;
        case 'checkbox':
          resetValues[filter.id] = false;
          break;
        case 'range':
          resetValues[filter.id] = {
            min: filter.min || 0,
            max: filter.max || 100,
          };
          break;
        case 'date':
          resetValues[filter.id] = undefined;
          break;
      }
    });
    onChange(resetValues);
    onReset?.();
  }, [filters, onChange, onReset]);

  const hasActiveFilters = useCallback(() => {
    return filters.some((filter) => {
      const value = values[filter.id];
      if (value === undefined || value === null || value === '') {
        return false;
      }
      if (filter.type === 'checkbox') {
        return value === true;
      }
      if (filter.type === 'range') {
        const min = filter.min || 0;
        const max = filter.max || 100;
        return value.min !== min || value.max !== max;
      }
      return true;
    });
  }, [filters, values]);

  const renderFilter = (filter: FilterOption) => {
    const value = values[filter.id];

    switch (filter.type) {
      case 'select':
        return (
          <div key={filter.id} className="space-y-2">
            <Label htmlFor={filter.id}>{filter.label}</Label>
            <Select
              options={
                filter.options?.map((opt) => ({
                  value: opt.value,
                  label: opt.label,
                })) || []
              }
              value={value}
              onChange={(newValue) => handleFilterChange(filter.id, newValue)}
              placeholder={
                filter.placeholder ||
                `Sélectionner ${filter.label.toLowerCase()}`
              }
              disabled={filter.disabled}
            />
          </div>
        );

      case 'checkbox':
        return (
          <div key={filter.id} className="flex items-center space-x-2">
            <Checkbox
              id={filter.id}
              checked={value === true}
              onCheckedChange={(checked) =>
                handleFilterChange(filter.id, checked === true)
              }
              disabled={filter.disabled}
            />
            <Label htmlFor={filter.id} className="cursor-pointer">
              {filter.label}
            </Label>
          </div>
        );

      case 'range': {
        const rangeValue = value || {
          min: filter.min || 0,
          max: filter.max || 100,
        };
        return (
          <div key={filter.id} className="space-y-2">
            <Label>{filter.label}</Label>
            <div className="flex items-center gap-4">
              <div className="flex-1">
                <Label
                  htmlFor={`${filter.id}-min`}
                  className="text-xs text-muted-foreground"
                >
                  Min: {rangeValue.min}
                </Label>
                <Input
                  id={`${filter.id}-min`}
                  type="number"
                  min={filter.min}
                  max={filter.max}
                  step={filter.step || 1}
                  value={rangeValue.min}
                  onChange={(e) =>
                    handleFilterChange(filter.id, {
                      min: Number(e.target.value),
                      max: rangeValue.max,
                    })
                  }
                  disabled={filter.disabled}
                />
              </div>
              <div className="flex-1">
                <Label
                  htmlFor={`${filter.id}-max`}
                  className="text-xs text-muted-foreground"
                >
                  Max: {rangeValue.max}
                </Label>
                <Input
                  id={`${filter.id}-max`}
                  type="number"
                  min={filter.min}
                  max={filter.max}
                  step={filter.step || 1}
                  value={rangeValue.max}
                  onChange={(e) =>
                    handleFilterChange(filter.id, {
                      min: rangeValue.min,
                      max: Number(e.target.value),
                    })
                  }
                  disabled={filter.disabled}
                />
              </div>
            </div>
            <input
              type="range"
              min={filter.min || 0}
              max={filter.max || 100}
              step={filter.step || 1}
              value={rangeValue.min}
              onChange={(e) =>
                handleFilterChange(filter.id, {
                  min: Number(e.target.value),
                  max: rangeValue.max,
                })
              }
              className="w-full"
              disabled={filter.disabled}
            />
            <input
              type="range"
              min={filter.min || 0}
              max={filter.max || 100}
              step={filter.step || 1}
              value={rangeValue.max}
              onChange={(e) =>
                handleFilterChange(filter.id, {
                  min: rangeValue.min,
                  max: Number(e.target.value),
                })
              }
              className="w-full"
              disabled={filter.disabled}
            />
          </div>
        );
      }

      case 'date':
        return (
          <div key={filter.id} className="space-y-2">
            <Label>{filter.label}</Label>
            <DatePicker
              value={value ? new Date(value) : undefined}
              onChange={(date) => {
                if (date instanceof Date) {
                  handleFilterChange(filter.id, date.toISOString());
                }
              }}
              minDate={filter.minDate}
              maxDate={filter.maxDate}
              placeholder={filter.placeholder || `Sélectionner une date`}
              disabled={filter.disabled}
            />
          </div>
        );

      default:
        return null;
    }
  };

  return (
    <div className={cn('space-y-4', className)}>
      {filters.map((filter) => renderFilter(filter))}

      {showReset && onReset && hasActiveFilters() && (
        <div className="pt-2 border-t">
          <Button
            variant="outline"
            onClick={handleReset}
            className="w-full sm:w-auto"
          >
            <RotateCcw className="h-4 w-4 mr-2" />
            {resetLabel}
          </Button>
        </div>
      )}
    </div>
  );
}
