import { h, unref } from 'vue';
import type { App, Component, Plugin } from 'vue';
import { NIcon, NTag } from 'naive-ui';
import { isObject } from './is/index';
/**
 * render 图标
 * */
export function renderIcon(icon: any) {
  return () => h(NIcon, null, { default: () => h(icon) });
}
/**
 * font 图标(Font class)
 * */
export function renderFontClassIcon(icon: string, iconName = 'iconfont') {
  return () => h('span', { class: [iconName, icon] });
}
/**
 * font 图标(Unicode)
 * */
export function renderUnicodeIcon(icon: string, iconName = 'iconfont') {
  return () => h('span', { class: [iconName], innerHTML: icon });
}
/**
 * font svg 图标
 * */
export function renderfontsvg(icon: any) {
  return () =>
    h(NIcon, null, {
      default: () => h('svg', { class: `icon`, 'aria-hidden': 'true' }, h('use', { 'xlink:href': `#${icon}` }))
    });
}

/**
 * render new Tag
 * */
const newTagColors = { color: '#f90', textColor: '#fff', borderColor: '#f90' };
export function renderNew(type = 'warning', text = 'New', color: object = newTagColors) {
  return () =>
    h(
      NTag as any,
      {
        type,
        round: true,
        size: 'small',
        color
      },
      { default: () => text }
    );
}

export const withInstall = <T extends Component>(component: T, alias?: string) => {
  const comp = component as any;
  comp.install = (app: App) => {
    app.component(comp.name || comp.displayName, component);
    if (alias) {
      app.config.globalProperties[alias] = component;
    }
  };
  return component as T & Plugin;
};
/**
 *  找到所有节点
 * */
const treeAll: any[] = [];
export function getTreeAll(data: any[]): any[] {
  data.forEach(item => {
    treeAll.push(item.key);
    if (item.children && item.children.length) {
      getTreeAll(item.children);
    }
  });
  return treeAll;
}

// dynamic use hook props
export function getDynamicProps<T extends Record<string, any>, U>(props: T): Partial<U> {
  const ret: Recordable = {};

  Object.keys(props).forEach((key: any) => {
    ret[key] = unref((props as Recordable)[key]);
  });

  return ret as Partial<U>;
}

export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  let key: string;
  for (key in target) {
    if (Object.hasOwn(target, key)) {
      src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]);
    }
  }
  return src;
}

/**
 * Sums the passed percentage to the R, G or B of a HEX color
 * @param {string} color The color to change
 * @param {number} amount The amount to change the color by
 * @returns {string} The processed part of the color
 */
function addLight(color: string, amount: number) {
  const cc = Number.parseInt(color, 16) + amount;
  const c = cc > 255 ? 255 : cc;
  return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
}

/**
 * Lightens a 6 char HEX color according to the passed percentage
 * @param {string} color The color to change
 * @param {number} amount The amount to change the color by
 * @returns {string} The processed color represented as HEX
 */
export function lighten(color: string, amount: number) {
  const hexColor = color.includes('#') ? color.substring(1, color.length) : color;
  const adjustedAmount = Math.trunc((255 * amount) / 100);
  return `#${addLight(hexColor.substring(0, 2), adjustedAmount)}${addLight(
    hexColor.substring(2, 4),
    adjustedAmount
  )}${addLight(hexColor.substring(4, 6), adjustedAmount)}`;
}

/**
 * 判断是否 url
 * */
export function isUrl(url: string) {
  return /^(http|https):\/\//g.test(url);
}
/**
 * 获取uuid
 */
export function getUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    const r = Math.random() * 16;
    const v = c === 'x' ? Math.floor(r) : Math.floor((r * 4) % 4) + 8;
    return v.toString(16);
  });
}
interface OriginalMenuItem {
  menuId: number;
  parentId: number;
  parentName: string | null;
  name: string;
  url: string;
  perms: string;
  type: number;
  icon: string | null;
  orderNum: number;
  list: OriginalMenuItem[] | null;
  component: string;
  hideInMenu: boolean;
}

interface OriginalMenuData {
  menuList: OriginalMenuItem[];
}

interface ConvertedMenuItem {
  name: string;
  path: string;
  component: string;
  meta: {
    title: string;
    // i18nKey: string;
    icon?: string;
    order?: number;
    hideInMenu?: boolean;
  };
  children?: ConvertedMenuItem[];
}

export function convertMenuData(originalData: OriginalMenuData): ConvertedMenuItem[] {
  // 首先过滤出顶级菜单 (parentId === 0)
  const topLevelMenus = originalData.menuList.filter(menu => menu.parentId === 0);

  return topLevelMenus.map(menu => {
    return convertMenuItem(menu, originalData.menuList);
  });
}

