import { reactive, ref, Ref, unref } from 'vue';
import { merge } from 'lodash-es';
import { DynamicProps } from '/#/utils';
import { BasicTableProps, TableActionType, useTable } from '/@/components/Table';
import { ColEx } from '/@/components/Form/src/types';
import { FormActionType } from '/@/components/Form';
import { useMessage } from '/@/hooks/web/useMessage';
import { useMethods } from '/@/hooks/system/useMethods';
import { useDesign } from '/@/hooks/web/useDesign';
import { filterObj } from '/@/utils/common/compUtils';
import { isFunction } from '@/utils/is';
const { handleExportXls, handleImportXls } = useMethods();

// 定义 useListPage 方法所需参数
interface ListPageOptions {
  // 样式作用域范围
  designScope?: string;
  // 【必填】表格参数配置
  tableProps: TableProps;
  // 是否分页
  pagination?: boolean;
  // 导出配置
  exportConfig?: {
    url: string | (() => string);
    // 导出文件名
    name?: string | (() => string);
    //导出参数
    params?: object | (() => object);
  };
  // 导入配置
  importConfig?: {
    // 代码逻辑说明: erp代码生成 子表 导入地址是动态的
    url: string | (() => string);
    // 导出成功后的回调
    success?: (fileInfo?: any) => void;
  };
}

interface IDoRequestOptions {
  // 是否显示确认对话框，默认 true
  confirm?: boolean;
  // 是否自动刷新表格，默认 true
  reload?: boolean;
  // 是否自动清空选择，默认 true
  clearSelection?: boolean;
}

/**
 * listPage页面公共方法
 *
 * @param options
 */
