import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Checkbox } from '@/components/ui/checkbox';
import { Separator } from '@/components/ui/separator';
import { RotateCcw } from 'lucide-react';
import { supabase } from '@/integrations/supabase/client';
import { FilterRangeSlider } from '@/components/filters/FilterRangeSlider';
import { FilterDateRangePicker } from '@/components/filters/FilterDateRangePicker';
import { FilterSection } from '@/components/filters/FilterSection';
import { FilterMultiSelectCombobox } from '@/components/filters/FilterMultiSelectCombobox';
import { MultiSelectOption } from '@/components/ui/multi-select-combobox';
import { Ride } from '@/types/database';
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
import { 
  convertValueToMetric, 
  convertValueFromMetric, 
  getDisplayUnit 
} from '@/lib/units';

export interface RideFilterState {
  categories: string[];
  status: string;
  countries: string[];
  statesProvinces: string[];
  cities: string[];
  parks: string[];
  manufacturers: string[];
  designers: string[];
  coasterTypes: string[];
  seatingTypes: string[];
  intensityLevels: string[];
  trackMaterials: string[];
  supportMaterials: string[];
  propulsionMethods: string[];
  minSpeed: number;
  maxSpeed: number;
  minHeight: number;
  maxHeight: number;
  minLength: number;
  maxLength: number;
  minInversions: number;
  maxInversions: number;
  openingDateFrom: Date | null;
  openingDateTo: Date | null;
  hasInversions: boolean;
  operatingOnly: boolean;
}

export const defaultRideFilters: RideFilterState = {
  categories: [],
  status: 'all',
  countries: [],
  statesProvinces: [],
  cities: [],
  parks: [],
  manufacturers: [],
  designers: [],
  coasterTypes: [],
  seatingTypes: [],
  intensityLevels: [],
  trackMaterials: [],
  supportMaterials: [],
  propulsionMethods: [],
  minSpeed: 0,
  maxSpeed: 200,
  minHeight: 0,
  maxHeight: 150,
  minLength: 0,
  maxLength: 3000,
  minInversions: 0,
  maxInversions: 14,
  openingDateFrom: null,
  openingDateTo: null,
  hasInversions: false,
  operatingOnly: false,
};

interface RideFiltersProps {
  filters: RideFilterState;
  onFiltersChange: (filters: RideFilterState) => void;
  rides: Ride[];
}

