import type { Dropdown } from "@/types";
import type { InjectionKey } from "vue";

export const DROPDOWN_SYMBOL = Symbol('DROPDOWN_SYMBOL') as InjectionKey<ReturnType<typeof useDropdown>>;

/**
 * 深拷贝一个值
 * @param value 要拷贝的值
 * @returns 深拷贝后的值
 */
const deepClone = (value: any): any => {
  // 如果是基本类型或 null/undefined，直接返回
  if (value == null || typeof value !== 'object') {
    return value;
  }

  // 如果是数组，递归拷贝每个元素
  if (Array.isArray(value)) {
    return value.map(item => deepClone(item));
  }

  // 如果是对象，递归拷贝所有属性
  const cloned: Record<string, any> = {};
  for (const key in value) {
    if (Object.prototype.hasOwnProperty.call(value, key)) {
      cloned[key] = deepClone(value[key]);
    }
  }
  return cloned;
};

/**
 * 深度比较两个值是否严格相等
 * @param a 第一个值
 * @param b 第二个值
 * @returns 是否相等
 */
const deepEqual = (a: any, b: any): boolean => {
  // 如果引用相同，直接返回 true
  if (a === b) return true;

  // 如果其中一个为 null 或 undefined
  if (a == null || b == null) return a === b;

  // 如果类型不同，返回 false
  if (typeof a !== typeof b) return false;

  // 如果是基本类型（非对象），直接比较
  if (typeof a !== 'object') return a === b;

  // 如果是数组
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    return a.every((item, index) => deepEqual(item, b[index]));
  }

  // 如果一个是数组，另一个不是，返回 false
  if (Array.isArray(a) || Array.isArray(b)) return false;

  // 如果是对象，比较所有键值对
  const keysA = Object.keys(a);
  const keysB = Object.keys(b);

  // 键的数量不同，返回 false
  if (keysA.length !== keysB.length) return false;

  // 检查所有键是否都存在且值相等
  for (const key of keysA) {
    if (!keysB.includes(key)) return false;
    if (!deepEqual(a[key], b[key])) return false;
  }

  return true;
};

export const useDropdown = (configs: Dropdown.DropdownItem[]) => {
  const list = computed(() => configs);
  const form = ref<Record<string, any>>({});
  const openIndex = ref<number>(-1);

  const open = (index: number) => {
    openIndex.value = index;
  }
  const close = () => {
    openIndex.value = -1;
  }
  const submit = (index: number, value: any) => {
    form.value = {
      ...form.value,
      [list.value[index].prop]: value
    };
  }
  const reset = (index: number) => {
    form.value = {
      ...form.value,
      [list.value[index].prop]: list.value[index].value
    };
  }
  const init = (initValue: Record<string, any>) => {
    form.value = { ...initValue };
    list.value.forEach(item => {
      item.value = initValue[item.prop] || item.value;
    });
  }

  return {
    init,
    form,
    openIndex,
    open,
    close,
    submit,
    reset,
    deepEqual,
    deepClone
  }
}