<script setup>
import {defineEmits, defineProps, onMounted, ref} from 'vue';
import {
  ElButton,
  ElForm,
  ElFormItem,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElSelect,
  ElUpload
} from 'element-plus';
import {
  AccessibilityHelp,
  Alignment,
  Autoformat,
  AutoLink,
  Autosave,
  BalloonToolbar,
  BlockQuote,
  Bold,
  ClassicEditor,
  CodeBlock,
  Essentials,
  FindAndReplace,
  GeneralHtmlSupport,
  Heading,
  HorizontalLine,
  Indent,
  IndentBlock,
  Italic,
  Link,
  Paragraph,
  SelectAll,
  Style,
  Table,
  TableCaption,
  TableCellProperties,
  TableColumnResize,
  TableProperties,
  TableToolbar,
  TextTransformation,
  Undo
} from 'ckeditor5';

import translations from 'ckeditor5/translations/zh-cn.js';

import 'ckeditor5/ckeditor5.css';
import {Delete, Plus, Refresh, ZoomIn} from "@element-plus/icons-vue";
import {useRoute, useRouter} from "vue-router";
import {useStore} from "vuex";
import axios from "axios";

const route = useRoute();
const router = useRouter();
const store = useStore();
const token = ref('')
const form = ref({
  token: '',
  title: '',
  author: '',
  content: '',
  summary: '',
  tenant: '',
  imagePath: ''
});
const createMode = ref(false);
const componentMode = ref(false);
const modeTitle = ref('');

const fileList = ref([]); // 用于存储上传文件的列表
const basePath = '/api/news'
const uploadUrl = basePath + '/uploadPic'; // 上传的后端地址
const dialogImageUrl = ref('');
const dialogVisible = ref(false);  // 用于图片放大预览
const props = defineProps({
  mode: {
    type: String,
    required: false
  },
  id: {
    type: String,
    required: false
  }
});
const containerStyle = ref('form-container')

const emit = defineEmits(['setNewsDialogInvisible']);
const setNewsDialogInvisible = (changed) => {
  emit('setNewsDialogInvisible', changed);
};

//下面是编辑模式需要的一些变量
const id = ref('');

const beforeUpload = (file) => {
  // 检查文件类型是否为图片（png, jpg, jpeg）
  const isImage = file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/jpeg';
  if (!isImage) {
    ElMessage.error('只能上传 png/jpg/jpeg 格式的图片文件！');
    return false;
  }

  // 检查文件大小是否超过 5MB
  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isLt5M) {
    ElMessage.error('上传文件大小不能超过 5MB！');
    return false;
  }

  return true;
};

const handleSuccess = (response, file, fileList) => {
  file.url = response.url;
};

const handleError = (error, file, fileList) => {
  ElMessage.error('图片上传失败，请重试！');
};

const handleChange = (file, fileList) => {
  // 处理文件选择变化时的逻辑，确保只选择最新上传的文件
  if (fileList.length > 1) {
    fileList.splice(0, fileList.length - 1)
  }
};

const handlePictureCardPreview = (file) => {
  dialogImageUrl.value = file.url
  dialogVisible.value = true
}
const handleRemove = (file) => {
  fileList.value = fileList.value.filter((item) => item.uid !== file.uid);
  console.log(file)
}

const handleCommit = async () => {
  // 判断form中的每一个字段都不为空字符串且不为null
  if (form.value.title === '' || form.value.author === '' || form.value.content === '' || form.value.summary === '' || form.value.tenant === '') {
    await ElMessageBox.alert('请填写完整信息！');
    return;
  }
  if (fileList.value.length === 0) {
    await ElMessageBox.alert('请选择图片！');
    return;
  }
  form.value.imagePath = fileList.value[0].url;
  if (createMode.value) {
    try {
      const response = await axios.post(basePath, form.value);
      ElMessage.success('添加成功！');
      if (componentMode){
        setNewsDialogInvisible(true);
      }
      else{
        router.push('/news');
      }
    } catch (e) {
      await ElMessageBox.alert(e.response.data.message);
    }
  } else {
    try {
      const response = await axios.put(`${basePath}/${id.value}`, form.value);
      ElMessage.success('修改成功！');
      if (componentMode){
        setNewsDialogInvisible(true);
      }
      else{
        router.push('/news');
      }
    } catch (e) {
      await ElMessageBox.alert(e.response.data.message);
    }

  }
};

const handleCancel = () => {
  if (componentMode){
    setNewsDialogInvisible(false);
  }
  else{
    router.push('/news');
  }
};

const isLayoutReady = ref(false);
const config = ref(null); // CKEditor needs the DOM tree before calculating the configuration.
const editor = ClassicEditor;

