import React, { useState, useEffect } from 'react';
import GroupedFieldSelect from './GroupedFieldSelect';

function FilterSelector({ selectedEntity, selectedBundle, filters, onFiltersChange, relatedEntityFields, baseUrl }) {
  const [newFilter, setNewFilter] = useState({ field: '', operator: 'value', value: '' });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [directFields, setDirectFields] = useState([]);
  const [newGroupConjunction, setNewGroupConjunction] = useState('AND');
  const [newGroupName, setNewGroupName] = useState('');
  const [selectedGroup, setSelectedGroup] = useState('');

  useEffect(() => {
    if (selectedEntity && selectedBundle) {
      fetchFields();
    } else {
      setDirectFields([]);
    }
  }, [selectedEntity, selectedBundle]);

  const fetchFields = async () => {
    if (!selectedEntity || !selectedBundle) return;

    setLoading(true);
    setError(null);

    try {
      // Use the baseUrl prop passed from the parent component
      const jsonApiBase = baseUrl;
      const resourceType = `${selectedEntity}--${selectedBundle}`;

      console.log(`Fetching fields for filters (${resourceType})`);

      // Use the OpenAPI endpoint instead of resource/schema
      const openApiUrl = drupalSettings.path.baseUrl + "openapi/jsonapi"
      console.log('Using OpenAPI endpoint for filters:', openApiUrl);

      const response = await fetch(openApiUrl);

      if (response.ok) {
        const data = await response.json();
        console.log('Schema data for filters:', data);

        // Extract fields from the schema
        let fieldNames = [];
        let relationshipNames = [];

        // Find the schema for this entity type and bundle in OpenAPI definitions
        if (data && data.definitions && data.definitions[resourceType]) {
          const resourceSchema = data.definitions[resourceType];
          console.log(`Found schema for ${resourceType} in OpenAPI 2.0 definitions`);

          // In OpenAPI 2.0, entity fields are in data.attributes.properties
          if (resourceSchema.properties?.data?.properties?.attributes?.properties) {
            const attributes = resourceSchema.properties.data.properties.attributes.properties;
            console.log(`Found ${Object.keys(attributes).length} attributes for filters in OpenAPI schema`);

            Object.entries(attributes).forEach(([field, def]) => {
              // If the field is an object with sub-properties, add only its leaf subfields (e.g., body.value, body.format, etc.)
              if (def.type === 'object' && def.properties) {
                Object.keys(def.properties).forEach(subfield => {
                  fieldNames.push(`${field}.${subfield}`);
                });
              } else {
                fieldNames.push(field);
              }
            });
          }

          // In OpenAPI 2.0, relationships are in data.relationships.properties
          if (resourceSchema.properties?.data?.properties?.relationships?.properties) {
            const relationships = resourceSchema.properties.data.properties.relationships.properties;
            console.log(`Found ${Object.keys(relationships).length} relationships for filters in OpenAPI schema`);

            Object.keys(relationships).forEach(rel => {
              relationshipNames.push(rel);
            });
          }
        }

        // If schema not found or no fields found, try looking in other entities as a fallback
        if (fieldNames.length === 0 && relationshipNames.length === 0 && data && data.definitions) {
          console.log(`Schema for ${resourceType} not found or has no fields/relationships. Checking other schemas...`);

          // Look for any entity type that might have similar structure
          Object.keys(data.definitions).forEach(defKey => {
            // Only check entity-like definitions (skip utility schemas)
            if (defKey.includes('--') && data.definitions[defKey].properties?.data?.properties) {
              const def = data.definitions[defKey];

              // Check for attributes
              if (def.properties.data.properties.attributes?.properties && fieldNames.length === 0) {
                console.log(`Using attributes from ${defKey} as reference`);
                Object.keys(def.properties.data.properties.attributes.properties).forEach(field => {
                  if (!fieldNames.includes(field)) {
                    fieldNames.push(field);
                  }
                });
              }

              // Check for relationships
              if (def.properties.data.properties.relationships?.properties && relationshipNames.length === 0) {
                console.log(`Using relationships from ${defKey} as reference`);
                Object.keys(def.properties.data.properties.relationships.properties).forEach(rel => {
                  if (!relationshipNames.includes(rel)) {
                    relationshipNames.push(rel);
                  }
                });
              }

              // If we've found both attributes and relationships, stop searching
              if (fieldNames.length > 0 && relationshipNames.length > 0) {
                return;
              }
            }
          });
        }

        // For basic identification fields
        if (fieldNames.length > 0) {
          // Make sure id and uuid are available for filtering
          if (!fieldNames.includes('id')) fieldNames.push('id');
          if (!fieldNames.includes('uuid')) fieldNames.push('uuid');
        }

        // Combine field names only; relationship attribute paths come via relatedEntityFields.
        let allFilterFields = [...fieldNames];

        if (allFilterFields.length > 0) {
          console.log('Final filter fields extracted:', allFilterFields);
          // Store direct fields separately
          setDirectFields(allFilterFields.sort());
        } else {
          console.warn('Could not extract fields from schema for filters, falling back to basic fields');
          const basicFields = ['id', 'uuid', 'title', 'name', 'created', 'changed'];
          setDirectFields(basicFields);
        }
      } else {
        console.log('Schema endpoint failed with status:', response.status);
        setError(`Schema endpoint failed with status: ${response.status}`);
      }
    } catch (err) {
      console.error('Error fetching fields for filters:', err);
      setError(`Unable to get fields: ${err.message}`);
    } finally {
      setLoading(false);
    }
  };

  const operatorOptions = [
    // Standard equality (most common)
    { value: 'value', label: 'Equals (=)' },

    // Comparison operators
    { value: '<>', label: 'Not equal (<>)' },
    { value: '>', label: 'Greater than (>)' },
    { value: '>=', label: 'Greater than or equal (>=)' },
    { value: '<', label: 'Less than (<)' },
    { value: '<=', label: 'Less than or equal (<=)' },

    // String matching
    { value: 'CONTAINS', label: 'Contains' },
    { value: 'STARTS_WITH', label: 'Starts with' },
    { value: 'ENDS_WITH', label: 'Ends with' },

    // Set operators
    { value: 'IN', label: 'In list (IN)' },
    { value: 'NOT IN', label: 'Not in list (NOT IN)' },

    // Range operators
    { value: 'BETWEEN', label: 'Between (inclusive)' },
    { value: 'NOT BETWEEN', label: 'Not between' },

    // Null operators
    { value: 'IS NULL', label: 'Is empty (IS NULL)' },
    { value: 'IS NOT NULL', label: 'Is not empty (IS NOT NULL)' },

    // Path for relationships (special case)
    { value: 'path', label: 'Path (relationship.field)' },
  ];

  // Helper to check if a filter is valid
  const isValidFilter = (filter) => {
    // For null operators, we don't need a value
    if (['IS NULL', 'IS NOT NULL'].includes(filter.operator)) {
      return filter.field && filter.operator;
    }
    // For all other operators, we need all fields
    return filter.field && filter.operator && filter.value;
  };

  // Add a filter to the current list or to a group based on dropdown selection
  const handleAddFilter = () => {
    // Check if the filter is valid before adding it
    if (!isValidFilter(newFilter)) {
      return;
    }

    // Create a copy of the filter to add
    const filterToAdd = { ...newFilter };

    // Set value to empty string for NULL operators
    if (['IS NULL', 'IS NOT NULL'].includes(filterToAdd.operator)) {
      filterToAdd.value = '';
    }

    const updatedFilters = [...filters];

    // If adding to a group AND a group is selected from the dropdown
    if (selectedGroup !== '') {
      // Find the group to add to
      const groupIndex = updatedFilters.findIndex(filter =>
          filter.group === true && filter.groupId === selectedGroup
      );

      if (groupIndex !== -1) {
        // If the group exists, add the filter to its members
        if (!updatedFilters[groupIndex].members) {
          updatedFilters[groupIndex].members = [];
        }
        updatedFilters[groupIndex].members.push(filterToAdd);
      } else {
        // If the selected group doesn't exist, add as a regular filter
        updatedFilters.push(filterToAdd);
      }
    } else {
      // If not adding to a group, add as a regular filter
      updatedFilters.push(filterToAdd);
    }

    onFiltersChange(updatedFilters);
    setNewFilter({ field: '', operator: 'value', value: '' });
  };

  // Create a new filter group with the specified conjunction and name
  const handleCreateGroup = () => {
    // Use the provided name or generate a default one
    const groupName = newGroupName.trim() || `Group ${filters.filter(filter => filter.group).length + 1}`;

    // Create a unique ID for the group
    const groupId = Date.now().toString();

    // Create the group object
    const newGroup = {
      group: true,
      groupId,
      groupName,
      conjunction: newGroupConjunction,
      members: []
    };

    // Add the group to filters
    const updatedFilters = [...filters, newGroup];
    onFiltersChange(updatedFilters);

    // Set this as the selected group
    setSelectedGroup(groupId);

    // Reset the name field
    setNewGroupName('');
  };

  // Remove a filter from the main list or from a group
  const handleRemoveFilter = (index, groupId = null) => {
    const updatedFilters = [...filters];

    if (groupId) {
      // If removing from a group, find the group
      const groupIndex = updatedFilters.findIndex(filter =>
          filter.group === true && filter.groupId === groupId
      );

      if (groupIndex !== -1 && updatedFilters[groupIndex].members) {
        // Remove the filter from the group's members
        updatedFilters[groupIndex].members.splice(index, 1);
      }
    } else {
      // If removing from the main list
      updatedFilters.splice(index, 1);
    }

    onFiltersChange(updatedFilters);
  };

  // Remove an entire group
  const handleRemoveGroup = (groupId) => {
    const updatedFilters = filters.filter(filter =>
        !(filter.group === true && filter.groupId === groupId)
    );

    // If removing the selected group, clear it
    if (selectedGroup === groupId) {
      setSelectedGroup('');
    }

    onFiltersChange(updatedFilters);
  };

  // Toggle the conjunction (AND/OR) for a group
  const handleToggleGroupConjunction = (groupId) => {
    const updatedFilters = [...filters];

    // Find the group
    const groupIndex = updatedFilters.findIndex(filter =>
        filter.group === true && filter.groupId === groupId
    );

    if (groupIndex !== -1) {
      // Toggle the conjunction
      updatedFilters[groupIndex].conjunction =
          updatedFilters[groupIndex].conjunction === 'AND' ? 'OR' : 'AND';
    }

    onFiltersChange(updatedFilters);
  };

  // Updated to use the dropdown selector instead of toggling active groups
  const handleGroupSelectionChange = (e) => {
    setSelectedGroup(e.target.value);
  };

  const handleFilterChange = (field, value) => {
    setNewFilter({
      ...newFilter,
      [field]: value
    });
  };

  const handleClearAll = () => {
    onFiltersChange([]);
    setSelectedGroup('');
  };

  // Return appropriate placeholder text based on operator
  const getValuePlaceholder = (operator) => {
    switch(operator) {
      case 'value':
        return 'Enter exact value (e.g. 1, true)';
      case 'path':
        return 'Enter value to match in related entity field';
      case '<>':
      case '>':
      case '>=':
      case '<':
      case '<=':
        return 'Enter comparison value';
      case 'CONTAINS':
        return 'Text to search for';
      case 'STARTS_WITH':
        return 'Text that begins with';
      case 'ENDS_WITH':
        return 'Text that ends with';
      case 'IN':
      case 'NOT IN':
        return 'Comma-separated values (e.g. 1,2,3)';
      case 'BETWEEN':
      case 'NOT BETWEEN':
        return 'Min,Max values (e.g. 5,10)';
      case 'IS NULL':
      case 'IS NOT NULL':
        return 'No value needed for this operator';
      default:
        return 'Enter filter value';
    }
  };

  return (
      <div className="filter-selector form-item">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
          <h4 className="form-item__label" style={{ margin: 0 }}>Filters</h4>
          <button
              className="button button--small"
              onClick={handleClearAll}
              disabled={filters.length === 0}
          >
            Clear
          </button>
        </div>

        {(selectedEntity && selectedBundle) ? (
            <>
              <div className="claro-details">
                <div className="claro-details__wrapper">
                  {loading ? (
                      <div className="form-item__description">
                        <div className="spinner" style={{ display: 'inline-block', marginRight: '8px' }}></div>
                        Loading fields for filtering…
                      </div>
                  ) : error ? (
                      <div className="messages messages--error">
                        {error}
                      </div>
                  ) : (
                      <>

                        {filters.length > 0 ? (
                            <>
                              <h5 className="filter-group-title">Selected filters</h5>
                              <div className="fields-chips">
                                {/* Render standard filters (not in groups) */}
                                {filters.filter(filter => !filter.group).sort().map((filter, index) => (
                                    <span
                                        key={`filter-${index}`}
                                        className={`gin-chip gin-chip--primary ${filter.field.includes('.') ? 'gin-chip--relationship' : ''}`}
                                        title={`Operator: ${filter.operator}, Value: ${filter.value}`}
                                    >
                            {filter.field}: {filter.value}
                                      <button
                                          className="gin-chip--remove"
                                          onClick={() => handleRemoveFilter(index)}
                                          aria-label={`Remove ${filter.field} filter`}
                                      >
                              ✕
                            </button>
                          </span>
                                ))}

                                {/* Render filter groups */}
                                {filters.filter(filter => filter.group).sort().map((group, groupIndex) => {
                                  const actualGroupIndex = filters.findIndex(f => f.group && f.groupId === group.groupId);

                                  return (
                                      <div
                                          key={`group-${group.groupId}`}
                                          className="filter-group"
                                          style={{
                                            border: '1px solid #cbd5e1',
                                            borderRadius: '8px',
                                            padding: '8px 12px',
                                            marginBottom: '8px',
                                            background: '#f8fafc'
                                          }}
                                      >
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
                                          <div>
                                  <span
                                      style={{
                                        fontWeight: 'bold',
                                        display: 'inline-block',
                                        padding: '2px 8px',
                                        marginRight: '8px'
                                      }}
                                  >
                                    {group.groupName}
                                  </span>
                                            <button
                                                className="gin-chip"
                                                onClick={() => handleToggleGroupConjunction(group.groupId)}
                                                style={{
                                                  cursor: 'pointer',
                                                  background: group.conjunction === 'AND' ? '#e0f2fe' : '#fef3c7',
                                                  color: group.conjunction === 'AND' ? '#0369a1' : '#92400e'
                                                }}
                                            >
                                              {group.conjunction}
                                            </button>
                                          </div>
                                          <button
                                              className="gin-chip--remove"
                                              onClick={() => handleRemoveGroup(group.groupId)}
                                              aria-label="Remove filter group"
                                              style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#64748b' }}
                                          >
                                            ✕
                                          </button>
                                        </div>

                                        {/* Group member filters */}
                                        <div className="fields-chips" style={{ paddingLeft: '8px' }}>
                                          {group.members && group.members.length > 0 ? (
                                              group.members.sort().map((filter, memberIndex) => (
                                                  <span
                                                      key={`group-${group.groupId}-member-${memberIndex}`}
                                                      className={`gin-chip ${filter.field.includes('.') ? 'gin-chip--relationship' : ''}`}
                                                      title={`Operator: ${filter.operator}, Value: ${filter.value}`}
                                                  >
                                      {filter.field}: {filter.value}
                                                    <button
                                                        className="gin-chip--remove"
                                                        onClick={() => handleRemoveFilter(memberIndex, group.groupId)}
                                                        aria-label={`Remove ${filter.field} filter`}
                                                    >
                                        ✕
                                      </button>
                                    </span>
                                              ))
                                          ) : (
                                              <div style={{ color: '#64748b', fontStyle: 'italic', fontSize: '0.85em', padding: '4px 0' }}>
                                                No filters in this group yet
                                              </div>
                                          )}
                                        </div>
                                      </div>
                                  );
                                })}
                              </div>
                            </>
                        ) : (
                            <div className="form-item__description">
                              No filters applied yet
                            </div>
                        )}

                        <h5 className="filter-group-title" style={{ marginTop: '16px' }}>Add filter</h5>
                        <div className="sort-selector__inputs-row" style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', marginBottom: '12px' }}>
                          <div className="form-item" style={{ flex: '1 1 200px', minWidth: '150px', marginBottom: '8px' }}>
                            <label className="form-item__label" htmlFor="filter-field">Field</label>
                            <GroupedFieldSelect
                              id="filter-field"
                              value={newFilter.field}
                              onChange={(val) => handleFilterChange('field', val)}
                              directFields={directFields}
                              relatedEntityFields={relatedEntityFields}
                              usedFields={[]}
                            />
                          </div>

                          <div className="form-item" style={{ flex: '1 1 200px', minWidth: '150px', marginBottom: '8px' }}>
                            <label className="form-item__label" htmlFor="filter-operator">Operator</label>
                            <select
                                id="filter-operator"
                                className="form-element"
                                value={newFilter.operator}
                                onChange={(e) => handleFilterChange('operator', e.target.value)}
                            >
                              {operatorOptions.map(op => (
                                  <option key={op.value} value={op.value}>{op.label}</option>
                              ))}
                            </select>
                          </div>

                          {/* Hide value input for NULL operators */}
                          {!['IS NULL', 'IS NOT NULL'].includes(newFilter.operator) && (
                              <div className="form-item" style={{ flex: '1 1 200px', minWidth: '150px', marginBottom: '8px' }}>
                                <label className="form-item__label" htmlFor="filter-value">Value</label>
                                <input
                                    id="filter-value"
                                    type="text"
                                    className="form-element"
                                    value={newFilter.value}
                                    onChange={(e) => handleFilterChange('value', e.target.value)}
                                    placeholder={getValuePlaceholder(newFilter.operator)}
                                />
                              </div>
                          )}
                          {/* Show help text for NULL operators */}
                          {['IS NULL', 'IS NOT NULL'].includes(newFilter.operator) && (
                              <div className="form-item" style={{ flex: '1 1 200px', minWidth: '150px', marginBottom: '8px' }}>
                                <label className="form-item__label">&nbsp;</label>
                                <div className="form-item__description" style={{ fontStyle: 'italic', marginTop: '8px' }}>
                                  No value needed for {newFilter.operator} operator
                                </div>
                              </div>
                          )}
                        </div>

                        <div style={{ marginTop: '8px', marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
                          <button
                              id="filter-add-button"
                              className="button button--small"
                              onClick={handleAddFilter}
                              disabled={!isValidFilter(newFilter)}
                          >
                            Add filter
                          </button>

                          {/* Group selection dropdown for adding filters */}
                          {filters.filter(filter => filter.group).length > 0 && (
                              <div className="form-item" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                                <select
                                    className="form-element"
                                    value={selectedGroup}
                                    onChange={handleGroupSelectionChange}
                                    style={{ minWidth: '150px' }}
                                >
                                  <option value="">Add as standalone filter</option>
                                  {filters.filter(filter => filter.group).map(group => (
                                      <option key={group.groupId} value={group.groupId}>
                                        Add to {group.groupName} ({group.conjunction})
                                      </option>
                                  ))}
                                </select>
                              </div>
                          )}
                        </div>

                        {/* Filter groups section */}
                        <div>
                          <h5 style={{ marginTop: '16px', marginBottom: '8px' }}>Filter groups (AND/OR logic)</h5>
                          <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', marginBottom: '8px' }}>
                            <div className="form-item" style={{ flex: '1 1 200px', minWidth: '150px' }}>
                              <label className="form-item__label" htmlFor="group-name">Group name</label>
                              <input
                                  id="group-name"
                                  type="text"
                                  className="form-element"
                                  value={newGroupName}
                                  onChange={(e) => setNewGroupName(e.target.value)}
                                  placeholder="Enter group name (optional)"
                              />
                            </div>

                            <div className="form-item" style={{ flex: '0 0 100px' }}>
                              <label className="form-item__label" htmlFor="group-conjunction">Logic</label>
                              <select
                                  id="group-conjunction"
                                  className="form-element"
                                  value={newGroupConjunction}
                                  onChange={(e) => setNewGroupConjunction(e.target.value)}
                                  style={{ width: '100px' }}
                              >
                                <option value="AND">AND</option>
                                <option value="OR">OR</option>
                              </select>
                            </div>
                          </div>

                          <div style={{ marginTop: '8px', marginBottom: '8px' }}>
                            <button
                                className="button button--small"
                                onClick={handleCreateGroup}
                            >
                              Create filter group
                            </button>
                          </div>

                          <div className="form-item__description" style={{ fontSize: '0.85em' }}>
                            Use filter groups to create complex AND/OR conditions. You can create multiple groups and choose which one to add filters to.
                          </div>

                          {filters.filter(filter => filter.group).length > 0 && (
                              <div className="form-item__description" style={{ marginTop: '8px', fontSize: '0.85em' }}>
                                <strong>Note:</strong> To add a filter to a specific group, select the group from the dropdown when adding a filter.
                              </div>
                          )}
                        </div>

                        <div className="form-item__description" style={{ marginTop: '8px' }}>
                          {relatedEntityFields && Object.keys(relatedEntityFields).length > 0 && (
                              <div style={{ marginBottom: '8px', color: '#6b84a3' }}>
                                <strong>Note:</strong> Include fields (shown in blue) are available because you have added includes to your query.
                              </div>
                          )}
                        </div>
                      </>
                  )}
                </div>
              </div>
            </>
        ) : (
            <div className="form-item__description">
              Select an entity type and **bundle** to add filters
            </div>
        )}
      </div>
  );
}

export default FilterSelector;
