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);
}

/**
 * 判断一个对象的所有字段是否有值（非 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;
  }
} /**
 * 转换路由格式为项目所需的CustomRoute格式
 * @param originalRoutes 原始路由数据
 * @returns 转换后的CustomRoute数组
 */
export function convertToCustomRoutes(originalRoutes: any[]) {
  return originalRoutes.map(route => {
    return convertMenuItem(route);
  });
}

function convertMenuItem(menu: any) {
  const routeName = menu.name
    .replace(/^\/+/, '') // 去掉开头的一个或多个 '/'
    .replace(/[/\s]/g, '_') // 替换剩余的 '/' 和空格为 '_'
    .toLowerCase();
  const routeData: any = {
    path: menu.path,
    name: routeName,
    meta: {
      title: menu.meta.title,
      icon: menu.meta.icon,
      hideInMenu: Number(menu.meta.hidden)
    },
    component: menu.component == 'Layout' ? `layout.base` : menu.component
  };
  if (menu.children && menu.children.length) {
    routeData.children = menu.children.map((child: any) => convertMenuItem(child));
  }

  return routeData;
}
