import type { VbenFormProps } from '#/adapter/form';
import type { DescItem } from '#/components/description';

import { isFunction } from '@vben/utils';

export const omit = (obj: any, keysToOmit: string[]) => {
  // 如果 obj 不是对象或者 keysToOmit 不是数组，则直接返回 obj
  if (typeof obj !== 'object' || !Array.isArray(keysToOmit)) {
    return obj;
  }

  // 创建一个新的对象，避免修改原始对象
  const result = {} as any;

  // 遍历 obj 的所有键值对
  for (const key in obj) {
    // 如果当前键不在要忽略的键列表中，则复制到新对象
    if (!keysToOmit.includes(key)) {
      result[key] = obj[key];
    }
  }

  return result;
};
export const get = (object: any, path: string) => {
  // 如果 object 不是对象或者 path 不是字符串，则直接返回 defaultValue
  if (
    typeof object !== 'object' ||
    object === null ||
    typeof path !== 'string'
  ) {
    return object;
  }

  // 将路径字符串转换为数组
  const pathArray = path.split('.').filter(Boolean); // 过滤掉空字符串
  let current = object;

  // 遍历路径数组
  for (const element of pathArray) {
    // 如果当前层级不是对象或没有对应的键，则返回 defaultValue
    if (
      typeof current !== 'object' ||
      current === null ||
      !(element in current)
    ) {
      return object;
    }
    // 更新 current 到下一层级
    current = current[element];
  }

  // 返回最终找到的值
  return current;
};
export const ifDetail = (renderCallbackParams: any): boolean => {
  const schema = renderCallbackParams.schema;
  if (isFunction(schema.ifDetail)) {
    return schema.ifDetail(renderCallbackParams);
  }
  return schema.ifDetail !== false;
};

/**
 * 将表单元数据转换为详情表单
 * @param formOptions
 * @param values
 */
export const schemaToDetailForm = (
  formOptions: VbenFormProps,
  values: any,
): DescItem[] => {
  const group: Array<DescItem> = [];
  const formSchemas = formOptions.schema;
  if (!Array.isArray(formSchemas)) return group;
  for (let i = 0; i < formSchemas.length; i++) {
    const item = formSchemas[i];
    // 找到分割线
    if (item?.component === 'Divider') {
      group.push({
        field: item.fieldName,
        label: item.label,
        children: [],
      } as unknown as DescItem);
      // 将分割线后面的数据添加到group中
      for (let j = i + 1; j < formSchemas.length; j++) {
        const nextItem = formSchemas[j];
        // 找到下面的分割线
        if (nextItem?.component === 'Divider') {
          // 中断
          i = j - 1;
          break;
        } else {
          if (
            ifDetail({
              schema: nextItem,
              values,
              model: values,
              field: item.fieldName,
            })
          ) {
            group[group.length - 1]?.children?.push({
              field: nextItem?.fieldName,
              label: nextItem?.label,
              span: nextItem?.detailSpan || 12,
              component: nextItem?.component,
              componentProps: nextItem?.componentProps,
            } as DescItem);
          }
        }
      }
    }
  }
  if (group.length > 0) {
    return group;
  }
  return [
    {
      field: 'baseinfo',
      label: '基本信息',
      children: formSchemas
        .filter((item) => {
          return ifDetail({
            schema: item,
            values,
            model: values,
            field: item.fieldName,
          });
        })
        .map((item) => {
          return {
            field: item.fieldName,
            label: item.label,
            span: item.detailSpan || 12,
            component: item.component,
            componentProps: item.componentProps,
          } as DescItem;
        }),
    } as DescItem,
  ];
};

// 获取子节点id
export const getChildIds = (record: any) => {
  const ids = [record.id];
  record.children?.forEach((item: any) => {
    ids.push(...getChildIds(item));
  });
  return ids;
};

/**
 * 获取所有叶子节点
 * @param treeData
 */
export const getLeafNodeIds = (treeData: any) => {
  const leafNodeIds: any = [];

  function traverse(node: any) {
    // 如果当前节点没有 children 或 children 是空数组，则它是叶子节点
    if (!node.children || node.children.length === 0) {
      leafNodeIds.push(node.id);
    } else {
      // 否则，递归遍历每个子节点
      for (const child of node.children) {
        traverse(child);
      }
    }
  }

  // 遍历树的根节点
  for (const root of treeData) {
    traverse(root);
  }
  return leafNodeIds;
};

/**
 * 获取所有节点id
 * @param treeData
 */
export const getAllNodeIds = (treeData: any) => {
  const allNodeIds: any = [];

  function traverse(node: any) {
    // 收集当前节点的 id
    allNodeIds.push(node.id);

    // 如果当前节点有 children，则递归遍历每个子节点
    if (node.children && node.children.length > 0) {
      for (const child of node.children) {
        traverse(child);
      }
    }
  }

  // 遍历树的根节点
  for (const root of treeData) {
    traverse(root);
  }

  return allNodeIds;
};

