<template>
  <div class="submit-page">
    <Navbar />
    <Loading :visible="isLoading" :text="loadingText" />
    
    <!-- 课程选择模态窗口 -->
    <div class="course-selector-modal" v-if="showCourseSelector">
      <div class="modal-overlay" @click="closeCourseSelector"></div>
      <div class="modal-container">
        <div class="modal-header">
          <h3>选择课程</h3>
          <button class="close-btn" @click="closeCourseSelector">×</button>
        </div>
        <div class="modal-body">
          <div class="search-bar">
            <input 
              type="text" 
              v-model="courseSearch" 
              placeholder="请输入课程名称"
              class="search-input" 
              @keyup.enter="searchCourses"
            />
            <button class="search-btn" @click="searchCourses">搜索</button>
          </div>
          
          <div class="course-results">
            <div v-if="searchLoading" class="course-loading">
              <div class="spinner"></div>
              <span>搜索中...</span>
            </div>
            <div v-else-if="searchError" class="search-error">
              {{ searchError }}
            </div>
            <div v-else-if="courseResults.length === 0" class="no-results">
              未找到相关课程
            </div>
            <table v-else class="course-table">
              <thead>
                <tr>
                  <th>选择</th>
                  <th>课程名称</th>
                  <th>课程类别</th>
                  <th>授课教师</th>
                  <th>评分</th>
                </tr>
              </thead>
              <tbody>
                <tr 
                  v-for="course in courseResults" 
                  :key="course.course_id"
                  @click="selectCourse(course)"
                  :class="{ 'selected': selectedCourse && selectedCourse.course_id === course.course_id }"
                >
                  <td>
                    <input 
                      type="radio" 
                      :checked="selectedCourse && selectedCourse.course_id === course.course_id" 
                      @click.stop="selectCourse(course)"
                    />
                  </td>
                  <td>{{ course.course_name }}</td>
                  <td>{{ getCategoryName(course.category_id) }}</td>
                  <td>{{ course.teachers }}</td>
                  <td>
                    <span class="rating">{{ course.rating }}</span>
                    <span class="rating-count">({{ course.rating_count }}人评)</span>
                  </td>
                </tr>
              </tbody>
            </table>
            
            <!-- 分页控件 -->
            <div class="pagination" v-if="totalPages > 1">
              <button 
                class="page-btn" 
                :disabled="currentPage === 1"
                @click="changePage(currentPage - 1)"
              >
                上一页
              </button>
              
              <span class="page-info">第 {{ currentPage }} / {{ totalPages }} 页</span>
              
              <button 
                class="page-btn" 
                :disabled="currentPage === totalPages"
                @click="changePage(currentPage + 1)"
              >
                下一页
              </button>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button 
            class="btn btn-secondary" 
            @click="closeCourseSelector"
          >
            取消
          </button>
          <button 
            class="btn btn-primary" 
            @click="confirmCourseSelection"
            :disabled="!selectedCourse"
          >
            确定
          </button>
        </div>
      </div>
    </div>
    
    <div class="container">
      <div class="page-header">
        <h1>{{ isEditMode ? '编辑投稿内容' : '内容投稿' }}</h1>
        <p class="sub-title">感谢您分享您的学习资源或独到见解！</p>
      </div>
      
      <!-- 投稿表单 -->
      <div class="submission-form">
        <div class="form-section">
          <div class="form-group">
            <label for="title">标题 {{ isEditMode ? '(如需更改标题，请不要更改【edit】前缀)' : '' }}</label>
            <input 
              type="text" 
              id="title" 
              v-model="formData.title" 
              class="form-control" 
              placeholder="请输入投稿标题"
              maxlength="50"
            />
          </div>
          
          <div class="form-group">
            <label for="section">板块</label>
            <select id="section" v-model="formData.section" class="form-control">
              <option value="" disabled>请选择板块</option>
              <option value="攻略指南">攻略指南</option>
              <option value="资源共享">资源共享</option>
            </select>
          </div>
          
          <div class="form-group">
            <label for="note">备注信息 (选填)</label>
            <input 
              type="text" 
              id="note" 
              v-model="formData.note" 
              class="form-control" 
              placeholder="可添加备注信息"
            />
          </div>
        </div>
        
        <!-- 图片上传区 -->
        <!-- <div class="form-section">
          <h3>图片上传</h3>
          <p class="section-desc">您可以上传图片并将图片标签插入到文章中</p>
          
          <div class="upload-area">
            <div class="file-input-container">
              <label for="imagePicker" class="upload-label">
                <span class="upload-icon">📷</span>
                <span>选择图片</span>
              </label>
              <input 
                type="file" 
                id="imagePicker" 
                ref="imagePicker"
                @change="uploadImage" 
                accept="image/*"
                class="file-input"
              />
            </div>
            
            <div v-if="imageUrl" class="preview-area">
              <div class="image-preview">
                <img :src="imageUrl" alt="预览图" ref="imagePreview" />
              </div>
              <div class="image-info">
                <p>图片HTML标签:</p>
                <div class="tag-container">
                  <code>{{ imageTag }}</code>
                </div>
                <button type="button" class="btn btn-secondary" @click="copyImageUrl">
                  复制标签
                </button>
              </div>
            </div>
          </div>
        </div> -->
        
        <!-- 附件上传区 -->
        <div class="form-section">
          <h3>附件上传</h3>
          <p class="section-desc">您可以上传最多10个文件，总大小不超过500MB。</p>
          
          <div class="upload-area">
            <div class="file-input-container">
              <label for="filePicker" class="upload-label">
                <span class="upload-icon">📎</span>
                <span>选择文件</span>
              </label>
              <input 
                type="file" 
                id="filePicker" 
                ref="filePicker"
                @change="validateFiles" 
                multiple
                class="file-input"
              />
            </div>
            
            <div v-if="selectedFiles.length > 0" class="file-list">
              <h4>已选择的文件:</h4>
              <ul>
                <li v-for="(file, index) in selectedFiles" :key="index">
                  <span class="file-name">{{ file.name }}</span>
                  <span class="file-size">({{ formatFileSize(file.size) }})</span>
                </li>
              </ul>
              <p class="total-size">总大小: {{ formatFileSize(totalFileSize) }}</p>
            </div>
          </div>
        </div>
        
        <!-- 编辑器 -->
        <div class="form-section">
          <h3>内容编辑</h3>
          <p class="section-desc">此部分主要用于"攻略指南"板块，"资源共享"板块可以留空。</p>
          <p class="section-desc">使用Markdown语法编辑您的投稿内容。插入图片后，如需修改图片大小，请在编辑器中找到插入的图片标签，修改其width属性。</p>
          <p class="section-desc">如上传了附件且需在文中指定位置展示，<strong>可以用[附件名]来表示附件位置</strong>。如不指定，则审核人员将按照文章内容在适当位置展示。</p>
          <p class="section-desc"><strong>"保存草稿"功能和"在文章页中预览"功能只针对此部分内容，上传的附件等将不会保存草稿并不支持"在文章页中预览"功能。</strong></p>
          <p class="section-desc" style="color: purple;">您可以轻松地插入课程卡片（点击<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" width="20" height="24" stroke-width="1.1" style="vertical-align: middle; display: inline-block; margin-bottom: 2px;"><path d="M22 9l-10 -4l-10 4l10 4l10 -4v6"></path><path d="M6 10.6v5.4a6 3 0 0 0 12 0v-5.4"></path></svg>按钮），引用课程评分系统中的课程数据。<strong>注意：由于网站的安全设置，课程卡片前必须有其他内容，请勿在内容第一行插入课程卡片，否则将无法正常显示！</strong></p>
          <p v-if="isEditMode" class="section-desc" style="color: red;"><strong>检测到您当前正在编辑已有的投稿内容，请注意您之前如有其他投稿的草稿内容，这些内容在此页面保存草稿或提交编辑后将不会保留。</strong></p>
          
          <div class="editor-container">
            <MdEditor
              v-model="formData.content"
              ref="markdownEditor"
              :theme="editorTheme"
              :toolbars="editorToolbars"
              language="zh-CN"
              preview-theme="github"
              :placeholder="editorPlaceholder"
              @onUploadImg="handleImageUpload"
              @onSave="saveDraftWithConfirm"
            >
              <template #defToolbars>
                 <span class="md-editor-toolbar-item" title="添加课程卡片" @click="chooseCourse">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" width="20" height="24" stroke-width="1.1">
                      <path d="M22 9l-10 -4l-10 4l10 4l10 -4v6"></path>
                      <path d="M6 10.6v5.4a6 3 0 0 0 12 0v-5.4"></path>
                    </svg>
                 </span>
              </template>
            </MdEditor>
          </div>
          
          <div class="draft-actions">
            <button 
              type="button" 
              class="btn btn-secondary" 
              @click="loadDraft"
            >
              加载草稿
            </button>
            <button 
              type="button" 
              class="btn btn-secondary" 
              @click="saveDraftWithConfirm"
            >
              保存草稿
            </button>
            <button 
              type="button" 
              class="btn btn-secondary preview-btn" 
              @click="previewDraft"
            >
              在文章页中预览
            </button>
          </div>
        </div>
        
        <!-- 提交按钮 -->
        <div class="form-actions">
          <button type="button" class="btn btn-primary" @click="submitForm">
            {{ isEditMode ? '提交编辑' : '提交投稿' }}
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Navbar from '@/components/NavBar.vue';
import MdEditor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import Cookies from 'js-cookie';
import messageBox from '@/utils/messageBox.js';
import Loading from '@/components/Loading.vue';

