import { DrupalJsonApiParams } from 'drupal-jsonapi-params';

/**
 * Parses a JSON:API URL into component parameters
 */
export const parseUrlToParameters = (url, setters) => {
  const {
    setSelectedEntity,
    setSelectedBundle,
    setSelectedFields,
    setIncludes,
    setFilters,
    setSorts,
    setPage,
    setLimit
  } = setters;

  try {
    // Extract the path and query parameters
    const urlObj = new URL(url);
    const path = urlObj.pathname.split('/');
    const queryString = urlObj.search.startsWith('?') ? urlObj.search.substring(1) : urlObj.search;

    // Extract entity type and bundle from the path
    if (path.length >= 4) {
      const entityPath = path[path.length - 2];
      const bundlePath = path[path.length - 1];

      // Set entity and bundle
      setSelectedEntity(entityPath);
      setSelectedBundle(bundlePath);

      // Use drupal-jsonapi-params to parse the query string
      const apiParams = new DrupalJsonApiParams();
      apiParams.initializeWithQueryString(queryString);
      const params = apiParams.getQueryObject();

      // Process fields (sparse fieldsets)
      if (params.fields) {
        // Find fields for the current entity type
        const entityType = `${entityPath}--${bundlePath}`;
        if (params.fields[entityType]) {
          const fields = params.fields[entityType].split(',');
          setSelectedFields(fields);
        } else {
          setSelectedFields([]);
        }
      } else {
        setSelectedFields([]);
      }

      // Process includes
      if (params.include && params.include.length > 0) {
        const includeFields = Array.isArray(params.include) ? params.include : params.include.split(',');
        setIncludes(includeFields);
      } else {
        setIncludes([]);
      }

      // Process filters - complex part
      if (params.filter) {
        const newFilters = [];
        const groupsMap = {}; // Maps group IDs to filter objects
        const conditionsMap = {}; // Maps condition ID to their memberships

        // Process each filter entry
        Object.entries(params.filter).forEach(([key, value]) => {
          // Case 1: This is a group definition
          if (value.group && value.group.conjunction) {
            const groupId = Date.now() + '_' + key; // Create a unique internal ID
            const groupName = `Group ${newFilters.filter(f => f.group).length + 1}`;

            // Create the group object
            const group = {
              group: true,
              groupId: groupId,
              groupName: groupName,
              conjunction: value.group.conjunction,
              members: [],
              externalId: key // Store original group ID for reference
            };

            groupsMap[key] = group;
            newFilters.push(group);
          }
          // Case 2: This is a condition with a field, operator, and value
          else if (value.condition && value.condition.path) {
            const condition = value.condition;

            // Create a filter object
            const filter = {
              field: condition.path,
              operator: condition.operator || 'value', // Default to value if no operator
              value: condition.value !== undefined ? condition.value : ''
            };

            // Check if this condition belongs to a group
            if (condition.memberOf && groupsMap[condition.memberOf]) {
              // Add to group members
              groupsMap[condition.memberOf].members.push(filter);
            } else {
              // Add as standalone filter
              newFilters.push(filter);
            }
          }
          // Case 3: Simple filter with operator shorthand (filter[title][CONTAINS]=foo)
          else if (typeof value === 'object' && !Array.isArray(value) && value.operator) {
            const filter = {
              field: key,
              operator: value.operator,
              value: value.value || ''
            };
            newFilters.push(filter);
          }
          // Case 4: Simple filter (filter[status]=1)
          else if (typeof value !== 'object') {
            const filter = {
              field: key,
              operator: 'value', // Default operator for simple filters
              value: String(value)
            };
            newFilters.push(filter);
          }
        });

        setFilters(newFilters);
      } else {
        setFilters([]);
      }

      // Process sorts
      if (params.sort && params.sort.length > 0) {
        const sortFields = Array.isArray(params.sort) ? params.sort : params.sort.split(',');
        const newSorts = sortFields.map(field => {
          if (field.startsWith('-')) {
            return { field: field.substring(1), direction: 'desc' };
          } else {
            return { field, direction: 'asc' };
          }
        });

        setSorts(newSorts);
      } else {
        setSorts([]);
      }

      // Process pagination
      if (params.page) {
        if (params.page.limit) {
          setLimit(parseInt(params.page.limit, 10));
        } else {
          setLimit(10);
        }

        if (params.page.offset && params.page.limit) {
          setPage(Math.floor(parseInt(params.page.offset, 10) / parseInt(params.page.limit, 10)));
        } else {
          setPage(0);
        }
      } else {
        setLimit(10);
        setPage(0);
      }
    }
  } catch (err) {
    console.error('Error parsing URL:', err);
    throw new Error('Error parsing URL parameters');
  }
};
