/* eslint-disable no-param-reassign */
import {
  FormItemController,
  GridEditItemController,
  UploadEditorController,
} from '@ibiz-template/controller';
import { HttpError } from '@ibiz-template/core';
import { getCookie } from 'qx-util';
import { Ref, ref, watch } from 'vue';
/**
 * iview的Upload适配逻辑
 *
 * @author lxm
 * @date 2022-11-17 16:11:12
 * @export
 * @param {IParams} props
 * @param {(_value: string | null) => {}} valueChange
 * @param {UploadEditorController} c
 * @returns {*}
 */
export function useIViewUpload(
  props: IParams,
  valueChange: (_value: string | null) => void,
  c: UploadEditorController,
) {
  // 文件列表
  const files: Ref<
    {
      id: string;
      name: string;
      url?: string;
    }[]
  > = ref([]);

  // 请求头
  const headers: Ref<IData> = ref({
    Authorization: `Bearer ${getCookie('access_token')}`,
  });

  // 上传文件路径
  const uploadUrl: Ref<string> = ref('');

  // 下载文件路径
  const downloadUrl: Ref<string> = ref('');

  // 文件上传缓存对象
  const uploadCache: IData = {
    count: 0,
    cacheFiles: [], // iview上传过程中不能改default-file-list,所以需要缓存
  };

  // 值响应式变更
  watch(
    () => props.value,
    newVal => {
      files.value = !newVal ? [] : JSON.parse(newVal);
    },
    { immediate: true },
  );

  // data响应式变更基础路径
  watch(
    () => props.data,
    newVal => {
      if (newVal) {
        const urls = c.calcBaseUrl(newVal);
        uploadUrl.value = urls.uploadUrl;
        downloadUrl.value = urls.downloadUrl;
      }
    },
    { immediate: true, deep: true },
  );

  watch(
    files,
    newVal => {
      // 变更后且下载基础路径存在时解析
      if (newVal?.length && downloadUrl.value) {
        newVal.forEach((file: IData) => {
          file.url = file.url || downloadUrl.value.replace('%fileId%', file.id);
        });
      }
    },
    { immediate: true },
  );

  watch(
    downloadUrl,
    newVal => {
      // 变更后且下载基础路径存在时解析
      if (newVal && files.value.length) {
        files.value.forEach((file: IData) => {
          file.url = downloadUrl.value.replace('%fileId%', file.id);
        });
      }
    },
    { immediate: true },
  );

  /**
   * 抛出值变更事件，根据files计算value
   *
   * @author lxm
   * @date 2022-11-17 14:11:54
   */
  const emitValue = () => {
    // 多选是合并，单选是替换
    let _files = [];
    if (c.model.editorType === 'FILEUPLOADER_ONE') {
      files.value = [];
      _files = [uploadCache.cacheFiles[uploadCache.cacheFiles.length - 1]];
    } else {
      _files = [...files.value, ...uploadCache.cacheFiles];
    }
    const value: string | null =
      _files.length > 0
        ? JSON.stringify(
            _files.map((file: IData) => ({ name: file.name, id: file.id })),
          )
        : null;
    uploadCache.cacheFiles = [];
    valueChange(value);
  };

  // 上传前回调
  const beforeUpload = (file: IData) => {
    const type = file.name.split('.').pop() || '';
    if (c.whiteList && c.whiteList.length > 0 && !c.whiteList.includes(type)) {
      ibiz.message.error(`${file.name} 文件格式不正确`, 2.5, true);
      return false;
    }
    if (file.size > c.defaultSize * 1024 * 1024) {
      // 超出限制，不上传
      ibiz.message.error(
        `${file.name} 超出限制，请选择小于${c.defaultSize}MB的文件`,
        2.5,
        true,
      );
      return false;
    }
    uploadCache.count += 1;
  };

  // 上传成功回调
  const onSuccess = (response: IData) => {
    if (!response) {
      return;
    }
    uploadCache.cacheFiles.push({
      name: response.filename,
      id: response.fileid,
    });
    uploadCache.count -= 1;

    // 回调都结束后抛出值变更
    if (uploadCache.count === 0) {
      emitValue();
    }
  };

  // 上传失败回调
  const onError = (error: IData, response: IData) => {
    uploadCache.count -= 1;
    throw new HttpError({
      response: { data: response, status: error.status },
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } as any);
  };

  // 删除回调
  const onRemove = (file: IData) => {
    if (props.disabled) {
      return;
    }
    const index = files.value.findIndex(item => item.id === file.id);
    if (index !== -1) {
      files.value.splice(index, 1);
    }
    emitValue();
  };

  // 下载文件
  const onDownload = (file: IData) => {
    // const url = file.url || downloadUrl.value.replace('%fileId%', file.id);
    const ctrl =
      (c.parent as FormItemController).form ||
      (c.parent as GridEditItemController).grid;
    const entityName = ctrl.model.appEntity.deName;
    const base64 = `${file.id}|${entityName}|${props.data.srfkey}|${
      c.context.srfpersonid || c.context.srfuserid
    }`;
    const url = file.url || downloadUrl.value.replace('%fileId%', file.id);
    c.fileDownload({
      url: `${url}?key=${window.btoa(base64)}${Math.floor(
        1000 + Math.random() * 9000,
      )}`,
      name: file.name,
    });
  };

  return {
    uploadUrl,
    downloadUrl,
    headers,
    files,
    onDownload,
    onError,
    onRemove,
    onSuccess,
    beforeUpload,
  };
}
