<template>
  <div class="container">
    <div class="editor-container">
      <Toolbar
          class="tool-bar"
          :editor="editorRef"
          :defaultConfig="toolbarConfig"
          :mode="mode"
      />
      <Editor
          :defaultConfig="editorConfig"
          :mode="mode"
          v-model="valueHtml"
          @onCreated="handleCreated"
          @onChange="handleChange"
          @onDestroyed="handleDestroyed"
          @onFocus="handleFocus"
          @onBlur="handleBlur"
          @customAlert="customAlert"
          @customPaste="customPaste"
      />
    </div>
    <button class="submit-btn" @click="submitBlog">提交</button>
  </div>
</template>

<script setup>
import '@wangeditor/editor/dist/css/style.css';
import {ref, shallowRef, onMounted, onBeforeUnmount} from 'vue';
import {Editor, Toolbar} from '@wangeditor/editor-for-vue';
import api from "../utils/axios.js";
import swal from "../utils/sweetalert.js";
import Swal from "sweetalert2";


// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();

// 内容 HTML
const valueHtml = ref('<p>hello</p>');
const imagesCache = ref([]);

// 工具栏和编辑器配置
const toolbarConfig = {};
const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {},
};

// 模式
const mode = 'default';


toolbarConfig.excludeKeys = ["insertImage", "group-video", "fullScreen", "insertTable"];
toolbarConfig.modalAppendToBody = true;


editorConfig.MENU_CONF.uploadImage = {
  fieldName: "image", // 后端接收字段名

  async customUpload(file, insertFn) {

    const index = imagesCache.value.length; // 当前图片索引

    // 读取图片尺寸
    const imageSize = await getImageSize(file);

    // 存入缓存
    imagesCache.value.push({
      file,
      originalWidth: imageSize.width,
      originalHeight: imageSize.height
    });

    // 生成临时预览 URL
    const objectURL = URL.createObjectURL(file);
    insertFn(objectURL, `image-${index}`, objectURL); // 插入编辑器
  }
};
// 🎯 读取图片原始尺寸的函数
const getImageSize = (file) => {
  return new Promise((resolve) => {
    const img = new Image();
    img.src = URL.createObjectURL(file);
    img.onload = () => {
      resolve({width: img.width, height: img.height});
    };
  });
};
// 模拟 Ajax 异步获取内容
onMounted(() => {
  // setTimeout(() => {
  //   valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>';
  //   // valueHtml.value = valueHtml.value.replaceAll(
  //   //     '<holder>',
  //   //     ''
  //   // );
  // }, 1500);
});

// 组件销毁时销毁编辑器实例
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

async function showInputPopup() {
  try {
    while (1) {
      const result = await Swal.fire({
        title: '请输入标题',
        input: 'text',
        inputLabel: '标题',
        inputPlaceholder: '请输入您的标题...',
        showCancelButton: true,
        cancelButtonText: '取消',
        confirmButtonText: '确定',
        inputValidator: (value) => {
          if (!value) {
            return '标题不能为空！'
          }
        }
      })

      // 判断用户操作
      if (!result.isConfirmed) {
        return -1;
      }
      const title = result.value;

      if (title) {
        const result = await swal.window('info', `确定吗?`, `用"${title}"作为标题`, '确定', '重输');
        if (result.isConfirmed) {
          return title;
        }
      }
    }
  } catch (error) {
    console.error('输入弹窗出错:', error)
  }
}

