// treeUtils.ts
import { TreeViewItem } from "@/shared/common/ui/treeSelect";

import { UseFormReturn } from "react-hook-form";

// Helper to get all checked items (including from children)
export const getCheckedItems = (items: TreeViewItem[]): TreeViewItem[] => {
  let checkedItems: TreeViewItem[] = [];
  items.forEach((item) => {
    if (item.checked) {
      checkedItems.push(item);
    }
    if (item.children) {
      checkedItems = [...checkedItems, ...getCheckedItems(item.children)];
    }
  });
  return checkedItems;
};

// Update children's checked state (only when parent is explicitly changed)
export const updateChildrenState = (
  children: TreeViewItem[],
  checked: boolean
): TreeViewItem[] => {
  return children.map((child) => ({
    ...child,
    checked,
    children: child.children
      ? updateChildrenState(child.children, checked)
      : undefined,
  }));
};

// Update parent state based on children
export const updateParentState = (item: TreeViewItem): TreeViewItem => {
  if (!item.children || item.children.length === 0) {
    return item;
  }

  const allChildrenChecked = item.children.every((child) => child.checked);
  const someChildrenChecked = item.children.some((child) => child.checked);

  return {
    ...item,
    checked: allChildrenChecked
      ? true
      : someChildrenChecked
      ? "indeterminate"
      : false,
    children: item.children.map(updateParentState),
  };
};

// Main function to update check state
export const updateCheckState = (
  treeItems: TreeViewItem[],
  itemsArray: TreeViewItem[],
  checked: boolean
): TreeViewItem[] => {
  return treeItems
    .map((currentItem) => {
      // Check if current item is in the changed items
      const isItemChanged = itemsArray.some(
        (item) => item.id === currentItem.id
      );

      if (isItemChanged) {
        // Update this item and all its children
        return {
          ...currentItem,
          checked,
          children: currentItem.children
            ? updateChildrenState(currentItem.children, checked)
            : undefined,
        };
      }

      // If not changed, check children recursively
      if (currentItem.children) {
        return {
          ...currentItem,
          children: updateCheckState(currentItem.children, itemsArray, checked),
        };
      }

      return currentItem;
    })
    .map(updateParentState); // Update parent states after children are updated
};

// Get only the checked items from the tree
export const getAllCheckedItems = (tree: TreeViewItem[]): TreeViewItem[] => {
  return tree.flatMap((item) => {
    const checkedItems: TreeViewItem[] = [];

    // Only include items that are explicitly checked (not indeterminate)
    if (item.checked === true && item.children?.length == 0) {
      checkedItems.push({
        id: item.id,
        name: item.name,
        hierarchyType: item.hierarchyType,
        checked: item.checked,
      });
    }

    // Recursively check children
    if (item.children) {
      checkedItems.push(...getAllCheckedItems(item.children));
    }

    return checkedItems;
  });
};

export const getLeafCheckedItems = (tree: TreeViewItem[]): TreeViewItem[] => {
  return getAllCheckedItems(tree);
};

// Main handler function
export function handleTreeViewChange(
  items: TreeViewItem | TreeViewItem[],
  checked: boolean,
  fieldName: string,
  options: TreeViewItem[],
  setOptions: React.Dispatch<React.SetStateAction<TreeViewItem[]>>,
  form: UseFormReturn<any>
) {
  const itemsArray = Array.isArray(items) ? items : [items];
  
  // Update the tree state
  const updatedOptions = updateCheckState(options, itemsArray, checked);
  

  setOptions(updatedOptions);

  // Get only the leaf nodes that are checked
  const leafCheckedItems = getLeafCheckedItems(updatedOptions);
  
  form.setValue(fieldName, leafCheckedItems);
}

export const getCheckedLeafNodes = (tree: TreeViewItem[]): TreeViewItem[] => {
  const checkedItems: TreeViewItem[] = [];

  tree?.forEach((item) => {
    if (item.checked === true) {
      checkedItems.push({
        id: item.id,
        name: item.name,
        hierarchyType: item.hierarchyType,
        checked: true,
      });
    }

    if (item.children) {
      checkedItems.push(...getCheckedLeafNodes(item.children));
    }
  });

  return checkedItems;
};
