<script setup lang="ts">
import { computed, onBeforeUnmount, shallowRef, watch } from 'vue';
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import type { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
import { uploadFile } from '@/service/api/file';

defineOptions({ name: 'BusinessRichTextEditor' });

interface Props {
  placeholder?: string;
  disabled?: boolean;
  height?: number | string;
  /** 上传目录，传给后端 directory 字段 */
  uploadDirectory?: string;
  /** 单张图片大小上限（MB），默认 5 */
  maxImageSizeMB?: number;
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '请输入内容',
  disabled: false,
  height: 320,
  uploadDirectory: undefined,
  maxImageSizeMB: 5
});

const model = defineModel<string | null | undefined>({ default: '' });

const editorRef = shallowRef<IDomEditor>();

const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: [
    // 视频组
    'group-video',
    'insertVideo',
    'uploadVideo',
    // 更多样式分组
    'group-more-style',
    // 图片：只允许本地上传，不允许插入网络图片 URL
    'insertImage',
    // 超链接：业务暂不需要
    'insertLink',
    'editLink',
    'unLink',
    'viewLink'
  ]
};

const editorConfig: Partial<IEditorConfig> = {
  placeholder: props.placeholder,
  readOnly: props.disabled,
  MENU_CONF: {
    uploadImage: {
      maxFileSize: props.maxImageSizeMB * 1024 * 1024,
      allowedFileTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/bmp'],
      async customUpload(file: File, insertFn: (url: string, alt?: string, href?: string) => void) {
        const result = await uploadFile(file, props.uploadDirectory);

        if (result.error || !result.data) {
          const msg = result.error?.response?.data?.msg || '图片上传失败';
          window.$message?.error(msg);
          return;
        }

        const url = result.data;
        insertFn(url, file.name, url);
      }
    }
  }
};

watch(
  () => props.disabled,
  value => {
    const editor = editorRef.value;
    if (!editor) {
      return;
    }

    if (value) {
      editor.disable();
    } else {
      editor.enable();
    }
  }
);

function handleCreated(editor: IDomEditor) {
  editorRef.value = editor;
}

onBeforeUnmount(() => {
  editorRef.value?.destroy();
  editorRef.value = undefined;
});

/** 当 height 传 '100%' 或 'auto' 时启用「撑满父容器」模式 —— 父级必须有具体高度。 */
const isAutoFill = computed(() => props.height === '100%' || props.height === 'auto');

const containerClass = computed(() => ({
  'business-rich-text-editor': true,
  'business-rich-text-editor--auto-fill': isAutoFill.value
}));

const editorStyle = computed(() => {
  if (isAutoFill.value) {
    return { flex: 1, minHeight: 0, overflowY: 'hidden' as const };
  }

  return {
    height: typeof props.height === 'number' ? `${props.height}px` : props.height,
    overflowY: 'hidden' as const
  };
});
</script>

<template>
  <div :class="containerClass">
    <Toolbar
      class="business-rich-text-editor__toolbar"
      :editor="editorRef"
      :default-config="toolbarConfig"
      mode="default"
    />
    <Editor
      v-model="model"
      class="business-rich-text-editor__editor"
      :style="editorStyle"
      :default-config="editorConfig"
      mode="default"
      @on-created="handleCreated"
    />
  </div>
</template>

<style scoped lang="scss">
.business-rich-text-editor {
  width: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  overflow: hidden;
  background: var(--el-bg-color);

  &__toolbar {
    border-bottom: 1px solid var(--el-border-color);
    background: var(--el-fill-color-light);
  }

  &__editor {
    background: var(--el-bg-color);
  }

  &--auto-fill {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }
}

/* wangeditor 弹层（链接、图片菜单等）默认 z-index 偏低，提高一档避免被 ElDialog 遮挡 */
:deep(.w-e-modal),
:deep(.w-e-drop-panel),
:deep(.w-e-bar-divider),
:deep(.w-e-hover-bar) {
  z-index: 3000 !important;
}
</style>