export default {
  name: 'SubmitPage',
  components: {
    Navbar,
    MdEditor,
    Loading
  },
  data() {
    return {
      formData: {
        title: '',
        section: '',
        note: '',
        content: ''
      },
      selectedFiles: [],
      totalFileSize: 0,
      imageUrl: '',
      imageTag: '',
      editorTheme: 'light',
      editorPlaceholder: '在此输入您的内容，支持直接把图片粘贴到编辑器中',
      editorToolbars: [
        'bold', 'italic', 'underline', 'sub', 'sup', '-', 'title', 'unorderedList', 
        'orderedList', '-', 'quote', 'link', 'image', 'table', 'codeRow', 'code', 'mermaid', 0,
        '=', 'save', 'revoke', 'next', '-', 'preview', 'pageFullscreen', 'fullscreen'
      ],
      isEditMode: false,
      editArticleId: null,
      isLoading: false,
      loadingText: '获取投稿内容中...',
      // 课程选择器相关状态
      showCourseSelector: false,
      courseSearch: '',
      searchLoading: false,
      searchError: null,
      courseResults: [],
      selectedCourse: null,
      currentPage: 1,
      totalPages: 1,
      // 类别映射
      categoryMap: {
        1: '通识选修类',
        2: '人文选修类',
        3: '专业方向类',
        4: '体育类',
        5: '学科基础类',
        6: '暑期国际课',
        7: '数学与自然科学类',
        8: '重修专栏',
        9: '数学与自然科学类（必修）',
        10: '人文社会科学类（必修）',
        11: '学科基础类（必修）',
        12: '专业方向类（必修）',
        13: '实践类（必修）'
      }
    };
  },
  created() {
    document.title = '内容投稿 - NEU小站';
    // 检查登录状态，未登录则跳转到登录页面
    this.checkLoginStatus().then(() => {
      // 检查是否是编辑模式
      this.checkEditMode();
    });
  },
  methods: {
    // 检查登录状态
    async checkLoginStatus() {
      const token = Cookies.get('token');
      if (!token) {
        this.$router.push('/login');
        return Promise.reject(new Error('未登录'));
      }

      try {
        const response = await fetch('https://newfront.xn--xhq44jb2fzpc.com/user/islogin', {
          method: 'GET',
          headers: {
            'Authorization': token
          }
        });

        if (!response.ok) {
          throw new Error('验证失败');
        }

        const data = await response.json();
        if (!data.isLoggedIn) {
          // 删除无效的 token
          Cookies.remove('token');
          this.$router.push('/login');
          return Promise.reject(new Error('登录已过期'));
        }
        
        return Promise.resolve();
      } catch (error) {
        console.error('登录验证失败:', error);
        // 删除可能无效的 token
        Cookies.remove('token');
        this.$router.push('/login');
        return Promise.reject(error);
      }
    },
    
    // 检查是否是编辑模式
    async checkEditMode() {
      // 获取查询参数中的文章ID
      const urlParams = new URLSearchParams(window.location.search);
      const articleId = urlParams.get('article');
      
      if (!articleId) return;
      
      try {
        // 更新界面状态
        this.isEditMode = true;
        this.editArticleId = articleId;
        
        // 显示加载中组件
        this.isLoading = true;
        
        // 获取文章详情
        const token = Cookies.get('token');
        const response = await fetch(`https://newfront.xn--xhq44jb2fzpc.com/article?id=${articleId}&edit=true`, {
          method: 'GET',
          headers: {
            'Authorization': token
          }
        });
        
        if (!response.ok) {
          throw new Error('获取文章失败');
        }
        
        const articleData = await response.json();
        
        // 填充表单
        this.formData.title = `【edit${articleId}】${articleData.title}`;
        this.formData.section = articleData.section;
        this.formData.content = articleData.content;
        
        // 更新标题
        document.title = `编辑投稿内容 - NEU小站`;
        
      } catch (error) {
        console.error('获取文章信息失败:', error);
        
        // 获取失败则回退到普通投稿模式
        this.isEditMode = false;
        this.editArticleId = null;
        
        // 可以显示友好提示
        // messageBox.alert("非法操作！", "提示");
      } finally {
        // 隐藏加载中组件
        this.isLoading = false;
      }
    },

    // 图片上传处理
    async handleImageUpload(files, callback) {
      // 这个方法处理编辑器内部的图片上传
      // files 是上传的文件数组，callback 是处理上传完成后返回URL的回调函数
      const token = Cookies.get('token');

      if (!token) {
        messageBox.alert('请先登录！', '提示');
        return;
      }
      
      try {
        const uploadPromises = files.map(async file => {
          // 检查文件大小（2MB）
          if (file.size > 2 * 1024 * 1024) {
            throw new Error(`图片 ${file.name} 大小不能超过2MB！`);
          }

          const postfix = file.name.split('.').pop().toLowerCase();
          const type = file.type;

          // 请求上传URL
          const prepareResponse = await fetch('https://userlogin.xn--xhq44jb2fzpc.com/submission/prepare-image-upload', {
            method: 'POST',
            headers: {
              'Authorization': token,
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({ postfix, type })
          });

          if (!prepareResponse.ok) {
            throw new Error('准备上传失败');
          }

          const { uploadUrl, path } = await prepareResponse.json();

          // 上传文件
          const uploadResponse = await fetch(uploadUrl, {
            method: 'PUT',
            body: file,
            headers: {
              'Content-Type': type,
              'Authorization': token
            }
          });

          if (!uploadResponse.ok) {
            throw new Error(`文件 ${file.name} 上传失败`);
          }

          // 返回图片URL - 现在返回HTML img标签格式
          const imageUrl = `https://download.xn--xhq44jb2fzpc.com/${path}`;
          
          // 返回HTML img标签
          return imageUrl;
        });

        // 等待所有上传完成
        const htmlTags = await Promise.all(uploadPromises);
        
        // 在回调中返回HTML标签数组，编辑器会直接插入这些标签
        callback(htmlTags);
        
        // 提示用户如何调整图片大小
        if (htmlTags.length > 0) {
          setTimeout(() => {
            messageBox.alert(
              '您已成功上传图片。如需修改图片大小，请在编辑器中找到刚插入的图片标签，修改其width属性。',
              '图片大小调整提示'
            );
          }, 800);
        }
      } catch (error) {
        console.error('图片上传失败:', error);
        messageBox.alert('图片上传失败：' + error.message, '错误');
      }
    },
    
    // 验证上传的文件
    validateFiles(event) {
      const maxFiles = 10;
      const maxTotalFileSize = 500 * 1024 * 1024; // 500MB in bytes
      const files = event.target.files;
      
      if (files.length > maxFiles) {
        messageBox.alert(`您只能选择最多 ${maxFiles} 个文件。`, '提示');
        event.target.value = ''; // 清除已选文件
        this.selectedFiles = []; // 清空状态
        this.totalFileSize = 0;
        return;
      }

      let totalSize = 0;
      const validFiles = [];

      // 检查文件限制
      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        const fileSize = file.size;

        // 更新总文件大小
        totalSize += fileSize;

        // 检查文件总大小是否超过限制
        if (totalSize > maxTotalFileSize) {
          messageBox.alert(`所有文件的总大小不能超过 500MB。`, '提示');
          event.target.value = ''; // 清除已选文件
          this.selectedFiles = []; // 清空状态
          this.totalFileSize = 0;
          return;
        }
        
        validFiles.push(file);
      }
      
      // 验证通过，更新状态
      this.selectedFiles = validFiles;
      this.totalFileSize = totalSize;
    },
    
    // 格式化文件大小显示
    formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes';
      
      const k = 1024;
      const sizes = ['Bytes', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    
    // 上传图片
    async uploadImage(event) {
      const file = event.target.files[0];

      // 基础检查
      if (!file) {
        messageBox.alert("请先选择图片文件！", '提示');
        return;
      }

      // 检查文件大小（2MB）
      if (file.size > 2 * 1024 * 1024) {
        messageBox.alert("图片文件大小不能超过2MB！", '提示');
        event.target.value = '';
        return;
      }

      // 检查文件类型
      if (!file.type.startsWith('image/')) {
        messageBox.alert("请选择图片文件！", '提示');
        event.target.value = '';
        return;
      }

      try {
        const token = Cookies.get('token');

        if (!token) {
          messageBox.alert('请先登录！', '提示');
          return;
        }

        const postfix = file.name.split('.').pop().toLowerCase();
        // 使用文件的MIME类型
        const type = file.type;

        // 请求上传URL，传递MIME类型
        const prepareResponse = await fetch('https://userlogin.xn--xhq44jb2fzpc.com/submission/prepare-image-upload', {
          method: 'POST',
          headers: {
            'Authorization': token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ postfix, type })
        });

        if (!prepareResponse.ok) {
          throw new Error('准备上传失败');
        }

        const { uploadUrl, path } = await prepareResponse.json();

        // 使用签名URL上传文件，使用相同的MIME类型
        const uploadResponse = await fetch(uploadUrl, {
          method: 'PUT',
          body: file,
          headers: {
            'Content-Type': type,
            'Authorization': token
          }
        });

        if (!uploadResponse.ok) {
          // 尝试解析错误响应
          const text = await uploadResponse.text();
          if (text.includes('<?xml')) {
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(text, "text/xml");
            const requestId = xmlDoc.getElementsByTagName("RequestId")[0]?.textContent;
            throw new Error(`文件上传失败 (RequestId: ${requestId || '未知'})`);
          }
          throw new Error('文件上传失败');
        }

        // 构造完整URL
        const imageUrl = `https://download.xn--xhq44jb2fzpc.com/${path}`;
        const imageTag = `<img src="${imageUrl}" alt="自定义图片文字" width="150">`;

        // 更新界面显示
        this.imageUrl = imageUrl;
        this.imageTag = imageTag;

      } catch (error) {
        console.error('上传失败:', error);
        messageBox.alert('图片上传失败：' + error.message, '错误');
        event.target.value = '';
      }
    },
    
    // 复制图片HTML标签到剪贴板
    copyImageUrl() {
      // 创建一个临时文本区域元素
      const textArea = document.createElement("textarea");
      textArea.value = this.imageTag;
      document.body.appendChild(textArea);
      textArea.select();

      try {
        const successful = document.execCommand('copy');
        const msg = successful ? '标签已复制到剪贴板！请直接粘贴到编辑区中，并根据预览效果调整大小。' : '复制失败！';
        messageBox.alert(msg, '提示');
      } catch (err) {
        messageBox.alert(`复制失败！${err}`, '错误');
      }

      document.body.removeChild(textArea);
    },
    
    // 预览草稿
    async previewDraft() {
      const { content } = this.formData;
      
      if (!content.trim()) {
        messageBox.alert("内容不能为空！", '提示');
        return;
      }
      
      try {
        // 添加确认提示框
        const confirmResult = await messageBox.confirm("此操作会自动保存草稿。确认继续吗？如您之前有草稿记录，此操作会覆盖之前的草稿内容。", '确认');
        
        // 如果用户取消了操作，直接返回
        if (!confirmResult) return;
        
        // 保存草稿后跳转到预览页面
        this.saveDraft(true).then(() => {
          window.open('/preview', '_blank');
        }).catch(error => {
          console.error("无法预览草稿:", error);
        });
      } catch (error) {
        console.error("预览草稿操作被取消:", error);
      }
    },
    
    // 包装保存草稿方法，确保调用确认对话框
    async saveDraftWithConfirm() {
      const { content } = this.formData;
      
      if (!content.trim()) {
        messageBox.alert("内容不能为空！", '提示');
        return;
      }
      
      try {
        // 显示确认对话框
        const confirmResult = await messageBox.confirm("确认保存草稿内容吗？如您之前有草稿记录，此操作会覆盖之前的草稿内容。", '确认');
        
        // 确认后保存草稿
        if (confirmResult) {
          this.saveDraft(true);
        }
      } catch (error) {
        console.error("保存草稿操作被取消:", error);
      }
    },
    
    // 保存草稿
    async saveDraft(silent = false) {
      const token = Cookies.get('token');
      
      if (!token) {
        messageBox.alert("非法操作！请先登录。", '警告');
        return Promise.reject(new Error("未登录"));
      }
      
      const draftContent = this.formData.content;
      
      if (!draftContent.trim()) {
        messageBox.alert("内容不能为空！", '提示');
        return;
      }
      
      try {
        let confirmResult = true;
        
        if (!silent) {
          confirmResult = await messageBox.confirm("确认保存草稿内容吗？如您之前有草稿记录，此操作会覆盖之前的草稿内容。", '确认');
        }
        
        // 如果用户取消了操作，直接返回
        if (!confirmResult) return;
        
        const response = await fetch('https://userlogin.xn--xhq44jb2fzpc.com/submission/save-draft', {
          method: 'POST',
          headers: {
            'Authorization': token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ content: draftContent }) // 将草稿内容发送到后端
        });

        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData.message || "保存草稿失败");
        }

        if (!silent) {
          messageBox.alert("草稿已保存！", '成功');
        }
        
        return Promise.resolve();
      } catch (error) {
        console.error("保存草稿时出错:", error);
        if (!silent) {
          messageBox.alert("保存草稿失败，请稍后再试。", '错误');
        }
        return Promise.reject(error);
      }
    },
    
    // 加载草稿
    async loadDraft() {
      const token = Cookies.get('token');
      
      if (!token) {
        messageBox.alert("非法操作！请先登录。", '警告');
        return;
      }
      
      try {
        const response = await fetch('https://userlogin.xn--xhq44jb2fzpc.com/submission/load-draft', {
          method: 'GET',
          headers: {
            'Authorization': token
          }
        });

        if (!response.ok) {
          if (response.status === 404) {
            messageBox.alert("没有草稿记录！", '提示');
          } else {
            const errorData = await response.json();
            throw new Error(errorData.message || "无法加载草稿内容");
          }
          return;
        }
        
        const draftData = await response.json();
        
        try {
          const confirmResult = await messageBox.confirm("此操作会覆盖您当前的输入内容，确认加载草稿吗？", '确认');
          
          // 如果用户取消了操作，直接返回
          if (!confirmResult) return;
          
          // 设置编辑器中的内容
          this.formData.content = draftData.content;
          messageBox.alert("草稿已加载！", '成功');
        } catch (error) {
          // 用户取消了加载操作，不执行任何操作
          console.log("用户取消了加载草稿操作");
        }
      } catch (error) {
        console.error("加载草稿时出错:", error);
        messageBox.alert("加载草稿失败，请稍后再试。", '错误');
      }
    },
    
    // 提交表单
    async submitForm() {
      const { title, section, note, content } = this.formData;
      const token = Cookies.get('token');
      const files = this.selectedFiles;
      
      if (!title || !section) {
        messageBox.alert("请填写内容的标题和板块。", '提示');
        return;
      }
      
      try {
        let confirmMessage = '请仔细检查后提交，多次提交无关内容将被禁止访问网站！';
        if (this.isEditMode) {
          confirmMessage = '确认提交修改？修改后的内容将重新进入审核流程。';
        }
        
        const confirmResult = await messageBox.confirm(confirmMessage, '提交确认');
        
        // 如果用户取消了操作，直接返回
        if (!confirmResult) return;
        
        // 准备文件信息
        const fileData = [];
        for (let i = 0; i < files.length; i++) {
          const file = files[i];
          const postfix = file.name.split('.').pop().toLowerCase();
          fileData.push({
            filename: file.name,
            postfix: postfix,
            type: file.type || 'application/octet-stream',
            size: (file.size / (1024 * 1024)).toFixed(2)
          });
        }

        // 提交表单和获取上传URL
        let apiUrl = 'https://userlogin.xn--xhq44jb2fzpc.com/submission/submit';
        
        // 提交参数
        const submitData = {
          title,
          section,
          detail: content || null,
          submission_note: note || null,
          has_file: files.length > 0 ? 1 : 0,
          files: fileData
        };
        
        // 如果是编辑模式，添加文章ID
        if (this.isEditMode && this.editArticleId) {
          submitData.article_id = this.editArticleId;
        }
        
        const response = await fetch(apiUrl, {
          method: 'POST',
          headers: {
            'Authorization': token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(submitData)
        });

        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData.message || '投稿失败，请重试！');
        }

        const result = await response.json();
        const submissionId = result.submissionId; // 获取投稿ID

        // 如果有文件需要上传
        if (result.fileUploadData && result.fileUploadData.length > 0) {
          this.loadingText = "文件正在上传中，请耐心等待...";
          this.isLoading = true;
          
          try {
            for (let i = 0; i < files.length; i++) {
              const file = files[i];
              const uploadInfo = result.fileUploadData[i];

              const uploadResponse = await fetch(uploadInfo.uploadUrl, {
                method: 'PUT',
                body: file,
                headers: {
                  'Content-Type': file.type || 'application/octet-stream',
                  'Authorization': token
                }
              });

              if (!uploadResponse.ok) {
                // 隐藏加载中状态 - 由外部 catch 处理
                throw new Error(`文件 ${file.name} 上传失败`);
              }
            }
            // 文件上传成功
            this.isLoading = false; // 隐藏文件上传loading
          } catch (uploadError) {
            // 文件上传失败，错误已向上抛出，外部catch会处理isLoading
            throw uploadError; 
          }
        }

        // *** 确认投稿 ***
        // 无论是否有文件上传，都需要确认
        try {
          this.loadingText = "确认状态中...";
          this.isLoading = true; // 显示确认loading

          const confirmResponse = await fetch('https://userlogin.xn--xhq44jb2fzpc.com/submission/confirm-submit', {
              method: 'POST',
              headers: {
                  'Authorization': token,
                  'Content-Type': 'application/json'
              },
              body: JSON.stringify({ submission_id: submissionId }) // 使用获取到的 submissionId
          });

          if (!confirmResponse.ok) {
              // 确认失败，记录错误，但可能仍需提示用户主体成功
              const confirmErrorData = await confirmResponse.json();
              console.error('确认投稿失败:', confirmErrorData.message || '未知错误');
              // 提示用户，投稿基本成功，但确认步骤失败
              messageBox.alert('投稿失败，请重试。如多次尝试仍失败，请联系管理员。', '警告');
          }
          // else: Confirmation successful

        } catch (confirmError) {
          console.error('确认状态时出错:', confirmError);
          messageBox.alert('确认状态时出错，请稍后重试或联系管理员。', '错误');
          // 即使确认接口调用失败，也可能需要继续，因为主要提交和文件上传（如果适用）已完成
        } finally {
          this.isLoading = false; // 隐藏确认loading
        }

        // *** 最终成功处理 ***
        let successMessage = `投稿成功！您将会在审核状态变化后收到邮件通知，敬请留意~`;
        if (this.isEditMode) {
          successMessage = `修改提交成功！您将会在审核状态变化后收到邮件通知，敬请留意~`;
        }
        await messageBox.alert(successMessage, '成功');
        this.$router.push('/user-center'); // 提交成功后跳转到用户中心

      } catch (error) {
        // 确保隐藏加载中状态
        this.isLoading = false;
        
        console.error("投稿失败:", error);
        // 判断是否为用户取消操作
        if (error && error.action === 'cancel') {
          // 用户主动取消操作，不显示错误提示
          return;
        }
        messageBox.alert(`投稿失败：${error.message || '未知错误'}`, '错误');
      }
    },
    chooseCourse() {
      this.showCourseSelector = true;
      this.courseSearch = '';
      this.courseResults = [];
      this.selectedCourse = null;
      this.currentPage = 1;
      this.totalPages = 1;
      this.searchError = null;
    },
    
    closeCourseSelector() {
      this.showCourseSelector = false;
    },
    
    async searchCourses(page = 1) {
      // 如果参数是事件对象，设为默认页码1
      if (page && typeof page === 'object' && page.type) {
        page = 1;
      }
      
      if (!this.courseSearch.trim()) {
        messageBox.alert('请输入课程名称', '提示');
        return;
      }
      
      this.searchLoading = true;
      this.searchError = null;
      this.selectedCourse = null;
      this.currentPage = page;
      
      try {
        // 构建API URL
        const encodedSearch = encodeURIComponent(this.courseSearch.trim());
        const url = `https://coursesystem.xn--xhq44jb2fzpc.com/list/courses?search=${encodedSearch}&page=${page}`;
        
        // 发送请求
        const response = await fetch(url);
        
        if (!response.ok) {
          throw new Error('搜索课程失败');
        }
        
        const data = await response.json();
        
        // 更新数据
        this.courseResults = data.courses || [];
        this.currentPage = data.currentPage || 1;
        this.totalPages = data.totalPages || 1;
        
      } catch (error) {
        console.error('课程搜索出错:', error);
        this.searchError = '搜索课程时发生错误，请稍后重试';
      } finally {
        this.searchLoading = false;
      }
    },
    
    getCategoryName(categoryId) {
      return this.categoryMap[categoryId] || '未知类别';
    },
    
    selectCourse(course) {
      this.selectedCourse = course;
    },
    
    changePage(page) {
      if (page < 1 || page > this.totalPages) return;
      this.searchCourses(page);
    },
    
    confirmCourseSelection() {
      if (!this.selectedCourse) {
        messageBox.alert('请先选择一个课程', '提示');
        return;
      }
      
      // 获取编辑器实例
      const editor = this.$refs.markdownEditor;
      
      // 构建要插入的内容
      const courseCardCode = `<CourseCard id="${this.selectedCourse.course_id}" />\n`;
      
      // 在光标位置插入内容
      editor.insert((selectedText) => {
        return {
          targetValue: courseCardCode,
          select: false,
          deviationStart: 0,
          deviationEnd: 0
        };
      });
      
      // 关闭模态窗口
      this.closeCourseSelector();
    }
  },
  computed: {
    displayedPages() {
      // 最多显示5个页码
      const maxButtons = 5;
      const halfButtons = Math.floor(maxButtons / 2);
      
      let startPage = Math.max(1, this.currentPage - halfButtons);
      let endPage = Math.min(this.totalPages, startPage + maxButtons - 1);
      
      // 调整开始页码，确保显示正确数量的按钮
      if (endPage - startPage + 1 < maxButtons) {
        startPage = Math.max(1, endPage - maxButtons + 1);
      }
      
      const pages = [];
      for (let i = startPage; i <= endPage; i++) {
        pages.push(i);
      }
      
      return pages;
    }
  }
};
</script>

