<script setup>
import axios from 'axios';
import { ref, reactive, onMounted } from 'vue';
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import {getNews,getNewsDetail,updateNews,saveDetail} from '@/api/index'

const baseURL = window.config?.baseUrl

// 新闻列表
const newsList = ref([]);

// 分页与状态过滤
const page = ref(1);
const pageSize = ref(10);
const totalPages = ref(1);
const statusFilter = ref("");
const loading = ref(false);

// 编辑新闻表单
const editingNews = reactive({
  title: "",
  cover_image: "",
  snapshot: "",
  content: "",
  status: "draft",
  slug: "",
  datetime: null,
});
const showForm = ref(false);
const isEditing = ref(false);

// 响应式引用 Quill 实例
const quillInstance = ref(null);

// 当编辑器就绪时保存实例
const onEditorReady = (quill) => {
  quillInstance.value = quill;
  quill.root.addEventListener('paste', handlePaste);
};


// ---------------- Quill 配置 ----------------
const editorOption= {
  placeholder: "请在这里输入",
  modules:{
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'], //加粗，斜体，下划线，删除线
        ['blockquote', 'code-block'], //引用，代码块
        [{'header': 1}, {'header': 2}], // 标题，键值对的形式；1、2表示字体大小
        [{'list': 'ordered'}, {'list': 'bullet'}], //列表
        [{'script': 'sub'}, {'script': 'super'}], // 上下标
        [{'indent': '-1'}, {'indent': '+1'}], // 缩进
        [{'direction': 'rtl'}], // 文本方向
        [{'size': ['small', false, 'large', 'huge']}], // 字体大小
        [{'header': [1, 2, 3, 4, 5, 6, false]}], //几级标题
        [{'color': []}, {'background': []}], // 字体颜色，字体背景颜色
        [{'font': []}], //字体
        [{'align': []}], //对齐方式
        ['clean'], //清除字体样式
        ['image', 'video'] //上传图片、上传视频
      ],
      handlers: {
        image: imageHandler,
      }
    },
  }
};

async function handlePaste(event) {
  const clipboardData = event.clipboardData || window.clipboardData;
  if (!clipboardData) return;

  const items = clipboardData.items;
  if (!items) return;

  // 检查是否有图片类型
  let blob = null;
  for (let i = 0; i < items.length; i++) {
    if (items[i].type.indexOf('image') === 0) {
      blob = items[i].getAsFile();
      break;
    }
  }

  if (!blob) return;

  // 阻止默认粘贴行为（避免插入 base64）
  event.preventDefault();

  try {
    // 上传图片
    const imageUrl = await uploadImage(blob);

    // 获取当前光标位置
    const quill = quillInstance.value;
    const selection = quill.getSelection();
    const index = selection ? selection.index : quill.getLength();

    // 插入图片 URL
    quill.insertEmbed(index, 'image', imageUrl);

    // 可选：移动光标到图片后
    quill.setSelection(index + 1);
  } catch (error) {
    console.error('粘贴图片上传失败:', error);
    // 可选：提示用户
  }
}

function imageHandler() {
  const input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.setAttribute('accept', 'image/*');
  input.click();

  input.onchange = () => {
    const file = input.files[0];
    // 将图片上传到服务器
    uploadImage(file)
      .then((imageUrl) => {
        // 将图片 URL 插入到编辑器中
        const quill = quillInstance.value
        const range = quill.getSelection();
        quill.insertEmbed(range.index, 'image', imageUrl);
      })
      .catch((error) => {
        console.error('图片上传失败：', error);
      });
  };
}

// ----------------- 获取新闻 -----------------
const fetchNews = async () => {
  try {
    let query = {
      status: statusFilter.value || undefined,
      page: page.value,
      page_size: pageSize.value,
    }
    let {code, data, pagination} = await getNews(query)
    if (code === 0) {
      newsList.value = data;
      totalPages.value = pagination.total_pages;
    }
  } catch (err) {
    console.error("获取新闻失败", err);
  }
};

// ----------------- 添加/编辑 -----------------
const saveNews = async () => {
  try {
    editingNews.content = quillInstance.value.root.innerHTML
    if (isEditing.value) {
      await updateNews(editingNews);
    } else {
      await saveDetail(editingNews);
    }
    showForm.value = false;
    fetchNews();
  } catch (err) {
    console.error("保存新闻失败", err);
  }
};

const editNews = async (news) => {
  loading.value = true;
  try {
    let query = {
      slug: news.slug,
    }
    let {code, data} = await getNewsDetail(query)
    if (code === 0) {
      Object.assign(editingNews, data);
      isEditing.value = true;
      showForm.value = true;
      quillInstance.value.clipboard.dangerouslyPasteHTML(editingNews.content)
    }
  } finally {
    loading.value = false;
  }
};

const addNews = () => {
  Object.assign(editingNews, {
    title: "",
    cover_image: "",
    snapshot: "",
    content: "",
    status: "draft",
    slug: "",
    datetime: null,
  });
  isEditing.value = false;
  showForm.value = true;
};

// 分页
const prevPage = () => {
  if (page.value > 1) {
    page.value--;
    fetchNews();
  }
};
const nextPage = () => {
  if (page.value < totalPages.value) {
    page.value++;
    fetchNews();
  }
};