export function useListPage(options: ListPageOptions) {
  const $message = useMessage();
  let $design = {} as ReturnType<typeof useDesign>;
  if (options.designScope) {
    $design = useDesign(options.designScope);
  }

  const tableContext = useListTable(options.tableProps);

  const [, { getForm, reload, setLoading, getColumns }, { selectedRowKeys }] = tableContext;

  // 导出 excel
  async function onExportXls() {
    // 代码逻辑说明: 导出新增自定义参数------------
    let { url, name, params } = options?.exportConfig ?? {};
    let realUrl = typeof url === 'function' ? url() : url;
    if (realUrl) {
      let title = typeof name === 'function' ? name() : name;
      // 代码逻辑说明: erp代码生成 子表 导出报错，原因未知-
      let paramsForm:any = {};
      try {
        //当useSearchFor不等于false的时候，才去触发validate
        if (options?.tableProps?.useSearchForm !== false) {
          paramsForm = await getForm().validate();
          console.log('paramsForm', paramsForm);
          // 在这里把执行beforeFetch
          if (options?.tableProps?.beforeFetch) {
            paramsForm = await options?.tableProps?.beforeFetch(paramsForm);
          }
        }
      } catch (e) {
        console.warn(e);
      }

      // 代码逻辑说明: [/issues/409]导出功能没有按排序结果导出,设置导出默认排序，创建时间倒序
      if(!paramsForm?.column){
         Object.assign(paramsForm,{column:'createTime',order:'desc'});
      }

      //如果参数不为空，则整合到一起
      // 代码逻辑说明: erp代码生成 子表 导出动态设置mainId
      if (params) {
        // 代码逻辑说明: [QQYUN-11627]代码生成原生表单，数据导出，前端报错，并且范围参数没有转换 #7962
        const realParams = isFunction(params) ? await params() : { ...(params || {}) };
        Object.keys(realParams).map((k) => {
          let temp = (realParams as object)[k];
          if (temp) {
            paramsForm[k] = unref(temp);
          }
        });
      }
      if (selectedRowKeys.value && selectedRowKeys.value.length > 0) {
        paramsForm['selections'] = selectedRowKeys.value.join(',');
      }

      //是否显示表格设置
      if(options?.tableProps?.showTableSetting !== false){
        //是否显示配置字段
        if(options?.tableProps?.tableSetting?.setting !== false){
          await exportColumns(paramsForm)
        }
      }
    
      return handleExportXls(title as string, realUrl, filterObj(paramsForm));
    } else {
      $message.createMessage.warn('没有传递 exportConfig.url 参数');
      return Promise.reject();
    }
  }

  /**
   * 设置导出的列
   * 
   * @param paramsForm
   */
  async function exportColumns(paramsForm: any) {
    //获取表格的列
    let columns = getColumns();
    if(columns && columns.length >0){
      //需要导出的字段
      let exportFields:any = [];
      //是否有隐藏列
      let hiddenColumns = false;
      for (const column of columns) {
        if(!column.defaultHidden){
          let dataIndex = column?.dataIndex;
          if(column?.dataIndex?.toString()?.indexOf('_dictText') !== -1){
            dataIndex = column?.dataIndex?.toString().replace('_dictText','')
          }
          exportFields.push(dataIndex);
        } else {
          hiddenColumns = true;
        }
      }
      if(hiddenColumns){
        paramsForm['exportFields'] = exportFields.join(",");
      }
    }
  }

  // 导入 excel
  function onImportXls(file) {
    let { url, success } = options?.importConfig ?? {};
    // 代码逻辑说明: erp代码生成 子表 导入地址是动态的
    let realUrl = typeof url === 'function' ? url() : url;
    if (realUrl) {
      return handleImportXls(file, realUrl, success || reload);
    } else {
      $message.createMessage.warn('没有传递 importConfig.url 参数');
      return Promise.reject();
    }
  }

  /**
   * 通用请求处理方法，可自动刷新表格，自动清空选择
   * @param api 请求api
   * @param options 是否显示确认框
   */
  function doRequest(api: () => Promise<any>, options?: IDoRequestOptions) {
    return new Promise((resolve, reject) => {
      const execute = async () => {
        try {
          setLoading(true);
          const res = await api();
          if (options?.reload ?? true) {
            reload();
          }
          if (options?.clearSelection ?? true) {
            selectedRowKeys.value = [];
          }
          resolve(res);
        } catch (e) {
          reject(e);
        } finally {
          setLoading(false);
        }
      };
      if (options?.confirm ?? true) {
        $message.createConfirm({
          iconType: 'warning',
          title: '删除',
          content: '确定要删除吗？',
          onOk: () => execute(),
          onCancel: () => reject(),
        });
      } else {
        execute();
      }
    });
  }

  /** 执行单个删除操作 */
  function doDeleteRecord(api: () => Promise<any>) {
    return doRequest(api, { confirm: false, clearSelection: false });
  }

  return {
    ...$design,
    ...$message,
    onExportXls,
    onImportXls,
    doRequest,
    doDeleteRecord,
    tableContext,
  };
}

// 定义表格所需参数
type TableProps = Partial<DynamicProps<BasicTableProps>>;
type UseTableMethod = TableActionType & {
  getForm: () => FormActionType;
};

/**
 * useListTable 列表页面标准表格参数
 *
 * @param tableProps 表格参数
 */