const fetchNewsDetail = async () => {
  let params = {
    token: token.value,
  }
  const res = await axios.get(basePath + '/' + id.value, {params});
  form.value.title = res.data.title;
  form.value.author = res.data.author;
  form.value.content = res.data.content;
  form.value.summary = res.data.summary;
  form.value.tenant = res.data.tenant;
  form.value.imagePath = res.data.imagePath;
  fileList.value.push({url: res.data.imagePath});
}

onMounted(() => {
  token.value = store.getters['authentication/token'];
  form.value.token = token.value;
  if (props.mode !== undefined){
    componentMode.value = true;
    containerStyle.value = 'form-container-component'
    if (props.mode === 'create'){
      createMode.value = true;
      modeTitle.value = '添加资讯';
    }
    else if (props.mode === 'edit'){
      createMode.value = false;
      id.value = props.id;
      modeTitle.value = '修改资讯';
      fetchNewsDetail();
    }
  }
  else if (route.query.mode === 'create' || route.params.mode === 'create') {
    createMode.value = true;
    modeTitle.value = '添加资讯';
  } else if (route.query.mode === 'edit' || route.params.mode === 'edit') {
    id.value = route.params.id === undefined ? route.query.id : route.params.id;
    createMode.value = false;
    modeTitle.value = '修改资讯';
    fetchNewsDetail();
  }

  config.value = {
    toolbar: {
      items: [
        'undo',
        'redo',
        '|',
        'heading',
        'style',
        '|',
        'bold',
        'italic',
        '|',
        'link',
        'insertTable',
        'blockQuote',
        'codeBlock',
        '|',
        'alignment',
        '|',
        'indent',
        'outdent'
      ],
      shouldNotGroupWhenFull: false
    },
    plugins: [
      AccessibilityHelp,
      Alignment,
      Autoformat,
      AutoLink,
      Autosave,
      BalloonToolbar,
      BlockQuote,
      Bold,
      CodeBlock,
      Essentials,
      FindAndReplace,
      GeneralHtmlSupport,
      Heading,
      HorizontalLine,
      Indent,
      IndentBlock,
      Italic,
      Link,
      Paragraph,
      SelectAll,
      Style,
      Table,
      TableCaption,
      TableCellProperties,
      TableColumnResize,
      TableProperties,
      TableToolbar,
      TextTransformation,
      Undo
    ],
    balloonToolbar: ['bold', 'italic', '|', 'link'],
    heading: {
      options: [
        {
          model: 'paragraph',
          title: 'Paragraph',
          class: 'ck-heading_paragraph'
        },
        {
          model: 'heading1',
          view: 'h1',
          title: 'Heading 1',
          class: 'ck-heading_heading1'
        },
        {
          model: 'heading2',
          view: 'h2',
          title: 'Heading 2',
          class: 'ck-heading_heading2'
        },
        {
          model: 'heading3',
          view: 'h3',
          title: 'Heading 3',
          class: 'ck-heading_heading3'
        },
        {
          model: 'heading4',
          view: 'h4',
          title: 'Heading 4',
          class: 'ck-heading_heading4'
        },
        {
          model: 'heading5',
          view: 'h5',
          title: 'Heading 5',
          class: 'ck-heading_heading5'
        },
        {
          model: 'heading6',
          view: 'h6',
          title: 'Heading 6',
          class: 'ck-heading_heading6'
        }
      ]
    },
    htmlSupport: {
      allow: [
        {
          name: /^.*$/,
          styles: true,
          attributes: true,
          classes: true
        }
      ]
    },
    initialData: '',
    language: 'zh-cn',
    link: {
      addTargetToExternalLinks: true,
      defaultProtocol: 'https://',
      decorators: {
        toggleDownloadable: {
          mode: 'manual',
          label: 'Downloadable',
          attributes: {
            download: 'file'
          }
        }
      }
    },
    menuBar: {
      isVisible: true
    },
    placeholder: '请在此处输入你的文章',
    style: {
      definitions: [
        {
          name: 'Article category',
          element: 'h3',
          classes: ['category']
        },
        {
          name: 'Title',
          element: 'h2',
          classes: ['document-title']
        },
        {
          name: 'Subtitle',
          element: 'h3',
          classes: ['document-subtitle']
        },
        {
          name: 'Info box',
          element: 'p',
          classes: ['info-box']
        },
        {
          name: 'Side quote',
          element: 'blockquote',
          classes: ['side-quote']
        },
        {
          name: 'Marker',
          element: 'span',
          classes: ['marker']
        },
        {
          name: 'Spoiler',
          element: 'span',
          classes: ['spoiler']
        },
        {
          name: 'Code (dark)',
          element: 'pre',
          classes: ['fancy-code', 'fancy-code-dark']
        },
        {
          name: 'Code (bright)',
          element: 'pre',
          classes: ['fancy-code', 'fancy-code-bright']
        }
      ]
    },
    table: {
      contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
    },
    translations: [translations]
  };

  isLayoutReady.value = true;
});
</script>