<style scoped>
.submit-page {
  background-color: #f5f7fa;
  min-height: 100vh;
  padding-top: 60px; /* 为导航栏预留空间 */
}

.container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 30px 20px;
}

.page-header {
  margin-bottom: 30px;
  text-align: center;
}

.page-header h1 {
  font-size: 28px;
  color: #333;
  margin-bottom: 10px;
}

.sub-title {
  color: #666;
  font-size: 16px;
}

.submission-form {
  background: white;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.form-section {
  padding: 30px;
  border-bottom: 1px solid #eee;
}

.form-section:last-child {
  border-bottom: none;
}

.form-section h3 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 18px;
  color: #333;
}

.section-desc {
  color: #666;
  font-size: 14px;
  margin-bottom: 20px;
}

.form-group {
  margin-bottom: 20px;
}

.form-group:last-child {
  margin-bottom: 0;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  font-weight: 600;
  color: #333;
}

.form-control {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
  transition: border-color 0.3s;
}

.form-control:focus {
  border-color: #3273dc;
  outline: none;
}

select.form-control {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath fill='%23333' d='M0 0h8L4 5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1em center;
  background-size: 8px 5px;
  padding-right: 30px;
  appearance: none;
}

.upload-area {
  background-color: #f9f9f9;
  border: 2px dashed #ddd;
  border-radius: 6px;
  padding: 20px;
  text-align: center;
  transition: all 0.3s;
}