export function useListTable(tableProps: TableProps): [
  (instance: TableActionType, formInstance: UseTableMethod) => void,
  TableActionType & {
    getForm: () => FormActionType;
  },
  {
    rowSelection: any;
    selectedRows: Ref<Recordable[]>;
    selectedRowKeys: Ref<any[]>;
  }
] {
  // 自适应列配置
  const adaptiveColProps: Partial<ColEx> = {
    xs: 24, // <576px
    sm: 12, // ≥576px
    md: 12, // ≥768px
    lg: 8, // ≥992px
    xl: 8, // ≥1200px
    xxl: 6, // ≥1600px
  };
  const defaultTableProps: TableProps = {
    rowKey: 'id',
    // 使用查询条件区域
    useSearchForm: true,
    // 查询条件区域配置
    formConfig: {
      // 紧凑模式
      compact: true,
      // label默认宽度
      // labelWidth: 120,
      // 按下回车后自动提交
      autoSubmitOnEnter: true,
      // 默认 row 配置
      rowProps: { gutter: 8 },
      // 默认 col 配置
      baseColProps: {
        ...adaptiveColProps,
      },
      labelCol: {
        xs: 24,
        sm: 8,
        md: 6,
        lg: 8,
        xl: 6,
        xxl: 6,
      },
      wrapperCol: {},
      // 是否显示 展开/收起 按钮
      showAdvancedButton: true,
      // 超过指定列数默认折叠
      autoAdvancedCol: 3,
      // 操作按钮配置
      actionColOptions: {
        ...adaptiveColProps,
        style: { textAlign: 'left' },
      },
    },
    // 斑马纹
    striped: false,
    // 是否可以自适应高度
    canResize: true,
    // 表格最小高度
    // update-begin--author:liaozhiyang---date:20240603---for【TV360X-861】列表查询区域不可往上滚动
    minHeight: 300,
    // update-end--author:liaozhiyang---date:20240603---for【TV360X-861】列表查询区域不可往上滚动
    // 点击行选中
    clickToRowSelect: false,
    // 是否显示边框
    bordered: true,
    // 是否显示序号列
    showIndexColumn: false,
    // 显示表格设置
    showTableSetting: true,
    // 表格全屏设置
    tableSetting: {
      fullScreen: false,
    },
    // 是否显示操作列
    showActionColumn: true,
    // 操作列
    actionColumn: {
      width: 120,
      title: '操作',
      //是否锁定操作列取值 right ,left,false
      fixed: false,
      dataIndex: 'action',
      slots: { customRender: 'action' },
    },
  };
  // 合并用户个性化配置
  if (tableProps) {
    // 代码逻辑说明: 【issues/6180】前端代码配置表变查询条件显示列不生效---
    if(tableProps.formConfig){
      setTableProps(tableProps.formConfig);
    }
    // merge 方法可深度合并对象
    merge(defaultTableProps, tableProps);
  }

  // 发送请求之前调用的方法
  function beforeFetch(params) {
    // 默认以 createTime 降序排序
    return Object.assign({ column: 'createTime', order: 'desc' }, params);
  }

  // 合并方法
  Object.assign(defaultTableProps, { beforeFetch });
  if (typeof tableProps.beforeFetch === 'function') {
    defaultTableProps.beforeFetch = function (params) {
      params = beforeFetch(params);
      // @ts-ignore
      tableProps.beforeFetch(params);
      return params;
    };
  }

  // 当前选择的行
  const selectedRowKeys = ref<any[]>([]);
  // 选择的行记录
  const selectedRows = ref<Recordable[]>([]);

  // 表格选择列配置
  const rowSelection: any = tableProps?.rowSelection ?? {};
  const defaultRowSelection = reactive({
    ...rowSelection,
    type: rowSelection.type ?? 'checkbox',
    // 选择列宽度，默认 50
    columnWidth: rowSelection.columnWidth ?? 50,
    selectedRows: selectedRows,
    selectedRowKeys: selectedRowKeys,
    onChange(...args) {
      selectedRowKeys.value = args[0];
      selectedRows.value = args[1];
      if (typeof rowSelection.onChange === 'function') {
        rowSelection.onChange(...args);
      }
    },
  });
  delete defaultTableProps.rowSelection;

  /**
   * 设置表格参数
   *
   * @param formConfig
   */
  function setTableProps(formConfig: any) {
    const replaceAttributeArray: string[] = ['baseColProps','labelCol'];
    for (let item of replaceAttributeArray) {
      if(formConfig && formConfig[item]){
        if(defaultTableProps.formConfig){
          let defaultFormConfig:any = defaultTableProps.formConfig;
          defaultFormConfig[item] = formConfig[item];
        }
        formConfig[item] = {};
      }
    }
  }

  return [
    ...useTable(defaultTableProps),
    {
      selectedRows,
      selectedRowKeys,
      rowSelection: defaultRowSelection,
    },
  ];
}
