<template>
  <el-drawer
    v-model="visible"
    :title="isEdit ? '编辑文章' : '新增文章'"
    size="60%"
    :before-close="handleBeforeClose"
  >
    <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
      <el-form-item label="标题" prop="title">
        <el-input v-model="form.title" placeholder="请输入文章标题" />
      </el-form-item>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="分类" prop="cate">
            <el-cascader
              v-model="form.cate"
              :options="cateOptions"
              placeholder="选择分类"
              clearable
              :props="{ expandTrigger: 'hover', emitPath: false }"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="作者" prop="author">
            <el-input v-model="form.author" placeholder="请输入作者姓名" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="简介" prop="desc">
        <el-input
          v-model="form.desc"
          :rows="4"
          type="textarea"
          placeholder="请输入简介"
        />
      </el-form-item>

      <el-form-item label="封面图片" prop="image">
        <div class="uploads">
          <!-- 已有图片显示 -->
          <div
            v-if="form.image && fileList.length === 0"
            class="existing-image"
          >
            <img
              :src="API_BASE_URL + form.image.replace(/\\\//g, '/')"
              alt="已有图片"
            />
            <div class="image-actions">
              <el-button
                type="primary"
                size="small"
                @click="previewExistingImage"
                >预览</el-button
              >
              <el-button type="danger" size="small" @click="removeExistingImage"
                >删除</el-button
              >
            </div>
          </div>

          <!-- 上传组件 -->
          <el-upload
            v-model:file-list="fileList"
            :auto-upload="false"
            :before-upload="beforeImgUpload"
            list-type="picture-card"
            :limit="1"
            :show-file-list="fileList.length > 0"
          >
            <el-icon>
              <Plus />
            </el-icon>

            <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>
                      <ZoomIn />
                    </el-icon>
                  </span>
                  <span
                    class="el-upload-list__item-delete"
                    @click="handleRemove(file)"
                  >
                    <el-icon>
                      <Delete />
                    </el-icon>
                  </span>
                </span>
              </div>
            </template>
          </el-upload>

          <el-drawer v-model="drawerVisible" width="60%" center>
            <div
              style="
                display: flex;
                justify-content: center;
                align-items: center;
              "
            >
              <img
                :src="drawerImageUrl"
                alt="Preview Image"
                style="max-width: 100%; max-height: 70vh; object-fit: contain"
              />
            </div>
          </el-drawer>

          <div class="upload-tip">
            <span>建议尺寸：250px × 140px</span>
          </div>
        </div>
      </el-form-item>

      <el-divider></el-divider>

      <el-form-item label="是否转载" prop="is_trans">
        <el-radio-group v-model="form.is_trans">
          <el-radio-button :value="0">否</el-radio-button>
          <el-radio-button :value="1">是</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="发布地址" prop="transurl" v-if="form.is_trans === 1">
        <el-input v-model="form.transurl" placeholder="请输入转载文章地址" />
      </el-form-item>

      <el-form-item label="内容" prop="content">
        <div class="editor-container">
          <TiptapEditor v-model="form.content" />
        </div>
      </el-form-item>
    </el-form>

    <template #footer>
      <el-divider></el-divider>
      <span class="drawer-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button
          v-if="!isEdit"
          type="warning"
          @click="handleConfirm(0)"
          :loading="submitLoading"
          >草稿</el-button
        >
        <el-button
          type="primary"
          @click="handleConfirm(1)"
          :loading="submitLoading"
          >提交</el-button
        >
      </span>
    </template>
  </el-drawer>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, nextTick, onMounted, computed } from "vue";
import { ElMessage, ElUpload } from "element-plus";
import { createArticle, editArticle, listCategories } from "@/api/article.js";
import { uploadFile } from "@/api/file.js";

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  isEdit: {
    type: Boolean,
    default: false,
  },
  model: {
    type: Object,
    default: () => null,
  },
});

const emit = defineEmits(["update:modelValue", "saved"]);

const visible = ref(false);
const submitLoading = ref(false);
const formRef = ref(null);

const handleBeforeClose = (done: () => void) => {
  handleCancel();
  done();
};

const cateOptions = ref([]);

const form = reactive({
  title: "",
  author: "",
  cate: "",
  content: "",
  image: "",
  desc: "",
  is_trans: 0,
  transurl: null,
});

const rules = {
  title: [
    { required: true, message: "请输入文章标题", trigger: "blur" },
    {
      min: 2,
      max: 200,
      message: "标题长度在 2 到 200 个字符",
      trigger: "blur",
    },
  ],
  author: [
    { required: true, message: "请输入作者", trigger: "blur" },
    { max: 50, message: "作者姓名不能超过50个字符", trigger: "blur" },
  ],
  content: [{ required: true, message: "请输入文章内容", trigger: "blur" }],
};

// 获取分类列表
async function fetchCategories() {
  try {
    const res = await listCategories();
    if (res.code === 200) {
      const categories = Array.isArray(res.data) ? res.data : [];
      // 将分类转换为树形结构
      cateOptions.value = buildCategoryTree(categories);
    }
  } catch (error) {
    console.error("获取分类失败:", error);
  }
}

