/* eslint-disable no-param-reassign */
import { RuntimeError } from '@ibiz-template/core';
import {
  getGridEditorEmits,
  getGridUploadProps,
  useEventListener,
  useNamespace,
} from '@ibiz-template/vue-util';
import { CreateElement, defineComponent, ref, toRefs } from 'vue';
import {
  FileInfo,
  openImagePreview,
  useIBizUploadInit,
} from '../use/use-ibiz-upload';
import { IBizGridFileUploadPopover } from './ibiz-grid-file-upload-popover';
import '@ibiz-template/theme/style/components/editor/ibiz-grid-file-upload/ibiz-grid-file-upload.scss';

export const IBizGridFileUpload = defineComponent({
  name: 'IBizGridFileUpload',
  props: getGridUploadProps(),
  emits: getGridEditorEmits(),
  setup(props, { emit }) {
    const ns = useNamespace('grid-file-upload');

    // 初始化文件上传编辑器的数据解析
    const { value, data, controller } = toRefs(props);
    const { downloadUrl, uploadUrl, valueList } = useIBizUploadInit({
      value,
      data,
      controller,
    });

    const componentRef = ref();

    /**
     * 打开文件上传操作飘窗
     *
     * @author lxm
     * @date 2022-11-21 11:11:45
     */
    const openPopover = async () => {
      if (!componentRef.value) {
        throw new RuntimeError('容器元素不存在');
      }
      const el = componentRef.value.$el as HTMLElement;
      const elHeight = el.offsetHeight;
      const popover = ibiz.overlay.createPopover(
        (h: CreateElement) => {
          return h(IBizGridFileUploadPopover, {
            props: {
              value: valueList.value,
              uploadUrl: uploadUrl.value,
              downloadUrl: downloadUrl.value,
            },
            on: {
              close: (result: {
                isModified: boolean;
                resultFiles: FileInfo[];
              }) => {
                popover.dismiss(result);
              },
            },
          });
        },
        undefined,
        {
          noArrow: true,
          placement: 'bottom-start',
          offsetOpts: { mainAxis: -elHeight, crossAxis: 0 },
        },
      );
      await popover.present(el);
      const { isModified, resultFiles } = await popover.onWillDismiss<{
        isModified: boolean;
        resultFiles: FileInfo[];
      }>();
      // 关闭popover后如果有上传的文件集合，则编辑器值变更,并且保存
      if (isModified) {
        const valueStr: string | null =
          resultFiles.length > 0
            ? JSON.stringify(
                resultFiles.map(file => ({ name: file.name, id: file.id })),
              )
            : null;
        emit('change', valueStr);
        emit('rowSave');
      }
    };

    // 非禁用和只读的时候点击打开飘窗
    useEventListener(componentRef, 'click', _evt => {
      if (!props.disabled && !props.readonly) {
        openPopover();
      }
    });

    const onFileClick = (file: FileInfo) => {
      // 编辑态时点击触发的打开飘窗，其他行为都禁用
      // 图片点击不下载，弹出预览
      if (!props.disabled || file.isImage) {
        return;
      }
      props.controller.fileDownload(file as Required<FileInfo>);
    };

    const onImageClick = (file: FileInfo) => {
      // 编辑态时点击触发的打开飘窗，其他行为都禁用
      if (!props.disabled) {
        return;
      }
      openImagePreview(file);
    };

    return {
      ns,
      valueList,
      componentRef,
      onFileClick,
      onImageClick,
    };
  },
  render() {
    return (
      <grid-editor
        disabled={this.disabled}
        readonly={this.readonly}
        ref='componentRef'
        class={`${this.ns.b()}`}
      >
        {this.valueList.map(file => {
          return (
            <i-tooltip
              class={[
                this.ns.e('item'),
                file.isImage
                  ? this.ns.em('item', 'image')
                  : this.ns.em('item', 'file'),
              ]}
              content={file.name}
              transfer
              placement='top'
              nativeOnClick={() => this.onFileClick(file)}
            >
              {file.isImage ? (
                <img
                  onClick={() => this.onImageClick(file)}
                  class={this.ns.e('item-image')}
                  src={file.url}
                />
              ) : (
                [
                  <span class={this.ns.e('item-file-name')}>
                    {file.fileName}
                  </span>,
                  <span class={this.ns.e('item-file-ext')}>
                    {file.fileExt}
                  </span>,
                ]
              )}
            </i-tooltip>
          );
        })}
      </grid-editor>
    );
  },
});