function handleImageUpload(event) {
  const file = event.target.files[0];
  if (!file) return;

  uploadImage(file)
    .then((imageUrl) => {
      editingNews.cover_image = imageUrl;
    })
    .catch((error) => {
      console.error('封面图片上传失败:', error);
    });
}

function uploadImage(file) {
  return new Promise((resolve, reject) => {
    const formData = new FormData();
    formData.append('file', file);

    fetch(`${baseURL}update/img`, {
      method: 'POST',
      body: formData,
    })
      .then((response) => response.json())
      .then((data) => {
        if (data.code === 0) {
        console.log(data)
          resolve(`${baseURL}download/img/${data.data}`);
        } else {
          reject(data.msg);
        }
      })
      .catch((error) => {
        reject(error);
      });
  });
}

onMounted(() => {
  fetchNews();
  addNews();
});
</script>

<template>
  <div class="page">
    <!-- 操作栏 -->
    <div class="my-card flex j-s a-c toolbar">
      <select v-model="statusFilter" @change="fetchNews">
        <option value="">全部状态</option>
        <option value="draft">草稿</option>
        <option value="published">发布</option>
        <option value="disable">关闭</option>
      </select>
      <button @click="addNews">添加新闻</button>
    </div>

    <!-- 新闻列表 -->
    <div class="my-card">
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>标题</th>
            <th>状态</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="n in newsList" :key="n.slug">
            <td>{{ n.id }}</td>
            <td>{{ n.title }}</td>
            <td>{{ n.status }}</td>
            <td>
              <button @click="editNews(n)">编辑</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页 -->
    <div class="my-card flex j-s a-c pagination">
      <button @click="prevPage" :disabled="page === 1">上一页</button>
      <span>{{ page }} / {{ totalPages }}</span>
      <button @click="nextPage" :disabled="page === totalPages">下一页</button>
    </div>

    <!-- 添加/编辑表单 -->
    <div v-if="showForm" class="my-card news-form">
      <h3>{{ isEditing ? "编辑新闻" : "添加新闻" }}</h3>
      <label>标题: <input v-model="editingNews.title" /></label><br />
      <label>发布时间:<input type="date" v-model="editingNews.datetime" /></label><br />
      <label>封面图片:
        <input type="file" accept="image/*" @change="handleImageUpload" />
      </label>
      <div v-if="editingNews.cover_image">
        <img :src="editingNews.cover_image" alt="封面预览" style="max-width:200px; margin-top:10px;" />
      </div>
      <label>内容简介: <textarea class="snapshot" v-model="editingNews.snapshot"></textarea></label><br />
      <label>内容:</label>
      <quill-editor content-type="html" 
        theme="snow" style="height: 300px" :options="editorOption" @ready="onEditorReady"/>
      <label>状态:
        <select v-model="editingNews.status">
          <option value="draft">草稿</option>
          <option value="published">发布</option>
          <option value="disable">关闭</option>
        </select>
      </label><br />
      <button @click="saveNews">{{ isEditing ? "保存修改" : "添加" }}</button>
      <button @click="showForm=false">取消</button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.my-card {
  width: 80%;
  padding: 20px;
  margin-bottom: 20px;
  margin: 20px auto;  
  border: 1px solid #eee;
  border-radius: 8px;
  background-color: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}

.flex {
  display: flex;
}
.j-s { justify-content: space-between; }
.a-c { align-items: center; }

.toolbar select,
.toolbar button {
  margin-right: 10px;
  padding: 6px 12px;
  font-size: 14px;
  border-radius: 4px;
  border: 1px solid #ccc;
  background-color: #fafafa;
  transition: 0.2s;
}

.toolbar button:hover {
  background-color: #007BFF;
  color: #fff;
  border-color: #007BFF;
  cursor: pointer;
}

table {
  width: 100%;
  border-collapse: collapse;
  th, td {
    padding: 10px 12px;
    border: 1px solid #ddd;
    text-align: left;
  }
  th {
    background-color: #f0f0f0;
    font-weight: 600;
  }
  tbody tr:nth-child(odd) { background-color: #fdfdfd; }
  tbody tr:hover { background-color: #f5faff; }
}

button {
  padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid #ccc;
  background-color: #fafafa;
  transition: 0.2s;
}
button:hover {
  background-color: #007BFF;
  color: #fff;
  border-color: #007BFF;
  cursor: pointer;
}

.pagination {
  gap: 10px;
  button {
    min-width: 80px;
    text-align: center;
  }
}
.snapshot{
  height: 100px;
  font-size: 14px;
}
.news-form input,
.news-form textarea,
.news-form select {
  width: 100%;
  margin-bottom: 12px;
  padding: 8px 10px;
  border-radius: 4px;
  border: 1px solid #ccc;
  font-size: 14px;
  transition: 0.2s;
}
.news-form input:focus,
.news-form textarea:focus,
.news-form select:focus {
  border-color: #007BFF;
  outline: none;
}

.news-form button {
  margin-right: 10px;
  min-width: 100px;
}
.news-form h3 {
  margin-bottom: 15px;
  font-size: 18px;
  color: #333;
}
</style>
