import { useEffect, useState, useCallback, useRef } from "react";
import { EntityTagPickerBaseProps, EntityType, Tag } from "./types";

export const UNASSIGNED_DRIVER = {
  id: -2,
  name: "Driver",
  label: "Unassigned Driver",
}

export const BASE_MARGIN = 45;

const ALL_TAGS_ID = -99;

const allTagsSelection = (entity: EntityType) => {
  return {
    id: ALL_TAGS_ID,
    name: EntityType.Tag,
    label: `All ${entity}`,
    color: "#007bff",
  };
};

export const useTags = ({
  entity,
  value,
  disableUntaggedSelection = false,
  disableTagSelection = false,
  multiple = true,
  onChange,
  tags,
  units,
  drivers,
  landmarks,
  geofences,
  forms,
  subusers,
  assets = [],
  hideTagsWithoutEntities,
  onlyTags = false,
  inheritance = false,
  enableSelectAll = false,
  includeInactiveDrivers = false
}: Pick<
  EntityTagPickerBaseProps,
  | "entity"
  | "value"
  | "disableUntaggedSelection"
  | "disableTagSelection"
  | "multiple"
  | "onChange"
  | "tags"
  | "units"
  | "drivers"
  | "landmarks"
  | "geofences"
  | "forms"
  | "subusers"
  | "assets"
  | "hideTagsWithoutEntities"
  | "onlyTags"
  | "inheritance"
  | "enableSelectAll"
> & { includeInactiveDrivers?: boolean }) => {
  const [expanded, setExpanded] = useState<{ [key: number]: Tag[] }>({});
  const hasInitialExpanded = useRef(false);

  useEffect(() => {
    setExpanded({});
    hasInitialExpanded.current = false;
  }, [entity]);

  const getEntities = useCallback(() => {
    if (entity === EntityType.Unit && units?.length > 0) {
      return units?.map((unit) => ({
        id: unit.id,
        name: EntityType.Unit,
        label: unit.label,
      }));

    }

    if (entity === EntityType.Driver && drivers?.length > 0) {
      const driversToShow = includeInactiveDrivers
        ? drivers
        : drivers.filter((d) => d.status !== 0);
      return driversToShow?.map((driver) => ({
        id: driver.driverId,
        name: EntityType.Driver,
        label: driver.name,
        status: driver.status,
      }));
    }

    if (entity === EntityType.Landmark && landmarks?.length > 0) {
      return landmarks?.map((landmark) => ({
        id: landmark.id,
        name: EntityType.Landmark,
        label: landmark.name,
      }));
    }
    
    if (entity === EntityType.Geofence && geofences?.length > 0) {
      return geofences?.map((geofence) => ({
        id: geofence.id,
        name: EntityType.Geofence,
        label: geofence.name,
      }));
    }
    
    
    if (entity === EntityType.Form && forms?.length > 0) {
      return forms?.map((form) => ({
        id: form.id,
        name: EntityType.Form,
        label: form.name,
      }));
    }
    
    if (entity === EntityType.User && subusers?.length > 0) {
      return subusers?.map((subuser) => ({
        id: subuser.id,
        name: EntityType.User,
        label: subuser.userName,
      }));
    }
    
    return [];
  }, [units, drivers, landmarks, geofences, forms, subusers, entity, includeInactiveDrivers]);

  const getLandmarksCount = useCallback(
    (tag: Tag) => {
      const count = landmarks?.filter((landmark) =>
        landmark.tags?.some((t: Tag) => t.id === tag.id)
      );
      return count?.length || 0;
    },
    [landmarks]
  );

  const getGeofencesCount = useCallback(
    (tag: Tag) => {
      const count = geofences?.filter((geofence) =>
        geofence.tags?.some((t: Tag) => t.id === tag.id)
      );
      return count?.length || 0;
    },
    [geofences]
  );

  const getFormsCount = useCallback(
    (tag: Tag) => {
      const count = forms?.filter((form) =>
        form.tags?.some((t: Tag) => t.id === tag.id)
      );
      return count?.length || 0;
    },
    [forms]
  );

  const getAssetsCount = useCallback((tag: Tag) => {
    const count = assets?.filter((asset) =>
      asset.tags?.some((t: Tag) => t.id === tag.id)
    );
    return count?.length || 0;
  }, [assets]);

  const getSubusersCount = useCallback((tag: Tag) => {
    const count = subusers?.filter((subuser) =>
      subuser.tags?.some((t: Tag) => t.id === tag.id)
    );
    return count?.length || 0;
  }, [subusers]);

  const getDriversCount = useCallback(
    (tag: Tag) => {
      const driversWithTag = drivers?.filter((driver) =>
        driver.tags?.some((t: Tag) => t.id === tag.id)
      );
      if (includeInactiveDrivers) {
        return driversWithTag?.length || 0;
      }
      const activeOnly = driversWithTag?.filter((driver) => driver.status !== 0);
      return activeOnly?.length || 0;
    },
    [drivers, includeInactiveDrivers]
  );

  const getEntityCount = useCallback(
    (tag: Tag) => {
      
      if (entity === EntityType.Unit) {
        return tag?.unitsCount || 0;
      } else if (entity === EntityType.Driver) {
        return getDriversCount(tag);
      } else if (entity === EntityType.Landmark) {
        return getLandmarksCount(tag);
      } else if (entity === EntityType.Geofence) {
        return getGeofencesCount(tag);
      } else if (entity === EntityType.Form) {
        return getFormsCount(tag);
      } else if (entity === EntityType.User) {
        return getSubusersCount(tag);
      } else if (entity === EntityType.Asset) {
        return getAssetsCount(tag);
      }
      return 0;
    },
    [entity, getDriversCount, getLandmarksCount, getGeofencesCount, getFormsCount, getSubusersCount, getAssetsCount]
  );

  const hasEntitiesInSelfOrDescendants = useCallback(
    (tagId: number): boolean => {
      const tag = tags?.find((t) => t.id === tagId);
      if (!tag) return false;

      if (getEntityCount(tag) > 0) return true;

      const children = tags?.filter((t) => t.parentId === tagId) || [];
      return children.some((child) => hasEntitiesInSelfOrDescendants(child.id));
    },
    [tags, getEntityCount]
  );

  const getParentsTags = useCallback(() => {
    if (!tags || tags.length === 0) return [];
    const rootTags = tags.filter(
      (tag) => tag.level === 0 || (tag.level === undefined && tag.parentId === null)
    );
    const result = rootTags
      .map((tag) => {
        const entitiesCount = getEntityCount(tag);
        const hasDescendants = hasEntitiesInSelfOrDescendants(tag.id);
        const included =
          entitiesCount > 0 ||
          hasDescendants ||
          !hideTagsWithoutEntities ||
          onlyTags;
        if (included) {
          return {
            ...tag,
            name: "Tag",
            entitiesCount: entitiesCount,
          };
        }
        return null;
      })
      .filter((tag) => tag !== null);
    return result;
  }, [tags, drivers, getEntityCount, hasEntitiesInSelfOrDescendants, hideTagsWithoutEntities, landmarks, geofences, forms, subusers, assets]);

  const getEntityData = useCallback(
    (tagId: number) => {
      switch (entity) {
        case EntityType.Unit:
          const unitsTags = units?.filter((unit) =>
            unit.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedUnitsTags = unitsTags?.map((unit: any) => ({
            id: unit.id,
            name: EntityType.Unit,
            label: unit.label,
            parentId: tagId,
          }));

          return formattedUnitsTags || [];
        case EntityType.Driver:
          let driversTags = drivers?.filter((driver) =>
            driver.tags?.some((tag: Tag) => tag.id === tagId)
          );

          if (!includeInactiveDrivers) {
            driversTags = driversTags?.filter((driver) => driver.status !== 0);
          }

          const formattedDriversTags = driversTags?.map((driver: any) => ({
            id: driver.driverId,
            name: EntityType.Driver,
            label: driver.name,
            parentId: tagId,
            status: driver.status,
          }));

          return formattedDriversTags || [];
        case EntityType.Landmark:
          const landmarksTags = landmarks?.filter((landmark) =>
            landmark.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedLandmarksTags = landmarksTags?.map((landmark: any) => ({
            id: landmark.id,
            name: EntityType.Landmark,
            label: landmark.name,
            parentId: tagId,
          }));

          return formattedLandmarksTags || [];
        case EntityType.Geofence:
          const geofencesTags = geofences?.filter((geofence) =>
            geofence.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedGeofencesTags = geofencesTags?.map((geofence: any) => ({
            id: geofence.id,
            name: EntityType.Geofence,
            label: geofence.name,
            parentId: tagId,
          }));

          return formattedGeofencesTags || [];
        case EntityType.Form:
          const formsTags = forms?.filter((form) =>
            form.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedFormsTags = formsTags?.map((form: any) => ({
            id: form.id,
            name: EntityType.Form,
            label: form.name,
            parentId: tagId,
          }));

          return formattedFormsTags || [];
        case EntityType.User:
          const subusersTags = subusers?.filter((subuser) =>
            subuser.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedSubusersTags = subusersTags?.map((subuser: any) => ({
            id: subuser.id,
            name: EntityType.User,
            label: subuser.userName,
            parentId: tagId,
          }));

          return formattedSubusersTags || [];
        case EntityType.Asset:
          const assetsTags = assets?.filter((asset) =>
            asset.tags?.some((tag: Tag) => tag.id === tagId)
          );

          const formattedAssetsTags = assetsTags?.map((asset: any) => ({
            id: asset.id,
            name: EntityType.Asset,
            label: asset.label,
            parentId: tagId,
          }));

          return formattedAssetsTags || [];
          default:
          return [];
      }
    },
    [entity, units, drivers, landmarks, geofences, forms, subusers, assets, includeInactiveDrivers]
  );

  const getExpandedData = useCallback(
    (tagId: number, disabled: boolean = false) => {
      const childrenTags = tags?.filter((tag) => tag.parentId === tagId);

      const formattedChildrenTags = childrenTags
        .map((tag: Tag) => ({
          ...tag,
          name: EntityType.Tag,
          entitiesCount: getEntityCount(tag),
        }))
        .filter((tag) => {
          if (!hideTagsWithoutEntities || onlyTags) return true;
          return (
            (tag.entitiesCount ?? 0) > 0 || hasEntitiesInSelfOrDescendants(tag.id)
          );
        });

      if(onlyTags || disabled) return [...formattedChildrenTags]

      const entitiesData = getEntityData(tagId);

      return [...entitiesData, ...formattedChildrenTags];
    },
    [tags, getEntityCount, getEntityData, hasEntitiesInSelfOrDescendants, hideTagsWithoutEntities, onlyTags, landmarks, geofences, forms, units, drivers, subusers]
  );

  const onExpand = useCallback(
    (tagId: number, disabled: boolean = false) => {
      let newExpanded: { [key: number]: Tag[] } = { ...expanded };
      if (expanded[tagId as keyof typeof expanded]) {
        delete newExpanded[tagId];
      } else {
        newExpanded[tagId] = getExpandedData(tagId, disabled) as unknown as Tag[];
      }
      setExpanded(newExpanded);
    },
    [expanded, getExpandedData]
  );

  const defineMarginLeft = useCallback(
    (depth: number, isTag: boolean, hasChildren: boolean) => {     

      if (depth === 0 && !hasChildren && isTag) {
        return `${BASE_MARGIN - 15}px`;
      }

      // Para todos los demás casos, usar un margen proporcional a la profundidad
      // Esto asegura que los tags hijos salgan justo debajo de su padre con indentación consistente
      return `${depth * BASE_MARGIN}px`;
    },
    []
  );

  const getAllDescendants = useCallback(
    (tagId: number): any[] => {
      const descendants: any[] = [];
      
      // Obtener tags hijos directos
      const childrenTags = tags?.filter((tag) => tag.parentId === tagId) || [];
      
      childrenTags.forEach((childTag: Tag) => {
        // Agregar el tag hijo
        descendants.push({
          ...childTag,
          name: EntityType.Tag,
          entitiesCount: getEntityCount(childTag),
        });
        
        // Recursivamente obtener descendientes del tag hijo
        const childDescendants = getAllDescendants(childTag.id);
        descendants.push(...childDescendants);
      });
      
      // Agregar entidades relacionadas a este tag
      if (!onlyTags) {
        const entitiesData = getEntityData(tagId);
        descendants.push(...entitiesData);
      }
      
      return descendants;
    },
    [tags, getEntityCount, getEntityData, onlyTags]
  );

  const expandAllDescendants = useCallback(
    (tagId: number): { [key: number]: Tag[] } => {
      const expansions: { [key: number]: Tag[] } = {};
      
      // Expandir el tag actual
      expansions[tagId] = getExpandedData(tagId) as unknown as Tag[];
      
      // Obtener todos los tags hijos
      const childrenTags = tags?.filter((tag) => tag.parentId === tagId) || [];
      
      // Recursivamente expandir cada tag hijo
      childrenTags.forEach((childTag: Tag) => {
        const childExpansions = expandAllDescendants(childTag.id);
        Object.assign(expansions, childExpansions);
      });
      
      return expansions;
    },
    [tags, getExpandedData]
  );

  const getParentTag = useCallback((parentId: number) => {
    return tags?.find(tag => tag.id === parentId);
  }, [tags]);

  const handleCheckboxChange = useCallback(
    (item: any, isSearching: boolean = false) => {
      let newSelected: any[] = [];
      const hasAllTagsSelected = value?.some((v: any) => v.id === ALL_TAGS_ID);
      
      // Caso especial: Si value incluye -99
      if (hasAllTagsSelected) {
        // Si se está intentando deseleccionar algo (ya está seleccionado porque todos están seleccionados)
        // Debemos quitar el -99 y devolver todos los items EXCEPTO el que se está desmarcando
        const allSelectableItems = getAllSelectableItems();
        
        if (inheritance && item.name === EntityType.Tag) {
          // Si es un tag con herencia, excluir el tag y todos sus descendientes
          const descendants = getAllDescendants(item.id);
          const idsToExclude = new Set([item.id, ...descendants.map(d => d.id)]);
          newSelected = allSelectableItems.filter(i => !idsToExclude.has(i.id));
        } else {
          // Excluir solo el item desmarcado
          newSelected = allSelectableItems.filter(i => i.id !== item.id);
        }
        
        if (onChange) onChange(newSelected, entity);
        return;
      }
      
      const exists = value?.some((v: any) => v.id === item.id);
      
      if (exists) {
        // Deseleccionar el item
        if (inheritance && item.name === EntityType.Tag) {
          // Si es un tag con herencia, deseleccionar todos los descendientes
          const descendants = getAllDescendants(item.id);
          const descendantIds = descendants.map(d => d.id);
          newSelected = value?.filter((v: any) => v.id !== item.id && !descendantIds.includes(v.id)) || [];
        } else {
          // Deseleccionar solo el item
          newSelected = value?.filter((v: any) => v.id !== item.id) || [];
          
          // Si tiene herencia y tiene parentId, deseleccionar el padre también
          if (inheritance && item.parentId) {
            const parent = getParentTag(item.parentId);
            if (parent && value?.some((v: any) => v.id === parent.id)) {
              newSelected = newSelected.filter((v: any) => v.id !== parent.id);
            }
          }
        }
      } else {
        // Seleccionar el item
        if (inheritance && item.name === EntityType.Tag) {
          // Si es un tag con herencia, expandir y seleccionar todos los descendientes
          const descendants = getAllDescendants(item.id);
          
          // Expandir todos los niveles
          const allExpansions = expandAllDescendants(item.id);
          setExpanded((prevExpanded) => ({
            ...prevExpanded,
            ...allExpansions
          }));
          
          // Filtrar descendientes que no estén ya seleccionados
          const existingIds = new Set(value?.map((v: any) => v.id) || []);
          const newDescendants = descendants.filter(d => !existingIds.has(d.id));
          
          newSelected = [...(value || []), item, ...newDescendants];
        } else {
          newSelected = [...(value || []), item];
        }
        
        
        // Verificar si ahora todos los items están seleccionados manualmente
        if (enableSelectAll && !isSearching) {
          const allSelectableItems = getAllSelectableItems();
          const allItemIds = allSelectableItems.map(i => ({ id: i.id, name: i.name }));
          const allAreSelected = allItemIds.every(i => 
            newSelected.some((v: any) => v.id === i.id && v.name === i.name)
          );

          // Si todos están seleccionados, reemplazar con el objeto -99
          if (allAreSelected && !isSearching) {
            newSelected = [allTagsSelection(entity)];
          }
        }
      }

      if (onChange) onChange(newSelected, entity);
    },
    [value, onChange, entity, inheritance, getAllDescendants, expandAllDescendants, getParentTag, enableSelectAll]
  );

  const isItemDisabled = useCallback(
    (item: any) => {
      let disabled =
        item?.disabled ||
        (disableUntaggedSelection && item.id == ALL_TAGS_ID)
          ? true
          : false;

      if (item?.name === EntityType.Tag && disableTagSelection) {
        disabled = true;
      }

      if (
        !multiple &&
        value?.length &&
        value.length > 0 &&
        !value.some((v: any) => v.id === item.id)
      ) {
        disabled = true;
      }

      return disabled;
    },
    [disableUntaggedSelection, disableTagSelection, multiple, value]
  );

  const isItemChecked = useCallback(
    (item: any) => {

      if (item.disabled) {
        return false;
      }

      // Si value incluye -99, todos los items están checked menos los tags deshabilitados
      if (value?.some((v: any) => v.id === ALL_TAGS_ID)) {
        return true;
      }
      
      // Verificar normalmente si el item está en value
      return value?.some((v: any) => v.id === item.id);
    },
    [value]
  );

  const isItemIndeterminate = useCallback(
    (item: any) => {
      // Si value incluye -99, ningún item puede estar indeterminado
      if (value?.some((v: any) => v.id === ALL_TAGS_ID)) {
        return false;
      }
      
      if (!inheritance || item.name !== EntityType.Tag) {
        // Lógica original para cuando no hay herencia
        return value?.some((v: any) => v?.parentId === item?.id) && !value?.some((v: any) => v.id === item.id);
      }

      // Verificar si el item está seleccionado
      const isChecked = value?.some((v: any) => v.id === item.id);
      
      // Si está seleccionado, no puede estar indeterminado
      if (isChecked) {
        return false;
      }

      // Obtener todos los descendientes directos e indirectos
      const allDescendants = getAllDescendants(item.id);
      
      if (allDescendants.length === 0) {
        return false;
      }

      // Contar cuántos descendientes están seleccionados
      const selectedDescendantsCount = allDescendants.filter(
        descendant => value?.some((v: any) => v.id === descendant.id)
      ).length;

      // Está indeterminado si al menos uno (pero no todos) están seleccionados
      return selectedDescendantsCount > 0 && selectedDescendantsCount < allDescendants.length;
    },
    [inheritance, value, getAllDescendants]
  );

  const getParentTags = useCallback((tagId: number, allTags: Tag[]): number[] => {
    const tag = allTags.find(t => t.id === tagId);
    if (!tag || !tag.parentId) {
      return [];
    }
    const parentIds = [tag.parentId];
    const grandParents = getParentTags(tag.parentId, allTags);
    return [...parentIds, ...grandParents];
  }, []);

  useEffect(() => {
    if (!value || value.length === 0 || !tags || tags.length === 0) return;
    if (hasInitialExpanded.current) return;

    const selectedWithParent = value.filter((v: any) => v.parentId);
    
    if (selectedWithParent.length === 0) return;

    const parentIdsToExpand = new Set<number>();
    
    selectedWithParent.forEach((item: any) => {
      if (item.parentId) {
        parentIdsToExpand.add(item.parentId);
        const ancestors = getParentTags(item.parentId, tags);
        ancestors.forEach(parentId => parentIdsToExpand.add(parentId));
      }
    });

    if (parentIdsToExpand.size > 0) {
      setExpanded((prevExpanded) => {
        let newExpanded = { ...prevExpanded };
        parentIdsToExpand.forEach((parentId) => {
          if (!newExpanded[parentId]) {
            newExpanded[parentId] = getExpandedData(parentId) as unknown as Tag[];
          }
        });
        return newExpanded;
      });
      hasInitialExpanded.current = true;
    }
  }, [tags, value, getParentTags, getExpandedData]);

  const getAllTags = useCallback(() => {
    if (!tags || tags.length === 0) return [];
    return tags
      .map((tag: Tag) => {
        const entitiesCount = getEntityCount(tag);
        if (
          entitiesCount > 0 ||
          hasEntitiesInSelfOrDescendants(tag.id) ||
          !hideTagsWithoutEntities ||
          onlyTags
        ) {
          return {
            ...tag,
            name: EntityType.Tag,
            entitiesCount: entitiesCount,
          };
        }
        return null;
      })
      .filter((tag) => tag !== null);
  }, [tags, getEntityCount, hasEntitiesInSelfOrDescendants, hideTagsWithoutEntities, onlyTags]);

  const getAllSelectableItems = useCallback(() => {
    const allItems: any[] = [];
    
    if (!tags || tags.length === 0) return allItems;
    
    // Obtener todos los tags que NO están deshabilitados
    const allTagsAvailable = tags
      .filter((tag: Tag) => !tag.disabled)
      .map((tag: Tag) => ({
        ...tag,
        name: EntityType.Tag,
        entitiesCount: getEntityCount(tag),
      }));
    
    allItems.push(...allTagsAvailable);
    
    // Si no es solo tags, incluir todas las entidades asociadas a cada tag (que no esté deshabilitado)
    if (!onlyTags) {
      allTagsAvailable.forEach((tag: any) => {
        const entitiesForTag = getEntityData(tag.id);
        // Filtrar entidades que también podrían estar deshabilitadas
        const enabledEntities = entitiesForTag.filter((entity: any) => !entity.disabled);
        allItems.push(...enabledEntities);
      });
    }
    
    return allItems;
  }, [tags, getEntityCount, onlyTags, getEntityData]);

  const isAllSelected = useCallback(() => {
    if (!enableSelectAll || !tags || tags.length === 0) return false;
    
    // Si el value contiene el id -1, entonces todos están seleccionados
    if (value?.some((v: any) => v.id === ALL_TAGS_ID)) {
      return true;
    }
    
    const allSelectableItems = getAllSelectableItems();
    
    if (allSelectableItems.length === 0) return false;
    
    // Verificar si todos los items (tags + entidades) están seleccionados
    const allItemIds = allSelectableItems.map(item => ({ id: item.id, name: item.name }));
    
    return allItemIds.every(item => 
      value?.some((v: any) => v.id === item.id && v.name === item.name)
    );
  }, [enableSelectAll, tags, value, getAllSelectableItems]);

  const handleSelectAllChange = useCallback(() => {
    if (!enableSelectAll) return;
    
    const allSelected = isAllSelected();
    
    let newSelected: any[] = [];

    if (allSelected) {
      // Deseleccionar todos los tags y entidades
      newSelected = [];
    } else {
      // En lugar de devolver todos los tags individuales, devolver solo el objeto con id -99
      newSelected = [allTagsSelection(entity)];
      
      // Expandir todos los tags para visualización (opcional, pero útil para el usuario)
      const allExpansions: { [key: number]: Tag[] } = {};
      tags
        .filter((tag: Tag) => !tag.disabled)
        .forEach((tag: Tag) => {
          if (inheritance) {
            // Si hay herencia, expandir todos los descendientes
            const expansions = expandAllDescendants(tag.id);
            Object.assign(allExpansions, expansions);
          } else {
            // Expandir solo el primer nivel
            allExpansions[tag.id] = getExpandedData(tag.id) as unknown as Tag[];
          }
        });
      setExpanded(allExpansions);
    }

    if (onChange) onChange(newSelected, entity);
  }, [enableSelectAll, isAllSelected, onChange, entity, tags, inheritance, expandAllDescendants, getExpandedData]);

  const getEntityList = useCallback((searchText: string) => {
    switch (entity) {
      case EntityType.Unit:
        const unitsList = units?.filter((unit) => unit.label.toLowerCase().includes(searchText.toLowerCase()));
        return unitsList?.map((unit) => ({
          id: unit.id,
          name: EntityType.Unit,
          label: unit.label,
        }));
      case EntityType.Driver:
        const driversList = drivers?.filter((driver) => driver.name.toLowerCase().includes(searchText.toLowerCase()));
        return driversList?.map((driver) => ({
          id: driver.driverId,
          name: EntityType.Driver,
          label: driver.name,
          status: driver.status,
        }));

      case EntityType.Landmark:
        const landmarksList = landmarks?.filter((landmark) => landmark.name.toLowerCase().includes(searchText.toLowerCase()));
        return landmarksList?.map((landmark) => ({
          id: landmark.id,
          name: EntityType.Landmark,
          label: landmark.name,
        }));
      case EntityType.Geofence:
        const geofencesList = geofences?.filter((geofence) => geofence.name.toLowerCase().includes(searchText.toLowerCase()));
        return geofencesList?.map((geofence) => ({
          id: geofence.id,
          name: EntityType.Geofence,
          label: geofence.name,
        }));
      case EntityType.Form:
        const formsList = forms?.filter((form) => form.name.toLowerCase().includes(searchText.toLowerCase()));
        return formsList?.map((form) => ({
          id: form.id,
          name: EntityType.Form,
          label: form.name,
        }));
      case EntityType.User:
        const subusersList = subusers?.filter((subuser) => subuser.userName.toLowerCase().includes(searchText.toLowerCase()));
        return subusersList?.map((subuser) => ({
          id: subuser.id,
          name: EntityType.User,
          label: subuser.userName,
        }));
      case EntityType.Asset:
        return assets?.filter((asset) => asset.label.toLowerCase().includes(searchText.toLowerCase()));
      default:
        return [];
    }
  }, [getEntityData]);

  return {
    expanded,
    getParentsTags,
    onExpand,
    defineMarginLeft,
    handleCheckboxChange,
    isItemDisabled,
    isItemChecked,
    isItemIndeterminate,
    getAllTags,
    isAllSelected,
    handleSelectAllChange,
    getEntities,
    getEntityList
  };
};