// 构建分类树形结构
function buildCategoryTree(categories, parentCid = 0) {
  return categories
    .filter((cate) => Number(cate.cid) === Number(parentCid))
    .map((cate) => {
      const children = buildCategoryTree(categories, cate.id);
      return {
        ...cate,
        label: cate.name,
        value: cate.id,
        children: children.length > 0 ? children : undefined,
      };
    });
}

// 上传相关
const fileList = ref<any[]>([]);
const drawerVisible = ref(false);
const drawerImageUrl = ref("");
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;

function beforeImgUpload(file: File) {
  const isImage = file.type.startsWith("image/");
  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isImage) ElMessage.error("仅支持图片格式");
  if (!isLt10M) ElMessage.error("图片大小不能超过10MB");
  return isImage && isLt10M;
}

function handlePictureCardPreview(file: any) {
  drawerImageUrl.value = file.url;
  drawerVisible.value = true;
}

function handleRemove(file: any) {
  fileList.value = [];
  form.image = "";
}

function removeExistingImage() {
  form.image = "";
}

function previewExistingImage() {
  const imagePath = form.image.replace(/\\\//g, "/");
  drawerImageUrl.value = API_BASE_URL + imagePath;
  drawerVisible.value = true;
}

// 监听对话框显示状态
watch(
  () => props.modelValue,
  (newVal) => {
    visible.value = newVal;
    if (newVal) {
      if (props.isEdit && props.model) {
        // 编辑模式，填充表单数据
        const modelData = props.model._raw || props.model;
        nextTick(() => {
          Object.assign(form, {
            title: modelData.title || "",
            author: modelData.author || "",
            cate: modelData.cate || "",
            content: modelData.content || "",
            desc: modelData.desc || "",
            is_trans: modelData.is_trans || 0,
            transurl: modelData.transurl || null,
            image: modelData.image || "",
          });
          fileList.value = []; // 重置文件列表
        });
      } else {
        // 新增模式，重置表单
        resetForm();
      }
    }
  },
);

function handleCancel() {
  emit("update:modelValue", false);
  resetForm();
}

async function handleConfirm(status = 1) {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      submitLoading.value = true;

      try {
        let imageUrl = form.image;

        // 如果有新选择的文件，先上传图片
        if (fileList.value.length > 0 && fileList.value[0].raw) {
          const uploadFormData = new FormData();
          uploadFormData.append("file", fileList.value[0].raw);
          uploadFormData.append("cate", "article");

          const uploadRes = await uploadFile(uploadFormData);
          // 200=新文件上传成功，201=文件已存在（使用已有文件的链接）
          if (
            (uploadRes.code === 200 || uploadRes.code === 201) &&
            uploadRes.data &&
            uploadRes.data.url
          ) {
            imageUrl = uploadRes.data.url;
          } else {
            ElMessage.error("图片上传失败：" + (uploadRes.msg || "未知错误"));
            return;
          }
        }

        // 添加状态参数，0为草稿，1为提交
        const submitData = {
          title: form.title,
          author: form.author,
          cate: form.cate,
          content: form.content,
          desc: form.desc,
          image: imageUrl,
          is_trans: form.is_trans,
          transurl: form.is_trans === 1 ? form.transurl : null,
          status: status, // 0为草稿，1为提交
        };

        // 根据新增/编辑模式选择不同的API调用函数
        const isCreateMode = !props.isEdit;
        let res;
        let resp;

        if (isCreateMode) {
          // 新增模式，使用createArticle接口
          const createArticleWithCheck = async (ignoreSimilarity = false) => {
            const data = {
              ...submitData,
              ...(ignoreSimilarity && { ignore_similarity: 1 }),
            };
            return await createArticle(data);
          };

          res = await createArticleWithCheck();
          resp =
            res && typeof res.code !== "undefined"
              ? res
              : res && res.data
                ? res.data
                : res;

          // 检测到相似标题，显示确认对话框
          if (resp && resp.code === 409) {
            const similarArticles = resp.data?.similar_articles || [];
            // 构建带样式的确认消息
            const similarArticlesList = similarArticles
              .map(
                (article: any) =>
                  `\n<div style="margin: 8px 0; padding: 8px; background: #f5f7fa; border-radius: 4px;">\n<div style="font-weight: bold; color: #303133;">${article.title}</div>\n<div style="color: #606266; font-size: 14px; margin-top: 4px;">相似度：${article.similarity}%</div>\n</div>\n`,
              )
              .join("");

            const confirmMessage = `\n<div>\n\n${similarArticlesList} \n<p style="margin-top: 16px; color: #303133;">是否继续创建？</p>\n</div>\n`;

            // 使用Element Plus的confirm对话框
            const { ElMessageBox } = await import("element-plus");
            try {
              await ElMessageBox.confirm(confirmMessage, "检测到相似标题", {
                confirmButtonText: "继续创建",
                cancelButtonText: "取消",
                type: "warning",
                dangerouslyUseHTMLString: true,
              });
              // 用户确认继续，再次调用接口并忽略相似度检测
              res = await createArticleWithCheck(true);
              resp =
                res && typeof res.code !== "undefined"
                  ? res
                  : res && res.data
                    ? res.data
                    : res;
            } catch (error) {
              // 用户取消创建
              return;
            }
          }
        } else {
          // 编辑模式，使用editArticle接口
          // 获取文章ID
          const modelData = props.model._raw || props.model;
          const articleId = modelData.id;

          if (!articleId) {
            ElMessage.error("文章ID不存在，无法更新");
            return;
          }

          // 构建编辑请求数据，不包含文章ID（ID通过URL参数传递）
          const editData = {
            ...submitData,
          };

          res = await editArticle(articleId, editData);
          resp =
            res && typeof res.code !== "undefined"
              ? res
              : res && res.data
                ? res.data
                : res;
        }

        if (
          resp &&
          resp.code === 200 &&
          (resp.message === "success" || resp.msg === "success")
        ) {
          ElMessage.success(
            status === 0
              ? "保存草稿成功"
              : props.isEdit
                ? "更新成功"
                : "创建成功",
          );
          emit("update:modelValue", false);
          emit("saved");
        } else {
          ElMessage.error(
            (resp && resp.message) ||
              (resp && resp.msg) ||
              (status === 0
                ? "保存草稿失败"
                : props.isEdit
                  ? "更新失败"
                  : "创建失败"),
          );
        }
      } catch (error) {
        ElMessage.error(
          status === 0
            ? "保存草稿失败"
            : props.isEdit
              ? "更新失败"
              : "创建失败",
        );
      } finally {
        submitLoading.value = false;
      }
    }
  });
}