export function RideFilters({ filters, onFiltersChange, rides }: RideFiltersProps) {
  const { preferences } = useUnitPreferences();
  const system = preferences.measurement_system;

  // Fetch unique filter options
  const { data: locations } = useQuery({
    queryKey: ['filter-locations'],
    queryFn: async () => {
      const { data } = await supabase
        .from('locations')
        .select('country, state_province, city')
        .not('country', 'is', null);
      return data || [];
    },
    staleTime: 5 * 60 * 1000,
  });

  const { data: parks } = useQuery({
    queryKey: ['filter-parks'],
    queryFn: async () => {
      const { data } = await supabase
        .from('parks')
        .select('id, name')
        .order('name');
      return data || [];
    },
    staleTime: 5 * 60 * 1000,
  });

  const { data: manufacturers } = useQuery({
    queryKey: ['filter-manufacturers'],
    queryFn: async () => {
      const { data } = await supabase
        .from('companies')
        .select('id, name')
        .eq('company_type', 'manufacturer')
        .order('name');
      return data || [];
    },
    staleTime: 5 * 60 * 1000,
  });

  const { data: designers } = useQuery({
    queryKey: ['filter-designers'],
    queryFn: async () => {
      const { data } = await supabase
        .from('companies')
        .select('id, name')
        .eq('company_type', 'designer')
        .order('name');
      return data || [];
    },
    staleTime: 5 * 60 * 1000,
  });

  const countryOptions: MultiSelectOption[] = useMemo(() => {
    const countries = new Set(locations?.map(l => l.country).filter(Boolean) || []);
    return Array.from(countries).sort().map(c => ({ label: c, value: c }));
  }, [locations]);

  const stateOptions: MultiSelectOption[] = useMemo(() => {
    const states = new Set(locations?.map(l => l.state_province).filter((s): s is string => s != null) || []);
    return Array.from(states).sort().map(s => ({ label: s, value: s }));
  }, [locations]);

  const cityOptions: MultiSelectOption[] = useMemo(() => {
    const cities = new Set(locations?.map(l => l.city).filter((c): c is string => c != null) || []);
    return Array.from(cities).sort().map(c => ({ label: c, value: c }));
  }, [locations]);

  const parkOptions: MultiSelectOption[] = useMemo(() => {
    return (parks || []).map(p => ({ label: p.name, value: p.id }));
  }, [parks]);

  const manufacturerOptions: MultiSelectOption[] = useMemo(() => {
    return (manufacturers || []).map(m => ({ label: m.name, value: m.id }));
  }, [manufacturers]);

  const designerOptions: MultiSelectOption[] = useMemo(() => {
    return (designers || []).map(d => ({ label: d.name, value: d.id }));
  }, [designers]);

  const categoryOptions: MultiSelectOption[] = [
    { label: 'Roller Coasters', value: 'roller_coaster' },
    { label: 'Flat Rides', value: 'flat_ride' },
    { label: 'Water Rides', value: 'water_ride' },
    { label: 'Dark Rides', value: 'dark_ride' },
    { label: 'Kiddie Rides', value: 'kiddie_ride' },
    { label: 'Transportation', value: 'transportation' },
  ];

  const statusOptions = [
    { value: 'all', label: 'All Status' },
    { value: 'operating', label: 'Operating' },
    { value: 'seasonal', label: 'Seasonal' },
    { value: 'under_construction', label: 'Under Construction' },
    { value: 'closed', label: 'Closed' },
  ];

  const coasterTypeOptions: MultiSelectOption[] = [
    { label: 'Steel', value: 'steel' },
    { label: 'Wood', value: 'wood' },
    { label: 'Hybrid', value: 'hybrid' },
    { label: 'Inverted', value: 'inverted' },
    { label: 'Suspended', value: 'suspended' },
    { label: 'Flying', value: 'flying' },
    { label: 'Wing', value: 'wing' },
    { label: 'Dive', value: 'dive' },
  ];

  const seatingTypeOptions: MultiSelectOption[] = [
    { label: 'Sit Down', value: 'sit_down' },
    { label: 'Stand Up', value: 'stand_up' },
    { label: 'Inverted', value: 'inverted' },
    { label: 'Flying', value: 'flying' },
    { label: 'Floorless', value: 'floorless' },
  ];

  const intensityOptions: MultiSelectOption[] = [
    { label: 'Family', value: 'family' },
    { label: 'Moderate', value: 'moderate' },
    { label: 'Thrill', value: 'thrill' },
    { label: 'Extreme', value: 'extreme' },
  ];

  const trackMaterialOptions: MultiSelectOption[] = [
    { label: 'Steel', value: 'steel' },
    { label: 'Wood', value: 'wood' },
  ];

  const supportMaterialOptions: MultiSelectOption[] = [
    { label: 'Steel', value: 'steel' },
    { label: 'Wood', value: 'wood' },
  ];

  const propulsionMethodOptions: MultiSelectOption[] = [
    { label: 'Chain Lift', value: 'chain_lift' },
    { label: 'Cable Lift', value: 'cable_lift' },
    { label: 'Launched (LIM/LSM)', value: 'launched_lim_lsm' },
    { label: 'Hydraulic Launch', value: 'hydraulic_launch' },
    { label: 'Compressed Air', value: 'compressed_air' },
    { label: 'Flywheel', value: 'flywheel' },
    { label: 'Gravity', value: 'gravity' },
    { label: 'Other', value: 'other' },
  ];

  // Calculate display ranges based on user preferences
  const speedUnit = getDisplayUnit('km/h', system);
  const heightUnit = getDisplayUnit('m', system);
  const lengthUnit = getDisplayUnit('m', system);

  // Convert metric filter ranges to display units for sliders
  const displaySpeedMin = Math.round(convertValueFromMetric(0, speedUnit, 'km/h'));
  const displaySpeedMax = Math.round(convertValueFromMetric(200, speedUnit, 'km/h'));
  const displayHeightMin = Math.round(convertValueFromMetric(0, heightUnit, 'm'));
  const displayHeightMax = Math.round(convertValueFromMetric(150, heightUnit, 'm'));
  const displayLengthMin = Math.round(convertValueFromMetric(0, lengthUnit, 'm'));
  const displayLengthMax = Math.round(convertValueFromMetric(3000, lengthUnit, 'm'));

  // Convert current metric filter values to display units
  const currentSpeedMin = Math.round(convertValueFromMetric(filters.minSpeed, speedUnit, 'km/h'));
  const currentSpeedMax = Math.round(convertValueFromMetric(filters.maxSpeed, speedUnit, 'km/h'));
  const currentHeightMin = Math.round(convertValueFromMetric(filters.minHeight, heightUnit, 'm'));
  const currentHeightMax = Math.round(convertValueFromMetric(filters.maxHeight, heightUnit, 'm'));
  const currentLengthMin = Math.round(convertValueFromMetric(filters.minLength, lengthUnit, 'm'));
  const currentLengthMax = Math.round(convertValueFromMetric(filters.maxLength, lengthUnit, 'm'));

  const resetFilters = () => {
    onFiltersChange(defaultRideFilters);
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h3 className="text-lg font-semibold">Filter Rides</h3>
        <Button variant="ghost" size="sm" onClick={resetFilters}>
          <RotateCcw className="w-4 h-4 mr-2" />
          Reset
        </Button>
      </div>

      {/* Basic Filters */}
      <FilterSection title="Basic Filters">
        <div className="grid grid-cols-1 gap-4">
          <FilterMultiSelectCombobox
            label="Categories"
            options={categoryOptions}
            value={filters.categories}
            onChange={(value) => onFiltersChange({ ...filters, categories: value })}
            placeholder="Select categories"
          />

          <div className="space-y-2">
            <Label>Status</Label>
            <Select
              value={filters.status}
              onValueChange={(value) => onFiltersChange({ ...filters, status: value })}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {statusOptions.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>
      </FilterSection>

      <Separator />

      {/* Geographic Filters */}
      <FilterSection title="Location">
        <div className="grid grid-cols-1 gap-4">
          <FilterMultiSelectCombobox
            label="Countries"
            options={countryOptions}
            value={filters.countries}
            onChange={(value) => onFiltersChange({ ...filters, countries: value })}
            placeholder="Select countries"
          />
          <FilterMultiSelectCombobox
            label="States/Provinces"
            options={stateOptions}
            value={filters.statesProvinces}
            onChange={(value) => onFiltersChange({ ...filters, statesProvinces: value })}
            placeholder="Select states"
          />
          <FilterMultiSelectCombobox
            label="Cities"
            options={cityOptions}
            value={filters.cities}
            onChange={(value) => onFiltersChange({ ...filters, cities: value })}
            placeholder="Select cities"
          />
        </div>
      </FilterSection>

      <Separator />

      {/* Relationship Filters */}
      <FilterSection title="Parks & Companies">
        <div className="grid grid-cols-1 gap-4">
          <FilterMultiSelectCombobox
            label="Parks"
            options={parkOptions}
            value={filters.parks}
            onChange={(value) => onFiltersChange({ ...filters, parks: value })}
            placeholder="Select parks"
          />
          <FilterMultiSelectCombobox
            label="Manufacturers"
            options={manufacturerOptions}
            value={filters.manufacturers}
            onChange={(value) => onFiltersChange({ ...filters, manufacturers: value })}
            placeholder="Select manufacturers"
          />
          <FilterMultiSelectCombobox
            label="Designers"
            options={designerOptions}
            value={filters.designers}
            onChange={(value) => onFiltersChange({ ...filters, designers: value })}
            placeholder="Select designers"
          />
        </div>
      </FilterSection>

      <Separator />

      {/* Coaster-Specific Filters */}
      <FilterSection title="Coaster Details">
        <div className="grid grid-cols-1 gap-4">
          <FilterMultiSelectCombobox
            label="Coaster Type"
            options={coasterTypeOptions}
            value={filters.coasterTypes}
            onChange={(value) => onFiltersChange({ ...filters, coasterTypes: value })}
            placeholder="Select types"
          />
          <FilterMultiSelectCombobox
            label="Seating Type"
            options={seatingTypeOptions}
            value={filters.seatingTypes}
            onChange={(value) => onFiltersChange({ ...filters, seatingTypes: value })}
            placeholder="Select seating"
          />
          <FilterMultiSelectCombobox
            label="Intensity"
            options={intensityOptions}
            value={filters.intensityLevels}
            onChange={(value) => onFiltersChange({ ...filters, intensityLevels: value })}
            placeholder="Select intensity"
          />
          <FilterMultiSelectCombobox
            label="Track Material"
            options={trackMaterialOptions}
            value={filters.trackMaterials}
            onChange={(value) => onFiltersChange({ ...filters, trackMaterials: value })}
            placeholder="Select material"
          />
          <FilterMultiSelectCombobox
            label="Support Material"
            options={supportMaterialOptions}
            value={filters.supportMaterials}
            onChange={(value) => onFiltersChange({ ...filters, supportMaterials: value })}
            placeholder="Select support material"
          />
          <FilterMultiSelectCombobox
            label="Propulsion Method"
            options={propulsionMethodOptions}
            value={filters.propulsionMethods}
            onChange={(value) => onFiltersChange({ ...filters, propulsionMethods: value })}
            placeholder="Select propulsion"
          />
        </div>
      </FilterSection>

      <Separator />

      {/* Numeric Range Filters */}
      <FilterSection title="Statistics">
        <div className="grid grid-cols-1 gap-4">
          <FilterRangeSlider
            label="Speed"
            value={[currentSpeedMin, currentSpeedMax]}
            onChange={([displayMin, displayMax]) => {
              // Convert display values back to metric for storage
              const metricMin = Math.round(convertValueToMetric(displayMin, speedUnit));
              const metricMax = Math.round(convertValueToMetric(displayMax, speedUnit));
              onFiltersChange({ ...filters, minSpeed: metricMin, maxSpeed: metricMax });
            }}
            min={displaySpeedMin}
            max={displaySpeedMax}
            step={system === 'metric' ? 5 : 2}
            formatValue={(v) => `${v} ${speedUnit}`}
          />
          <FilterRangeSlider
            label="Height"
            value={[currentHeightMin, currentHeightMax]}
            onChange={([displayMin, displayMax]) => {
              // Convert display values back to metric for storage
              const metricMin = Math.round(convertValueToMetric(displayMin, heightUnit));
              const metricMax = Math.round(convertValueToMetric(displayMax, heightUnit));
              onFiltersChange({ ...filters, minHeight: metricMin, maxHeight: metricMax });
            }}
            min={displayHeightMin}
            max={displayHeightMax}
            step={system === 'metric' ? 5 : 10}
            formatValue={(v) => `${v} ${heightUnit}`}
          />
          <FilterRangeSlider
            label="Length"
            value={[currentLengthMin, currentLengthMax]}
            onChange={([displayMin, displayMax]) => {
              // Convert display values back to metric for storage
              const metricMin = Math.round(convertValueToMetric(displayMin, lengthUnit));
              const metricMax = Math.round(convertValueToMetric(displayMax, lengthUnit));
              onFiltersChange({ ...filters, minLength: metricMin, maxLength: metricMax });
            }}
            min={displayLengthMin}
            max={displayLengthMax}
            step={system === 'metric' ? 50 : 100}
            formatValue={(v) => `${v} ${lengthUnit}`}
          />
          <FilterRangeSlider
            label="Inversions"
            value={[filters.minInversions, filters.maxInversions]}
            onChange={([min, max]) => onFiltersChange({ ...filters, minInversions: min, maxInversions: max })}
            min={0}
            max={14}
            step={1}
          />
        </div>
      </FilterSection>

      <Separator />

      {/* Date Filters */}
      <FilterSection title="Dates">
        <div className="grid grid-cols-1 gap-4">
          <FilterDateRangePicker
            label="Opening Date"
            fromDate={filters.openingDateFrom}
            toDate={filters.openingDateTo}
            onFromChange={(date) => onFiltersChange({ ...filters, openingDateFrom: date || null })}
            onToChange={(date) => onFiltersChange({ ...filters, openingDateTo: date || null })}
            fromPlaceholder="From year"
            toPlaceholder="To year"
          />
        </div>
      </FilterSection>

      <Separator />

      {/* Boolean Filters */}
      <FilterSection title="Other Options">
        <div className="space-y-3">
          <div className="flex items-center space-x-2">
            <Checkbox
              id="hasInversions"
              checked={filters.hasInversions}
              onCheckedChange={(checked) =>
                onFiltersChange({ ...filters, hasInversions: checked as boolean })
              }
            />
            <Label htmlFor="hasInversions" className="cursor-pointer">
              Has inversions
            </Label>
          </div>
          <div className="flex items-center space-x-2">
            <Checkbox
              id="operatingOnly"
              checked={filters.operatingOnly}
              onCheckedChange={(checked) =>
                onFiltersChange({ ...filters, operatingOnly: checked as boolean })
              }
            />
            <Label htmlFor="operatingOnly" className="cursor-pointer">
              Operating only
            </Label>
          </div>
        </div>
      </FilterSection>
    </div>
  );
}