<template>
  <div :class="containerStyle">
    <ElForm :model="form" label-width="120px" @submit.prevent="handleCommit">
      <h2>{{ modeTitle }}</h2>
      <ElFormItem label="新闻标题" required>
        <ElInput v-model="form.title" placeholder="请输入新闻标题" required></ElInput>
      </ElFormItem>
      <ElFormItem label="新闻图片路径" required>
        <el-upload
            :action="uploadUrl"
            :limit="2"
            :before-upload="beforeUpload"
            :on-success="handleSuccess"
            :on-error="handleError"
            :on-change="handleChange"
            :file-list="fileList"
            list-type="picture-card"
            auto-upload
            v-model:file-list="fileList"
            required
        >
          <template #file="{ file }">
            <div>
              <img class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
              <span class="el-upload-list__item-actions">
          <span
              class="el-upload-list__item-preview"
              @click="handlePictureCardPreview(file)"
          >
            <el-icon><zoom-in/></el-icon>
          </span>
          <span
              class="el-upload-list__item-delete"
              @click="handleRemove(file)"
          >
            <el-icon><Delete/></el-icon>
          </span>
        </span>
            </div>
          </template>
          <el-icon v-if="fileList.length === 0">
            <Plus/>
          </el-icon>
          <el-icon v-else>
            <Refresh/>
          </el-icon>
        </el-upload>
        <div class="tip">
          请上传大小不超过 <span style="color: red;">5MB</span> 格式为 <span style="color: red;">png/jpg/jpeg</span> 的文件
        </div>
      </ElFormItem>
      <ElFormItem label="新闻内容" required>
        <div class="editor-container editor-container_classic-editor editor-container_include-style"
             ref="editorContainerElement">
          <div class="editor-container__editor">
            <div ref="editorElement">
              <ckeditor v-if="isLayoutReady" v-model="form.content" :editor="editor" :config="config"/>
            </div>
          </div>
        </div>
      </ElFormItem>
      <ElFormItem label="作者" required>
        <ElInput v-model="form.author" placeholder="请输入作者" required></ElInput>
      </ElFormItem>
      <ElFormItem label="新闻简介" required>
        <ElInput v-model="form.summary" placeholder="请输入新闻简介" required></ElInput>
      </ElFormItem>
      <ElFormItem label="选择租户" required>
        <ElSelect v-model="form.tenant" placeholder="请选择" class="dynamic-width-select">
          <ElOption label="Option 1" value="option1"></ElOption>
          <ElOption label="Option 2" value="option2"></ElOption>
          <ElOption label="Option 3" value="option3"></ElOption>
        </ElSelect>
      </ElFormItem>
      <ElFormItem>
        <ElButton type="primary" native-type="submit">确定</ElButton>
        <ElButton @click="handleCancel">取消</ElButton>
      </ElFormItem>
    </ElForm>
  </div>

  <el-dialog v-model="dialogVisible" class="image-preview">
    <img w-full :src="dialogImageUrl" alt="Preview Image"/>
  </el-dialog>
</template>

<style scoped>
.form-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: white;
  overflow-y: auto; /* 使容器在内容溢出时出现滚动条 */
}

.image-preview {
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-preview img {
  max-width: 100%;
  height: auto;
}

.tip {
  margin-top: 8px;
  color: #727272;
  font-size: 12px;
}

.el-form {
  background: white;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  width: 55%;
  max-height: 90vh; /* 确保表单不会超过视口高度 */
  overflow-y: auto; /* 使表单在内容溢出时出现滚动条 */
}

.el-form-item {
  margin-bottom: 1rem;
  text-align: left;
}

.el-form-item label {
  display: block;
  margin-bottom: 0.5rem;
}

.el-input,
.el-select {
  width: 100%;
}

.el-button--primary {
  background-color: #007bff;
  color: white;
}

.el-button--primary:hover {
  background-color: #0056b3;
}

.dynamic-width-select {
  min-width: 30%;
  max-width: 100%;
  width: auto; /* 使宽度根据内容调整 */
}

.form-container-component {
  display: flex;
  justify-content: center;
  align-items: center;
  height: auto;
  background: white;
  overflow-y: auto; /* 使容器在内容溢出时出现滚动条 */
}

.form-container-component .el-form {
  background: white;
  padding: 2rem;

  width: 100%;
  height: 100%;
  max-height: 90vh; /* 确保表单不会超过视口高度 */
  overflow-y: auto; /* 使表单在内容溢出时出现滚动条 */
}
</style>