/**
 * KRA - Dictionary Utility Functions
 * Dictionary lookup and caching utilities
 */

export interface DictionaryItem {
  label: string;
  value: any;
  extend?: string;
  children?: DictionaryItem[];
}

/**
 * Filter tree data by depth
 * @param items - Tree items
 * @param currentDepth - Current depth level
 * @param targetDepth - Target depth (0 = all)
 * @returns Filtered tree items
 */
export const filterTreeByDepth = (
  items: DictionaryItem[],
  currentDepth: number,
  targetDepth: number
): DictionaryItem[] => {
  if (targetDepth === 0) {
    return items;
  }

  if (currentDepth >= targetDepth) {
    return items.map((item) => ({
      label: item.label,
      value: item.value,
      extend: item.extend,
    }));
  }

  return items.map((item) => ({
    label: item.label,
    value: item.value,
    extend: item.extend,
    children: item.children
      ? filterTreeByDepth(item.children, currentDepth + 1, targetDepth)
      : undefined,
  }));
};

/**
 * Flatten tree structure to array
 * @param items - Tree items
 * @returns Flat array of items
 */
export const flattenTree = (items: DictionaryItem[]): DictionaryItem[] => {
  const result: DictionaryItem[] = [];

  const traverse = (nodes: DictionaryItem[]) => {
    nodes.forEach((item) => {
      result.push({
        label: item.label,
        value: item.value,
        extend: item.extend,
      });

      if (item.children && item.children.length > 0) {
        traverse(item.children);
      }
    });
  };

  traverse(items);
  return result;
};

/**
 * Normalize tree data to standard format
 * @param items - Tree items
 * @returns Normalized tree items
 */
export const normalizeTreeData = (items: DictionaryItem[]): DictionaryItem[] => {
  return items.map((item) => ({
    label: item.label,
    value: item.value,
    extend: item.extend,
    children:
      item.children && item.children.length > 0
        ? normalizeTreeData(item.children)
        : undefined,
  }));
};

/**
 * Find node by value in tree
 * @param items - Tree items
 * @param targetValue - Value to find
 * @param currentDepth - Current depth
 * @param maxDepth - Max depth (0 = unlimited)
 * @returns Children of found node or null
 */
export const findNodeByValue = (
  items: DictionaryItem[],
  targetValue: any,
  currentDepth: number = 1,
  maxDepth: number = 0
): DictionaryItem[] | null => {
  for (const item of items) {
    if (item.value === targetValue) {
      if (maxDepth === 0) {
        return item.children ? normalizeTreeData(item.children) : [];
      }
      if (item.children && item.children.length > 0) {
        return filterTreeByDepth(item.children, 1, maxDepth);
      }
      return [];
    }

    if (
      item.children &&
      item.children.length > 0 &&
      (maxDepth === 0 || currentDepth < maxDepth)
    ) {
      const result = findNodeByValue(
        item.children,
        targetValue,
        currentDepth + 1,
        maxDepth
      );
      if (result !== null) {
        return result;
      }
    }
  }
  return null;
};

/**
 * Find label by value in dictionary
 * @param items - Dictionary items
 * @param value - Value to find
 * @returns Label string or undefined
 */
export const findLabelByValue = (
  items: DictionaryItem[],
  value: any
): string | undefined => {
  for (const item of items) {
    if (item.value === value) {
      return item.label;
    }
    if (item.children && item.children.length > 0) {
      const found = findLabelByValue(item.children, value);
      if (found) return found;
    }
  }
  return undefined;
};

/**
 * Build cache key for dictionary
 * @param type - Dictionary type
 * @param depth - Depth level
 * @param value - Optional value filter
 * @returns Cache key string
 */
export const buildCacheKey = (
  type: string,
  depth: number = 0,
  value?: any
): string => {
  if (value !== null && value !== undefined) {
    return `${type}_value_${value}_depth_${depth}`;
  }
  return depth === 0 ? `${type}_tree` : `${type}_depth_${depth}`;
};

/**
 * Get dictionary items by type
 * This is a simple wrapper that fetches dictionary data from API
 * @param type - Dictionary type
 * @returns Promise of dictionary items
 */
export const getDict = async (type: string): Promise<DictionaryItem[]> => {
  try {
    const { getDictionaryTreeListByType } = await import('@/services/kratos/dictionaryDetail');
    const res = await getDictionaryTreeListByType({ type });
    if (res.code === 0 && res.data?.list) {
      return res.data.list.map((item: any) => ({
        label: item.label || item.value,
        value: item.value,
        extend: item.extend,
      }));
    }
    return [];
  } catch (error) {
    console.error('Failed to get dictionary:', error);
    return [];
  }
};

export default {
  filterTreeByDepth,
  flattenTree,
  normalizeTreeData,
  findNodeByValue,
  findLabelByValue,
  buildCacheKey,
  getDict,
};