function convertMenuItem(menu: OriginalMenuItem, allMenus: OriginalMenuItem[]): ConvertedMenuItem {
  // 生成路由名称 (使用小写字母和下划线)
  const routeName = menu.url
    .replace(/^\/+/, '') // 去掉开头的一个或多个 '/'
    .replace(/[/\s]/g, '_') // 替换剩余的 '/' 和空格为 '_'
    .toLowerCase();

  // 生成路由路径
  let routePath = `${routeName}`;
  if (menu.url && menu.url.trim() !== '') {
    routePath = `${menu.url}`;
  }

  // 转换基本信息
  const converted: ConvertedMenuItem = {
    name: routeName,
    path: routePath,
    component: menu.component,
    meta: {
      title: menu.name,
      // i18nKey: `route.${routeName}`,
      order: menu.orderNum,
      hideInMenu: menu.hideInMenu,
      icon: String(menu.icon)
    }
  };

  // 处理子菜单
  if (menu.list && menu.list.length > 0) {
    converted.children = menu.list.map(child => convertMenuItem(child, allMenus));
  } else {
    // 如果没有直接子菜单，但可能有其他关联的子菜单
    const children = allMenus.filter(m => m.parentId === menu.menuId);
    if (children.length > 0) {
      converted.children = children.map(child => convertMenuItem(child, allMenus));
    }
  }

  return converted;
}

/**
 * 菜单转为树型结构
 * @param data
 * @returns
 */
export function buildMenuTree(data: any) {
  // 创建根节点数组和映射表
  const rootNodes: any = [];
  const nodeMap: any = {};

  // 首先将所有节点存入映射表
  data.forEach((item: any) => {
    nodeMap[item.menuId] = { ...item };
  });

  // 构建树形结构
  data.forEach((item: any) => {
    const node = nodeMap[item.menuId];

    if (item.parentId === 0) {
      // 根节点
      rootNodes.push(node);
    } else {
      // 子节点，找到父节点并添加到父节点的children中
      const parent = nodeMap[item.parentId];
      if (parent) {
        if (!parent.children) {
          parent.children = [];
        }
        parent.children.push(node);
      } else {
        // 如果父节点不存在，也作为根节点
        rootNodes.push(node);
      }
    }
  });

  // 删除空children字段
  const removeEmptyChildren = (nodes: any) => {
    nodes.forEach((node: any) => {
      if (node.children && node.children.length === 0) {
        delete node.children;
      } else if (node.children) {
        removeEmptyChildren(node.children);
      }
    });
    return nodes;
  };

  // 对根节点和子节点按orderNum排序
  const sortByOrderNum = (nodes: any) => {
    return nodes
      .sort((a: any, b: any) => a.orderNum - b.orderNum)
      .map((node: any) => {
        if (node.children) {
          node.children = sortByOrderNum(node.children);
        }
        return node;
      });
  };

  return removeEmptyChildren(sortByOrderNum(rootNodes));
}
/**
 * 判断一个对象的所有字段是否有值（非 null 和 undefined）
 * @param obj 要检查的对象
 * @returns 所有字段有值返回 true，否则 false
 */
function areAllFieldsFilled(obj: Record<string, any>): boolean {
  return Object.values(obj).every(value => unref(value) !== null && unref(value) !== undefined);
}

/**
 * 判断数组中每个对象是否所有字段都有值
 * @param arr 要检查的对象数组
 * @returns 所有对象字段都有值返回 true，否则 false
 */
export function areAllItemsAllFieldsFilled(arr: Array<Record<string, any>>): boolean {
  return arr.every(item => areAllFieldsFilled(item));
}

/**
 * 复制文本到剪贴板
 * @param text 需要复制的文本内容
 * @returns Promise<boolean> 复制成功返回true，失败返回false
 */
export async function copyTextToClipboard(text: string): Promise<boolean> {
  try {
    // 使用现代 Clipboard API（如果支持）
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(text);
      window.$message?.success(`复制成功:${text}`);
    }
    // 降级方案：使用传统的 document.execCommand('copy')
    const textArea = document.createElement('textarea');
    textArea.value = text;

    // 避免滚动到底部
    textArea.style.top = '0';
    textArea.style.left = '0';
    textArea.style.position = 'fixed';
    textArea.style.opacity = '0';

    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();

    const successful = document.execCommand('copy');
    document.body.removeChild(textArea);

    return successful;
  } catch (error: any) {
    window.$message?.error(error.message);
    console.error('复制文本失败:', error);
    return false;
  }
}