/**
 * -转大驼峰
 * @param str
 */
export const toPascalCase = (str: any) => {
  // 将连字符或下划线替换为空格，以便后续处理
  const words = str.replaceAll(/[-_]/g, ' ').split(' ');

  // 将每个单词的首字母大写，并将其余部分保持原样
  const pascalCaseWords = words.map((word: any) => {
    if (word) {
      return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
    }
    return word;
  });

  // 将处理后的单词拼接成一个新的字符串
  return pascalCaseWords.join('');
};

/**
 * 转-kebab
 */
export const toKebabCase = (str: string) => {
  // 将每个单词的首字母小写，并在单词之间插入连字符
  return str
    .replaceAll(/([A-Z])/g, (match, _p1, offset) => {
      // 如果是第一个字符，直接转为小写
      if (offset === 0) {
        return match.toLowerCase();
      }
      // 否则，在大写字母前加上连字符，并将大写字母转为小写
      return `-${match.toLowerCase()}`;
    })
    .toLowerCase(); // 确保整个字符串都是小写
};

export function getFileNameWithoutExtension(path: string) {
  // 使用正则表达式匹配最后一个 / 后面的所有字符，但不包括最后一个点（.）之后的内容
  const match = path.match(/[^/]+(?=\.[^./]+$|$)/);
  return match ? match[0].replace(/\.[^/.]+$/, '') : null;
}

/**
 * 数据脱敏
 * @param data
 * @param type
 */
export function desensitize(data: string, type: 'bankCard' | 'idCard'): string {
  if (!data) return '';

  switch (type) {
    case 'bankCard': {
      // 银行卡号脱敏规则：显示前6位和后4位，中间用*代替
      if (data.length < 12) {
        throw new Error('Invalid bank card number length');
      }
      return data.slice(0, 6) + '*'.repeat(data.length - 10) + data.slice(-4);
    }

    case 'idCard': {
      // 身份证号脱敏规则：显示前6位和后4位，中间用*代替
      if (data.length !== 18) {
        throw new Error('Invalid ID card number length');
      }
      return data.slice(0, 6) + '*'.repeat(10) + data.slice(-4);
    }

    default: {
      throw new Error('Unsupported desensitization type');
    }
  }
}

/**
 * 获取操作系统的Icon
 * @param str
 */
export function getIcon(str: string) {
  switch (str) {
    case 'Api Post': {
      return 'logos:async-api-icon';
    }
    case 'Chrome': {
      return 'devicon:chrome';
    }
    case 'Edge':
    case 'Microsoft Edge': {
      return 'logos:microsoft-edge';
    }
    case 'Firefox': {
      return 'devicon:firefox';
    }
    case 'Linux': {
      return 'logos:linux-tux';
    }
    case 'Mac': {
      return 'wpf:mac-os';
    }
    case 'Safari': {
      return 'devicon:safari';
    }
    case 'Windows': {
      return 'logos:microsoft-windows-icon';
    }
    default: {
      return 'logos:microsoft-windows-icon';
    }
  }
}

/**
 * 获取接诊状态
 * @param status
 */
export function getRegisterStatus(status: number) {
  switch (status) {
    case 0: {
      return '待支付';
    }
    case 1: {
      return '待接诊';
    }
    case 2: {
      return '接诊中';
    }
    case 3: {
      return '已结束';
    }
    case 4: {
      return '已取消';
    }
    case 5: {
      return '待评价';
    }
    case 6: {
      return '已评价';
    }
    case 7: {
      return '已拒诊';
    }
    default: {
      return '未知状态';
    }
  }
}

// 把格式化时间转换成相对时间(刚刚,几分钟前,几小时前,几天前,几周前)
export function formatTimeToRelative(time: string) {
  const now = new Date();
  const date = new Date(time);
  const diff = now.getTime() - date.getTime();
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  const weeks = Math.floor(days / 7);

  if (seconds < 60) {
    return '刚刚';
  } else if (minutes < 60) {
    return `${minutes} 分钟前`;
  } else if (hours < 24) {
    return `${hours} 小时前`;
  } else if (days < 7) {
    return `${days} 天前`;
  } else if (weeks < 4) {
    return `${weeks} 周前`;
  }
  return time;
}

/**
 * Download according to the background interface file stream
 * @param {*} data
 * @param {*} filename
 * @param {*} mime
 * @param {*} bom
 */
export function downloadByData(
  data: BlobPart,
  filename: string,
  mime?: string,
  bom?: BlobPart,
) {
  const blobData = bom === undefined ? [data] : [bom, data];
  const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });

  const blobURL = window.URL.createObjectURL(blob);
  const tempLink = document.createElement('a');
  tempLink.style.display = 'none';
  tempLink.href = blobURL;
  tempLink.setAttribute('download', filename);
  if (tempLink.download === undefined) {
    tempLink.setAttribute('target', '_blank');
  }
  document.body.append(tempLink);
  tempLink.click();
  tempLink.remove();
  window.URL.revokeObjectURL(blobURL);
}