// 🚀 提交博客
const submitBlog = async () => {
  if (!editorRef.value) return;

  const title = await showInputPopup();
  if (title === -1) {
    return;
  }
  const response = await swal.window('info', '允许评论吗?', '其他用户可以在你的博客下留言', '允许', '不允许');
  let allowComments = response.isConfirmed;

  let content = editorRef.value.getHtml(); // 获取 HTML 内容
  const images = [...imagesCache.value]; // 复制图片数组

  // 解析 `<img>` 并处理宽高
  const imgTags = content.match(/<img[^>]+>/g) || [];

  // 创建 blob URL 到索引的映射
  const urlToIndexMap = new Map();
  let uniqueIndex = 0;

  // 第一步：为每个唯一的 blob URL 分配索引
  imgTags.forEach((imgTag) => {
    const srcMatch = imgTag.match(/src=["']([^"']+)["']/);
    if (srcMatch) {
      const src = srcMatch[1]; // 提取 blob URL
      if (!urlToIndexMap.has(src)) {
        urlToIndexMap.set(src, uniqueIndex);
        uniqueIndex++;
      }
    }
  });

  // 第二步：替换 `<img>` 标签并处理宽高
  imgTags.forEach((imgTag) => {
    const srcMatch = imgTag.match(/src=["']([^"']+)["']/);
    if (srcMatch) {
      const src = srcMatch[1];
      const index = urlToIndexMap.get(src); // 获取相同 blob URL 的索引
      const styleMatch = imgTag.match(/style=["']([^"']+)["']/);
      let width = "", height = "";

      // 获取图片的原始尺寸（从 images 中根据 blob URL 匹配）
      const imageData = images.find((img) => URL.createObjectURL(img.file) === src);
      const originalWidth = imageData?.originalWidth || 0;
      const originalHeight = imageData?.originalHeight || 0;

      if (styleMatch && styleMatch[1]) {
        const styleStr = styleMatch[1];
        const widthMatch = styleStr.match(/width:\s*([\d.]+)px/);
        const heightMatch = styleStr.match(/height:\s*([\d.]+)px/);
        const percentWidthMatch = styleStr.match(/width:\s*([\d.]+)%/);

        if (widthMatch) {
          width = widthMatch[1];
        } else if (percentWidthMatch && originalWidth) {
          width = ((parseFloat(percentWidthMatch[1]) / 100) * originalWidth).toFixed(2);
        }

        if (heightMatch) {
          height = heightMatch[1];
        } else if (width && originalWidth && originalHeight) {
          height = ((width / originalWidth) * originalHeight).toFixed(2);
        }
      } else {
        width = originalWidth;
        height = originalHeight;
      }

      // 替换为占位符，使用相同的索引
      content = content.replace(imgTag, `<preholder image ${index} width=${width} height=${height}>`);
    }
  });


  // 2️⃣ 构造表单数据
  const formData = new FormData();
  formData.append("title", title);
  formData.append("content", content);
  formData.append("allow_comments", allowComments);


  images.forEach((imgData, index) => {
    formData.append(`images[${index}]`, imgData.file); // 按索引存储图片
  });

  console.log(Object.fromEntries(formData.entries()));
  // 3️⃣ 发送请求
  api.post('/blogs', formData).then(response => {
    if (response.status !== 200) {
      swal.tip('error', `404'}`);
      return;
    }
    if (response.code === 0) {
      swal.window('success', `提交成功, 博客id${response.blogId || '未找到(blogId字段)'}`);
      return;
    }
    swal.tip('error', '提交失败, code字段不为0')
  }).catch((e) => {
    swal.tip('error', `错误${e.message}`)
  });

};

// 编辑器回调函数
const handleCreated = (editor) => {
  // console.log('created', editor);
  editorRef.value = editor; // 记录 editor 实例
};

const handleChange = (editor) => {
  // console.log('change:', editor.getHtml());
};

const handleDestroyed = (editor) => {
  // console.log('destroyed', editor);
};

const handleFocus = (editor) => {
  // console.log('focus', editor);
};

const handleBlur = (editor) => {
  // console.log('blur', editor);
};

const customAlert = (info, type) => {
  // alert(`【自定义提示】${type} - ${info}`);
};

const customPaste = (editor, event, callback) => {
  // console.log('ClipboardEvent 粘贴事件对象', event);
  // editor.insertText('xxx');
  // callback(false); // 阻止默认粘贴行为
};

// 按钮点击事件
const insertText = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.insertText('hello world');
};

const printHtml = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  console.log(editor.getHtml());
};

const disable = () => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.disable();
};
</script>
<style scoped>
.container {
  height: calc(100vh - 65px);
  max-width: 1300px;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}

.submit-btn {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 80px;
  height: 40px;
  border: #ffb74d solid 3px;
  border-radius: 5px;
  margin: 5px;
  opacity: 0.3;
  transition: all 0.2s ease;
}

