/*
 * @Author: 赵伟
 * @Date: 2024-04-19 14:42:51
 * @Description: UI 公共方法
 */
import { PageEnum } from '@/enums/pagesEnums';
import { removeAllPageCacheState } from '@/hooks/useCacheState';
import { deleteUploadFileReq } from '@/services/dataset/index.js';
import themes from '@/styles/theme.less';
import { type AppResponse, type ClientInfo, type UploadFileRes } from '@/types';
import { to } from '@/utils/promise';
import { history } from '@umijs/max';
import {
  Modal,
  Upload,
  message,
  type FormInstance,
  type ModalFuncProps,
  type UploadFile,
} from 'antd';
import { NamePath } from 'antd/es/form/interface';
import { isEmpty } from './index';
import { closeAllModals } from './modal';
import SessionStorage from './sessionStorage';

type ModalConfirmProps = ModalFuncProps & {
  isDelete?: boolean;
};

/**
 * 自定义 Confirm 弹框
 */
export function modalConfirm({
  title,
  content,
  okText = '确认',
  cancelText = '取消',
  isDelete = true,
  onOk,
  ...rest
}: ModalConfirmProps) {
  Modal.confirm({
    ...rest,
    width: 600,
    centered: true,
    title: (
      <div>
        <img
          src={
            isDelete
              ? require('@/assets/img/delete-icon.png')
              : require('@/assets/img/confirm-icon.png')
          }
          style={{ width: '120px', marginBottom: '24px' }}
          draggable={false}
          alt=""
        />
        <div style={{ color: themes.textColor, fontSize: '16px', fontWeight: 500 }}>{title}</div>
      </div>
    ),
    content: content && <div style={{ color: themes.textColor, fontSize: '15px' }}>{content}</div>,
    okText: okText,
    cancelText: cancelText,
    onOk: onOk,
  });
}

/**
 * 跳转到登录页
 * @param toHome - 是否跳转到首页
 */
export const gotoLoginPage = (toHome: boolean = true) => {
  const { pathname, search } = location;
  const urlParams = new URLSearchParams();
  urlParams.append('redirect', pathname + search);
  const newSearch = toHome || pathname === '/' ? '' : urlParams.toString();
  if (pathname !== PageEnum.LOGIN) {
    closeAllModals();
    removeAllPageCacheState();
    history.replace({
      pathname: PageEnum.LOGIN,
      search: newSearch,
    });
  }
};

/**
 * 跳转到 OAuth2 登录页
 */
export const gotoOAuth2 = () => {
  const clientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true) as ClientInfo;
  if (clientInfo) {
    const { clientId, userAuthorizationUri } = clientInfo;
    const url = `${userAuthorizationUri}?client_id=${clientId}&response_type=code&grant_type=authorization_code`;
    location.replace(url);
  }
};

/**
 * 从事件中获取上传文件列表，用于 Upload + Form 中
 * @param e - 事件，包含文件列表 fileList
 */
export const getFileListFromEvent = (e: any) => {
  const fileList: UploadFile[] = (Array.isArray(e) ? e : e?.fileList) || [];
  return fileList.map((item) => {
    if (item.status === 'done') {
      const { response } = item;
      if (response?.code !== 200) {
        return {
          ...item,
          status: 'error',
        };
      }
    }
    return item;
  });
};

/**
 * 验证文件上传
 *
 * @param {UploadFile[]} files - The array of uploaded files.
 * @param {boolean} [required=true] - Flag indicating if files are required.
 * @return {boolean} Returns true if all files are valid, false otherwise.
 */
export const validateUploadFiles = (files: UploadFile[], required: boolean = true): boolean => {
  if (required && files.length === 0) {
    message.error('请上传文件');
    return false;
  }

  const hasError = files.some((file) => {
    if (file.status === 'uploading') {
      message.error('请等待文件上传完成');
      return true;
    }
    if (file.status === 'error') {
      message.error('存在上传失败的文件，请删除后重新上传');
      return true;
    }
    if (!file.response || file.response.code !== 200 || !file.response.data) {
      message.error('存在上传失败的文件，请删除后重新上传');
      return true;
    }
    return false;
  });
  return !hasError;
};

/**
 * 限制上传文件类型
 * @param type - 只允许上次的的文件类型
 */
export const limitUploadFileType = (type: string) => {
  return (file: UploadFile): boolean | string => {
    const acceptTypes = type.split(',').map((item) => item.trim());
    const fileType = file.name.split('.').pop()?.trim();
    if (!(fileType && acceptTypes.includes(fileType))) {
      message.error(`文件类型不正确，只支持 "${acceptTypes.join('、')}" 类型的文件`);
      file.status = 'error';
      return Upload.LIST_IGNORE;
    }
    return true;
  };
};

/**
 * 删除已上传的文件
 * @param file - 已上传的文件
 */
export const removeUploadedFile = async (file: UploadFile<AppResponse<UploadFileRes[]>>) => {
  const { status, response } = file;
  const { code, data } = response ?? {};
  if (status === 'done' && code === 200 && Array.isArray(data) && data.length > 0) {
    const uploadRes = data[0];
    const { fileName, url } = uploadRes;
    const [res] = await to(
      deleteUploadFileReq({
        fileName,
        url,
      }),
    );
    if (res) {
      return true;
    } else {
      return false;
    }
  }

  return true;
};

/**
 * 删除 FormList 表单项，如果表单项没有值，则直接删除，否则弹出确认框
 * @param form - From实例
 * @param listName - FormList 的 name
 * @param name - FormList 的其中一项
 * @param remove - FormList 的删除方法
 * @param fieldNames - FormList 的子项名称数组
 * @param confirmTitle - 弹出确认框的标题
 */
export const removeFormListItem = (
  form: FormInstance,
  listName: NamePath,
  name: number,
  remove: (name: number) => void,
  fieldNames: NamePath[],
  confirmTitle: string,
) => {
  const fields = fieldNames.map((item) => [listName, name, item].flat());
  const isEmptyField = fields.every((item) => {
    const value = form.getFieldValue(item);
    return isEmpty(value);
  });

  if (isEmptyField) {
    remove(name);
    return;
  }

  modalConfirm({
    title: confirmTitle,
    content: '是否确认删除?',
    onOk: () => {
      remove(name);
    },
  });
};

/**
 * 退出子系统
 * @param url - 退出登录的地址
 */
export const oauthLogout = (url: string) => {
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  iframe.src = url;
  document.body.appendChild(iframe);
};