.upload-area:hover {
  border-color: #3273dc;
}

.file-input-container {
  display: inline-block;
}

.upload-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 10px 20px;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  transition: all 0.3s;
}

.upload-label:hover {
  background-color: #f0f0f0;
}

.upload-icon {
  font-size: 20px;
}

.file-input {
  display: none;
}

.preview-area {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.image-preview {
  max-width: 300px;
  max-height: 200px;
  overflow: hidden;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.image-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.image-info {
  width: 100%;
  max-width: 500px;
}

.tag-container {
  background-color: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 10px;
  margin-bottom: 10px;
  font-family: monospace;
  word-break: break-all;
  font-size: 13px;
  color: #333;
}

.file-list {
  margin-top: 20px;
  text-align: left;
}

.file-list h4 {
  margin-top: 0;
  font-size: 16px;
}

.file-list ul {
  padding-left: 20px;
  margin-bottom: 10px;
}

.file-list li {
  margin-bottom: 5px;
}

.file-name {
  font-weight: 500;
}

.file-size {
  color: #666;
  margin-left: 5px;
}

.total-size {
  font-weight: 500;
  color: #333;
}

.editor-container {
  margin-bottom: 20px;
}

/* 确保编辑器高度适中 */
.editor-container :deep(.md-editor) {
  height: 400px;
}

.draft-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

.form-actions {
  padding: 30px;
  text-align: center;
}

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s;
}

.btn-primary {
  background-color: #3273dc;
  color: white;
}

.btn-primary:hover {
  background-color: #2366d1;
}

.btn-secondary {
  background-color: #f0f0f0;
  color: #333;
}

.btn-secondary:hover {
  background-color: #e0e0e0;
}

.preview-btn {
  background-color: #4a9eff;
  color: white;
}

.preview-btn:hover {
  background-color: #3789e9;
}

@media (max-width: 768px) {
  .container {
    padding: 20px 15px;
  }
  
  .form-section {
    padding: 20px;
  }
  
  .preview-area {
    flex-direction: column;
  }
  
  .image-info {
    width: 100%;
  }
}

/* 课程选择器样式 */
.course-selector-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10001;
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-container {
  width: 90%;
  max-width: 900px;
  max-height: 90vh;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  z-index: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-header {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #eee;
}

.modal-header h3 {
  margin: 0;
  font-size: 18px;
}

.close-btn {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #666;
}

.modal-body {
  padding: 16px;
  overflow-y: auto;
  flex-grow: 1;
}

.search-bar {
  display: flex;
  margin-bottom: 16px;
}

.search-input {
  flex-grow: 1;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 14px;
  margin-right: 8px;
}

.search-btn {
  background-color: #3273dc;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  cursor: pointer;
}

.course-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 30px;
}

.spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  border-top-color: #3273dc;
  animation: spin 1s linear infinite;
  margin-bottom: 10px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.search-error, .no-results {
  text-align: center;
  padding: 20px;
  color: #e74c3c;
}

.no-results {
  color: #666;
}

.course-table {
  width: 100%;
  border-collapse: collapse;
}

.course-table th, .course-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #eee;
}

.course-table th {
  background-color: #f8f9fa;
  font-weight: 600;
}

.course-table tr {
  cursor: pointer;
  transition: background-color 0.2s;
}

.course-table tr:hover {
  background-color: #f5f7fa;
}

.course-table tr.selected {
  background-color: #e8f0ff;
}

.rating {
  font-weight: 600;
  color: #ff9800;
}

.rating-count {
  color: #888;
  font-size: 0.9em;
  margin-left: 4px;
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  gap: 5px;
  align-items: center;
}

.page-btn {
  min-width: 36px;
  height: 36px;
  padding: 0 8px;
  border: 1px solid #ddd;
  background-color: white;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.page-btn:hover:not(:disabled) {
  background-color: #f5f7fa;
  border-color: #ccc;
}

.page-btn.active {
  background-color: #3273dc;
  color: white;
  border-color: #3273dc;
}

.page-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.modal-footer {
  padding: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  border-top: 1px solid #eee;
}

.page-info {
  margin: 0 10px;
  font-size: 14px;
  color: #666;
}
</style>