.submit-btn:hover {
  opacity: 1;
  background: #ffb74d;
}

.editor-container {
  width: 99%;
  height: 100vh;
  max-height: 100%;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  border: 1px solid #5d5d5d;
  overflow: hidden;
}

.theme-light .editor-container {
  border: 1px solid #c4c4c4;
}

</style>
<style>
div[data-slate-editor] {
  max-height: 0;
}

.w-e-text-container {
  background: #2a2a2a;
}

.w-e-toolbar {
  background: #1c1c1c;
  border-bottom: 1px solid #595959;
}

.w-e-toolbar button {
  color: #e5e5e5;
  background-color: #262626;
}

.w-e-bar-item button:hover {
  color: white;
  background-color: #494949;
}

.w-e-bar-item .disabled:hover {
  background-color: #494949;
}

.w-e-bar-item-group .w-e-bar-item-menus-container {
  background-color: #262626;
  border: #464646 solid 1px;
}

.w-e-toolbar svg {
  fill: #e5e5e5;
}

.w-e-drop-panel {
  background: #262626;
}

.w-e-panel-content-table {
  background-color: #262626;
  color: white;
}

.w-e-panel-content-table td {
  background-color: #262626;
}

.w-e-panel-content-table td.active {
  background-color: #494949;
}

#w-e-textarea-1 {
  background: #000000;
  color: white;
}

.w-e-bar-divider {
  background: #595959;
}

.w-e-select-list {
  background: #262626;
}

.w-e-select-list ul {
  background: #262626;
  color: white;
}

.w-e-select-list ul .selected {
  background: #494949;
}

.w-e-select-list ul li:hover {
  background: #595959;
}

.w-e-drop-panel, .w-e-select-list {
  border: #464646 solid 1px;
}

.w-e-panel-content-color li {
  border: #464646 solid 1px;
}

.w-e-panel-content-color li .color-block {
  border: #464646 solid 1px;
}

.w-e-hover-bar {
  background: black;
}

/* 亮色模式 */
.theme-light .w-e-text-container {
  background: #ffffff;
}

.theme-light .w-e-toolbar {
  background: #f5f5f5;
  border-bottom: 1px solid #d4d4d4;
}

.theme-light .w-e-toolbar button {
  color: #333333;
  background-color: #ebebeb;
}

.theme-light .w-e-bar-item .disabled svg {
  fill: #b6b6b6;
}

.theme-light .w-e-bar-item .disabled {
  color: #b6b6b6;
}

.theme-light .w-e-bar-item button:hover {
  color: black;
  background-color: #dcdcdc;
}

.theme-light .w-e-bar-item .disabled:hover {
  color: #b6b6b6;
  background-color: #dcdcdc;
}

.theme-light .w-e-bar-item-group .w-e-bar-item-menus-container {
  background-color: #ebebeb;
  border: #d4d4d4 solid 1px;
}

.theme-light .w-e-toolbar svg {
  fill: #333333;
}

.theme-light .w-e-drop-panel {
  background: #ebebeb;
}

.theme-light .w-e-panel-content-table {
  background-color: #ffffff;
  color: black;
}

.theme-light .w-e-panel-content-table td {
  background-color: #ffffff;
}

.theme-light .w-e-panel-content-table td.active {
  background-color: #dcdcdc;
}

.theme-light #w-e-textarea-1 {
  background: #ffffff;
  color: black;
}

.theme-light .w-e-bar-divider {
  background: #d4d4d4;
}

.theme-light .w-e-select-list {
  background: #ebebeb;
}

.theme-light .w-e-select-list ul {
  background: #ebebeb;
  color: black;
}

.theme-light .w-e-select-list ul .selected {
  background: #dcdcdc;
}

.theme-light .w-e-select-list ul li:hover {
  background: #d4d4d4;
}

.theme-light .w-e-drop-panel, .theme-light .w-e-select-list {
  border: #d4d4d4 solid 1px;
}

.theme-light .w-e-panel-content-color li {
  border: #d4d4d4 solid 1px;
}

.theme-light .w-e-panel-content-color li .color-block {
  border: #d4d4d4 solid 1px;
}

.theme-light .w-e-hover-bar {
  background: white;
}

</style>