/**
 * Filter Group Field Component
 *
 * A generic, schema-driven filter builder component that can be used
 * for any integration that needs filter/query building capabilities.
 *
 * This replaces integration-specific filter builders like NotionFilterGroupBuilder
 * by reading the filter configuration from the schema.
 */

import { memo } from 'react';
import { Plus, X, Filter } from 'lucide-react';
import { Button } from '../ui/button';
import { Card } from '../ui/card';
import { Label } from '../ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';
import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group';
import { ActionField } from '../../types/action';
import { FilterGroupValue, FilterConditionValue } from '../../types/schema';
import { AvailableContext } from '../../hooks/useAvailableContext';
import { VariableInput } from '../VariableInput';

interface Property {
  id: string;
  name: string;
  type: string;
}

interface FilterGroupFieldComponentProps {
  fieldName: string;
  field: ActionField;
  value?: FilterGroupValue;
  onChange: (value: FilterGroupValue) => void;
  availableContext: AvailableContext;
  properties: Array<Record<string, string>>;
  isLoadingProperties?: boolean;
  propertyError?: string;
  error?: string;
}

interface FilterConditionRowProps {
  condition: FilterConditionValue;
  index: number;
  properties: Property[];
  conditionMappings: Record<string, string[]>;
  valueNotRequired: string[];
  availableContext: AvailableContext;
  onChange: (index: number, condition: FilterConditionValue) => void;
  onRemove: (index: number) => void;
  canRemove: boolean;
}