function resetForm() {
  // 重置表单
  if (formRef.value) {
    formRef.value.resetFields();
  }
  // 重置文件列表
  fileList.value = [];
  // 重置表单数据
  Object.assign(form, {
    title: "",
    author: "",
    cate: "",
    content: "",
    image: "",
    desc: "",
    is_trans: 0,
    transurl: null,
  });
}

// 暴露重置方法（如果需要的话）
defineExpose({
  resetForm: () => {
    formRef.value?.resetFields();
  },
});

onMounted(() => {
  fetchCategories();
});
</script>

<style lang="less" scoped>
.editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;

  &:focus {
    outline: none !important;
  }

  :deep(.tiptap) {
    p {
      color: #1a1a2e !important;
      margin: 0.5em 0 !important;
    }

    h1, h2, h3, h4, h5, h6 {
      color: #1a1a2e !important;
      font-weight: 600 !important;
    }

    a {
      color: #3973ff !important;
      text-decoration: underline !important;

      &:hover {
        color: #3973ff !important;
        opacity: 0.8 !important;
      }
    }

    code {
      background-color: #f5f7fa !important;
      color: #1a1a2e !important;
      border: 1px solid #e4e7ed !important;
      padding: 2px 6px !important;
      border-radius: 3px !important;
      font-family: 'Consolas', 'Monaco', monospace;
      font-size: 13px;
    }

    pre {
      background-color: #f5f7fa !important;
      border: 1px solid #e4e7ed !important;
      color: #1a1a2e !important;
      border-radius: 4px !important;
      padding: 12px 16px;
      margin: 12px 0;
      overflow-x: auto;

      code {
        background-color: transparent !important;
        border: none !important;
        padding: 0 !important;
      }
    }

    blockquote {
      border-left: 4px solid #3973ff !important;
      background-color: #f5f7fa !important;
      color: #606266 !important;
      padding: 0.6em 1.2em !important;
      margin: 1em 0 !important;
    }

    table {
      border-collapse: collapse !important;
      border: 1px solid #e4e7ed !important;

      th, td {
        border: 1px solid #e4e7ed !important;
        background-color: #ffffff !important;
        color: #1a1a2e !important;
        padding: 8px 12px;
      }

      th {
        background-color: #f5f7fa !important;
      }
    }

    ul, ol {
      color: #1a1a2e !important;
      padding-left: 24px;
      margin: 8px 0;
    }

    li {
      color: #1a1a2e !important;
      line-height: 1.8;
      margin: 4px 0;
    }

    hr {
      border-top: 1px solid #e4e7ed !important;
      margin: 16px 0;
    }

    img {
      max-width: 100%;
      border-radius: 4px;
      margin: 8px 0;
    }
  }
}

.drawer-footer {
  text-align: right;
}

.uploads {
  display: flex;
  gap: 10px;
}

.upload-tip {
  font-size: 12px;
  color: #999;
}

.existing-image {
  position: relative;
  width: 148px;
  height: 148px;
  border: 1px solid #dcdfe6;
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 8px;
}

.existing-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-actions {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity 0.3s;
}

.existing-image:hover .image-actions {
  opacity: 1;
}

::deep(.el-message-box) {
  width: 800px !important;
}
</style>
