import type { AxiosResponse } from 'axios';
import dayjs from 'dayjs';
import _ from 'lodash';
import consola from 'consola';
import { disAutoConnect, autoConnect, hiprint } from '@sv-print/hiprint';
import type { IScopedContext } from 'amis';
import { loadAmisSDK } from '@maita/amis-tools';
import axios from 'axios';
disAutoConnect();





/**
 * 动态执行给定的作用域表达式，并返回处理后的上下文和数据。
 *
 * @param scope - 要执行的动态表达式字符串。
 * @returns 包含 `context` 和 `data` 的对象。如果 `scope` 为空，则返回空对象。
 */
export const evalFc = async (
  scopeStr: string,
  instance?: IScopedContext & amis.TypeEmbed
): Promise<{
  data?: Record<string, string | number | boolean | null | undefined>;
  context?: Record<string, any>;
}> => {
  const getAmis = async () => {
    if (!window.amisRequire) await loadAmisSDK();
    return new Promise((res, rej) => {
      try {
        window.amisRequire(['amis-ui', 'amis', 'amis-formula', 'react', 'amis-core'], (...args: any[]) => {
          const [ui, lib, formula, react, core] = args;
          res({ ui, lib, formula, react, core });
        });
      } catch (error) {
        consola.error('amisRequire 加载失败，部分功能可能无法使用', error);
        rej(error);
      }
    });
  };

  const eval2 = (express: string) => {
    // eslint-disable-next-line no-new-func
    return new Function('instance', '_', 'axios', 'hiprint', 'hiprintConnect', 'dayjs', 'amis', `return ${express}`);
  };
  const dynamicCode = eval2(`(${scopeStr})`)(
    instance,
    _,
    axios,
    hiprint.PrintTemplate,
    autoConnect,
    dayjs,
    await getAmis()
  );

  const Scope: {
    data?: Record<string, string | number | boolean | null | undefined>;
    context?: Record<string, any>;
  } = {
    context: dynamicCode.context,
    data: dynamicCode.data
  };

  return Scope;
};

/**
 * 递归转换数组Schema类型的$字符串表达式
 * @param orgobj 含$字符串的Schema表达式的对象
 * @param args Title ,entity,user 参数
 * @returns 计算后的对象
 */
export function ConvertSchemaMarkToJSON<T>(orgobj: Record<string, any>, scope: any): T {
  const eval2 = (express: string) => {
    // eslint-disable-next-line no-new-func
    return new Function('scope', `return ${express.replace('{{', '').replace('}}', '')}`);
  };

  /**
   * 递归处理对象
   * @param obj 当前处理的对象
   * @returns 处理后的对象
   */
  const getObject = (obj: Record<string, any> | string): any => {
    // 处理对象
    const targetObj: Record<string, any> = {};
    if (typeof obj === 'number') {
      return obj;
    } else if (typeof obj === 'string') {
      if (/{{.*}}/.test(obj)) obj = eval2(obj)(scope);
      return obj;
    }

    for (const key in obj) {
      if (Object.hasOwn(obj, key)) {
        const value = obj[key];
        // 递归处理对象或数组
        if (Array.isArray(value)) {
          targetObj[key] = value.map(item => getObject(item));
        } else if (typeof value === 'object') {
          targetObj[key] = getObject(value);
        }
        // 处理包含 {{}} 的字符串
        else if (typeof value === 'string' && /{{.*}}/.test(value)) {
          targetObj[key] = eval2(value)(scope);
        } else targetObj[key] = value;
      }
    }
    return targetObj;
  };
  return getObject(orgobj);
}

/**
 * 封装response数据为一个文件下载
 * @param response - Axios 响应对象
 * @returns 如果服务端返回的是一个blob 则返回一个文件下载
 */
export const responeToDownLoad = (response: AxiosResponse<any>) => {
  let filename = '文件打包.zip';
  const contentDisposition = response.headers['content-disposition'] || response.headers['Content-Disposition'];
  // 解析 Content-Disposition 头以获取文件名
  if (contentDisposition) {
    const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
    if (filenameMatch && filenameMatch[1]) {
      filename = decodeURIComponent(filenameMatch[1].replace(/['"]/g, ''));
    }
  }

  const downloadUrl = window.URL.createObjectURL(new Blob([response.data as unknown as BlobPart]));
  const link = document.createElement('a');
  link.style.display = 'none';
  link.href = downloadUrl;
  link.setAttribute('download', filename); // 设置下载的文件名
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  window.URL.revokeObjectURL(downloadUrl);
  return { msg: '下载成功', status: 0, data: {} }; // 不进行 Amis 渲染
};