function FilterConditionRow({
  condition,
  index,
  properties,
  conditionMappings,
  valueNotRequired,
  availableContext,
  onChange,
  onRemove,
  canRemove,
}: FilterConditionRowProps) {
  const selectedProperty = properties.find((p) => p.id === condition.property);
  const propertyType = selectedProperty?.type || condition.property_type || '';
  const availableConditions = conditionMappings[propertyType] || [];
  const showValueInput = !valueNotRequired.includes(condition.condition);

  const handlePropertyChange = (propertyId: string) => {
    const prop = properties.find((p) => p.id === propertyId);
    onChange(index, {
      ...condition,
      property: propertyId,
      property_type: prop?.type || '',
      // Reset condition when property changes
      condition: '',
      value: '',
    });
  };

  const handleConditionChange = (conditionValue: string) => {
    onChange(index, {
      ...condition,
      condition: conditionValue,
      // Clear value if condition doesn't require it
      value: valueNotRequired.includes(conditionValue) ? undefined : condition.value,
    });
  };

  const handleValueChange = (value: string) => {
    onChange(index, {
      ...condition,
      value,
    });
  };

  return (
    <div className="flex items-center gap-2 flex-wrap">
      <span className="text-sm text-muted-foreground shrink-0">Where</span>

      {/* Property selector */}
      <Select value={condition.property || ''} onValueChange={handlePropertyChange}>
        <SelectTrigger className="w-[180px]">
          <SelectValue placeholder="Select property" />
        </SelectTrigger>
        <SelectContent>
          {properties.map((prop) => (
            <SelectItem key={prop.id} value={prop.id}>
              {prop.name}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>

      {/* Condition selector - only show if property selected */}
      {condition.property && availableConditions.length > 0 && (
        <Select value={condition.condition || ''} onValueChange={handleConditionChange}>
          <SelectTrigger className="w-[160px]">
            <SelectValue placeholder="Select condition" />
          </SelectTrigger>
          <SelectContent>
            {availableConditions.map((cond) => (
              <SelectItem key={cond} value={cond}>
                {formatConditionLabel(cond)}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      )}

      {/* Value input - only show if condition requires it */}
      {condition.condition && showValueInput && (
        <div className="flex-1 min-w-[200px]">
          <VariableInput
            value={condition.value || ''}
            onChange={handleValueChange}
            availableContext={availableContext}
            placeholder="Enter value or @variable"
          />
        </div>
      )}

      {/* Remove button */}
      {canRemove && (
        <Button
          type="button"
          variant="ghost"
          size="icon"
          onClick={() => onRemove(index)}
          className="shrink-0 h-8 w-8 text-muted-foreground hover:text-destructive"
        >
          <X className="h-4 w-4" />
        </Button>
      )}
    </div>
  );
}

/**
 * Format a condition key into a human-readable label
 */
function formatConditionLabel(condition: string): string {
  return condition.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
}

export const FilterGroupFieldComponent = memo(function FilterGroupFieldComponent({
  fieldName: _fieldName,
  field,
  value,
  onChange,
  availableContext,
  properties: rawProperties,
  isLoadingProperties,
  propertyError,
  error,
}: FilterGroupFieldComponentProps) {
  const filterConfig = field.filter_config;
  if (!filterConfig) {
    return null;
  }

  const conditionMappings = filterConfig.condition_mappings || {};
  const operators = filterConfig.operators || ['and', 'or'];
  const valueNotRequired = filterConfig.value_not_required || [];

  // Normalize properties to common format
  const properties: Property[] = rawProperties.map((p) => ({
    id: p.id || p.value || '',
    name: p.name || p.label || '',
    type: p.type || 'text',
  }));

  // Initialize with default value if needed
  const filterValue: FilterGroupValue = value || {
    operator: 'and',
    conditions: [],
  };

  const handleOperatorChange = (operator: 'and' | 'or') => {
    onChange({
      ...filterValue,
      operator,
    });
  };

  const handleConditionChange = (index: number, condition: FilterConditionValue) => {
    const newConditions = [...filterValue.conditions];
    newConditions[index] = condition;
    onChange({
      ...filterValue,
      conditions: newConditions,
    });
  };

  const handleAddCondition = () => {
    onChange({
      ...filterValue,
      conditions: [
        ...filterValue.conditions,
        { property: '', property_type: '', condition: '', value: '' },
      ],
    });
  };

  const handleRemoveCondition = (index: number) => {
    const newConditions = filterValue.conditions.filter((_, i) => i !== index);
    onChange({
      ...filterValue,
      conditions: newConditions,
    });
  };

  const handleClearAll = () => {
    onChange({
      operator: 'and',
      conditions: [],
    });
  };

  const hasConditions = filterValue.conditions.length > 0;

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <Label className="flex items-center gap-2">
          <Filter className="h-4 w-4" />
          {field.label}
        </Label>
        {hasConditions && (
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={handleClearAll}
            className="text-muted-foreground hover:text-destructive"
          >
            Clear all
          </Button>
        )}
      </div>

      {field.description && <p className="text-sm text-muted-foreground">{field.description}</p>}

      {isLoadingProperties && (
        <p className="text-sm text-muted-foreground">Loading available properties...</p>
      )}

      {propertyError && <p className="text-sm text-destructive">{propertyError}</p>}

      {!isLoadingProperties && properties.length === 0 && !propertyError && (
        <p className="text-sm text-muted-foreground">
          Select a data source first to enable filtering.
        </p>
      )}

      {properties.length > 0 && (
        <Card className="p-4">
          {hasConditions ? (
            <div className="space-y-3">
              {/* Operator toggle */}
              {operators.length > 1 && filterValue.conditions.length > 1 && (
                <div className="flex items-center gap-2 mb-4">
                  <span className="text-sm text-muted-foreground">Match</span>
                  <ToggleGroup
                    type="single"
                    value={filterValue.operator}
                    onValueChange={(val) => val && handleOperatorChange(val as 'and' | 'or')}
                  >
                    {operators.includes('and') && (
                      <ToggleGroupItem value="and" size="sm">
                        All
                      </ToggleGroupItem>
                    )}
                    {operators.includes('or') && (
                      <ToggleGroupItem value="or" size="sm">
                        Any
                      </ToggleGroupItem>
                    )}
                  </ToggleGroup>
                  <span className="text-sm text-muted-foreground">of the following:</span>
                </div>
              )}

              {/* Condition rows */}
              <div className="space-y-2">
                {filterValue.conditions.map((condition, index) => (
                  <FilterConditionRow
                    key={index}
                    condition={condition}
                    index={index}
                    properties={properties}
                    conditionMappings={conditionMappings}
                    valueNotRequired={valueNotRequired}
                    availableContext={availableContext}
                    onChange={handleConditionChange}
                    onRemove={handleRemoveCondition}
                    canRemove={filterValue.conditions.length > 0}
                  />
                ))}
              </div>

              {/* Add condition button */}
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={handleAddCondition}
                className="mt-2"
              >
                <Plus className="h-4 w-4 mr-2" />
                Add condition
              </Button>
            </div>
          ) : (
            <div className="text-center py-4">
              <p className="text-sm text-muted-foreground mb-3">
                No filter conditions defined. Results will include all items.
              </p>
              <Button type="button" variant="outline" size="sm" onClick={handleAddCondition}>
                <Plus className="h-4 w-4 mr-2" />
                Add filter conditions
              </Button>
            </div>
          )}
        </Card>
      )}

      {error && <p className="text-sm text-destructive">{error}</p>}
    </div>
  );
});
