<!--
  页面名称：FunctionalReport.vue
  页面描述：报告中心-功能测试模块页面，支持上传Excel、生成报告、下载预览、上传ERP

  @author czj
  @date 2026-08-12
-->

<template>
  <div class="functional-report-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <h2>功能测试报告</h2>
      <el-button @click="resetAll">
        <el-icon><Refresh /></el-icon>
        重置
      </el-button>
    </div>

    <!-- 步骤1：上传Excel -->
    <el-card class="step-card" shadow="never">
      <template #header>
        <div class="card-header">
          <span class="step-title">① 上传测试数据</span>
          <span class="step-tip">上传测试用例 Excel 和 BUG 列表 Excel</span>
        </div>
      </template>

      <div class="upload-grid">
        <el-upload
          drag
          :auto-upload="false"
          :limit="1"
          :on-change="(file: any) => (testcaseFile = file.raw)"
          :on-remove="() => (testcaseFile = null)"
          accept=".xlsx,.xls"
          class="upload-item"
        >
          <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
          <div class="el-upload__text">拖拽测试用例 Excel 到此处，或<em>点击上传</em></div>
          <template #tip>
            <div class="el-upload__tip">测试用例表：表头第 3 行，数据从第 4 行开始（17 列）</div>
          </template>
        </el-upload>

        <el-upload
          drag
          :auto-upload="false"
          :limit="1"
          :on-change="(file: any) => (buglistFile = file.raw)"
          :on-remove="() => (buglistFile = null)"
          accept=".xlsx,.xls"
          class="upload-item"
        >
          <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
          <div class="el-upload__text">拖拽 BUG 列表 Excel 到此处，或<em>点击上传</em></div>
          <template #tip>
            <div class="el-upload__tip">BUG 列表：表头第 1 行，数据从第 2 行开始（9 列）</div>
          </template>
        </el-upload>
      </div>

      <div class="upload-actions">
        <el-button
          type="primary"
          :loading="uploading"
          :disabled="!testcaseFile || !buglistFile"
          @click="handleUpload"
        >
          <el-icon><Upload /></el-icon>
          上传文件
        </el-button>
        <el-tag v-if="sessionId" type="success" size="small">会话: {{ sessionId }}</el-tag>
      </div>
    </el-card>

    <!-- 步骤2：生成报告 -->
    <el-card class="step-card" shadow="never">
      <template #header>
        <div class="card-header">
          <span class="step-title">② 生成报告</span>
          <span class="step-tip">配置项目信息并生成功能测试报告</span>
        </div>
      </template>

      <el-form :inline="true" label-width="90px">
        <el-form-item label="项目名称">
          <el-input
            v-model="projectName"
            placeholder="请输入项目名称"
            style="width: 260px"
          />
        </el-form-item>
        <el-form-item label="报告格式">
          <el-radio-group v-model="reportFormat">
            <el-radio value="docx">Word</el-radio>
            <el-radio value="md">Markdown</el-radio>
            <el-radio value="both">两者</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            :loading="generating"
            :disabled="!sessionId"
            @click="handleGenerate"
          >
            <el-icon><Document /></el-icon>
            生成报告
          </el-button>
        </el-form-item>
      </el-form>

      <!-- 生成结果 -->
      <template v-if="generateResult">
        <el-divider />
        <div class="result-summary">
          <h4>分析结果</h4>
          <div class="summary-grid">
            <div class="summary-item">
              <span class="label">项目名称</span>
              <span class="value">{{ generateResult.project_name }}</span>
            </div>
            <div class="summary-item">
              <span class="label">用例总数</span>
              <span class="value">{{ generateResult.case_analysis.total_cases }}</span>
            </div>
            <div class="summary-item">
              <span class="label">通过率</span>
              <span class="value success">{{ generateResult.case_analysis.pass_rate }}%</span>
            </div>
            <div class="summary-item">
              <span class="label">执行率</span>
              <span class="value">{{ generateResult.case_analysis.execution_rate }}%</span>
            </div>
            <div class="summary-item">
              <span class="label">BUG总数</span>
              <span class="value">{{ generateResult.bug_analysis.total_bugs }}</span>
            </div>
            <div class="summary-item">
              <span class="label">遗留BUG</span>
              <span class="value danger">{{ generateResult.bug_analysis.remaining_bugs }}</span>
            </div>
            <div class="summary-item">
              <span class="label">用例-BUG关联</span>
              <span class="value">{{ generateResult.case_bug_link_count }}</span>
            </div>
          </div>
        </div>

        <!-- 图表预览 -->
        <div v-if="generateResult.charts && Object.keys(generateResult.charts).length" class="charts-block">
          <h4>统计图表</h4>
          <div class="charts-grid">
            <div v-for="(path, key) in generateResult.charts" :key="key" class="chart-item">
              <span class="chart-label">{{ chartLabels[key] || key }}</span>
              <el-image
                :src="getChartUrl(path)"
                :preview-src-list="[getChartUrl(path)]"
                fit="contain"
                class="chart-img"
              />
            </div>
          </div>
        </div>

        <!-- 报告下载 -->
        <div class="reports-block">
          <h4>生成的报告</h4>
          <div class="report-list">
            <div v-for="report in generateResult.reports" :key="report" class="report-item">
              <span class="report-name">{{ getReportFileName(report) }}</span>
              <div class="report-actions">
                <el-button size="small" type="primary" link @click="downloadReport(report)">
                  <el-icon><Download /></el-icon>
                  下载
                </el-button>
                <el-button
                  v-if="getReportFileName(report).endsWith('.md')"
                  size="small"
                  type="primary"
                  link
                  @click="previewReport(report)"
                >
                  <el-icon><View /></el-icon>
                  预览
                </el-button>
                <el-button
                  v-if="getReportFileName(report).endsWith('.docx')"
                  size="small"
                  type="warning"
                  link
                  :loading="erpUploading"
                  @click="openErpDialog(report)"
                >
                  <el-icon><Upload /></el-icon>
                  上传ERP
                </el-button>
                <el-button
                  v-if="getReportFileName(report).endsWith('.docx')"
                  size="small"
                  type="success"
                  link
                  @click="openProjectUploadDialog(report)"
                >
                  <el-icon><Folder /></el-icon>
                  项目资料
                </el-button>
                <el-button
                  v-if="getReportFileName(report).endsWith('.docx')"
                  size="small"
                  type="primary"
                  link
                  @click="openCooperationUploadDialog(report)"
                >
                  <el-icon><Share /></el-icon>
                  协作文档
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </template>
    </el-card>

    <!-- 底部操作栏（生成报告后固定显示） -->
    <div v-if="generateResult" class="sticky-action-bar">
      <div class="action-bar-inner">
        <div class="action-bar-info">
          <el-tag type="success" effect="dark" size="small">已生成报告</el-tag>
          <span class="action-bar-summary">
            用例: {{ generateResult.case_analysis.total_cases }} |
            通过率: {{ generateResult.case_analysis.pass_rate }}% |
            BUG: {{ generateResult.bug_analysis.total_bugs }}
          </span>
        </div>
        <div class="action-bar-buttons">
          <template v-for="report in generateResult.reports" :key="report">
            <el-button size="small" type="primary" @click="downloadReport(report)">
              <el-icon><Download /></el-icon>
              下载 {{ getReportFileName(report).endsWith('.docx') ? 'Word' : 'MD' }}
            </el-button>
            <el-button
              v-if="getReportFileName(report).endsWith('.docx')"
              size="small"
              type="warning"
              :loading="erpUploading"
              @click="openErpDialog(report)"
            >
              <el-icon><Upload /></el-icon>
              上传ERP
            </el-button>
            <el-button
              v-if="getReportFileName(report).endsWith('.docx')"
              size="small"
              type="success"
              @click="openProjectUploadDialog(report)"
            >
              <el-icon><Folder /></el-icon>
              项目资料
            </el-button>
            <el-button
              v-if="getReportFileName(report).endsWith('.docx')"
              size="small"
              @click="openCooperationUploadDialog(report)"
            >
              <el-icon><Share /></el-icon>
              协作文档
            </el-button>
          </template>
        </div>
      </div>
    </div>

    <!-- Markdown 报告预览弹窗 -->
    <el-dialog
      v-model="previewVisible"
      title="功能测试报告预览"
      width="90%"
      top="5vh"
      destroy-on-close
      fullscreen
    >
      <div class="preview-container" v-loading="previewLoading">
        <iframe v-if="previewUrl" :src="previewUrl" class="preview-iframe" />
        <el-empty v-else-if="!previewLoading" description="报告加载失败" />
      </div>
    </el-dialog>

    <!-- ERP 上传弹窗 -->
    <el-dialog v-model="erpDialogVisible" title="上传报告到 ERP" width="500px">
      <el-form label-width="100px">
        <el-form-item label="报告文件">
          <el-input :model-value="getReportFileName(currentErpReport || '')" disabled />
        </el-form-item>
        <el-form-item label="测试单ID">
          <el-input-number v-model="developtestingId" :min="1" style="width: 200px" />
          <span class="form-tip">留空使用系统默认</span>
        </el-form-item>
        <el-form-item label="抄送人">
          <el-select
            v-model="copyuserNames"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="输入抄送人姓名，回车添加"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="创建人">
          <el-input v-model="createuserName" placeholder="创建人姓名（可选）" style="width: 200px" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="erpDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="erpUploading" @click="handleErpUpload">
          确认上传
        </el-button>
      </template>
    </el-dialog>

    <!-- 项目资料上传弹窗 -->
    <el-dialog v-model="projectDialogVisible" title="上传到 ERP 项目资料" width="500px">
      <el-form label-width="100px">
        <el-form-item label="报告文件">
          <el-input :model-value="getReportFileName(currentProjectReport || '')" disabled />
        </el-form-item>
        <el-form-item label="项目ID" required>
          <el-input-number v-model="projectId" :min="1" style="width: 200px" />
        </el-form-item>
        <el-form-item label="文件名称">
          <el-input v-model="projectFileName" placeholder="默认取报告文件名" style="width: 260px" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="projectDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="projectUploading" @click="handleProjectUpload">
          确认上传
        </el-button>
      </template>
    </el-dialog>

    <!-- 协作文档上传弹窗 -->
    <el-dialog v-model="cooperationDialogVisible" title="上传到 ERP 协作文档" width="500px">
      <el-form label-width="100px">
        <el-form-item label="报告文件">
          <el-input :model-value="getReportFileName(currentCooperationReport || '')" disabled />
        </el-form-item>
        <el-form-item label="项目ID" required>
          <el-input-number v-model="cooperationProjectId" :min="1" style="width: 200px" />
        </el-form-item>
        <el-form-item label="文件名称">
          <el-input v-model="cooperationFileName" placeholder="默认取报告文件名" style="width: 260px" />
        </el-form-item>
        <el-form-item label="分组ID">
          <el-input-number v-model="cooperationGroupId" :min="1" style="width: 200px" />
          <span class="form-tip">可选</span>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="cooperationDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="cooperationUploading" @click="handleCooperationUpload">
          确认上传
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
/**
 * 功能测试报告页面
 *
 * 功能：
 * 1. 上传测试用例 Excel + BUG 列表 Excel
 * 2. 生成功能测试报告（Word / Markdown）
 * 3. 下载、预览报告
 * 4. 上传报告到 ERP
 */

import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import {
  Refresh,
  Upload,
  UploadFilled,
  Document,
  Download,
  View,
  Folder,
  Share
} from '@element-plus/icons-vue'
import { functionalReportApi } from '@/api/functionalReport'

// ==================== 响应式数据 ====================

const testcaseFile = ref<File | null>(null)
const buglistFile = ref<File | null>(null)
const sessionId = ref('')
const uploading = ref(false)

const projectName = ref('')
const reportFormat = ref('docx')
const generating = ref(false)
const generateResult = ref<any>(null)

const previewVisible = ref(false)
const previewLoading = ref(false)
const previewUrl = ref('')

const erpDialogVisible = ref(false)
const erpUploading = ref(false)
const currentErpReport = ref('')
const developtestingId = ref<number | undefined>(undefined)
const copyuserNames = ref<string[]>([])
const createuserName = ref('')

const projectDialogVisible = ref(false)
const projectUploading = ref(false)
const currentProjectReport = ref('')
const projectId = ref<number | undefined>(undefined)
const projectFileName = ref('')

const cooperationDialogVisible = ref(false)
const cooperationUploading = ref(false)
const currentCooperationReport = ref('')
const cooperationProjectId = ref<number | undefined>(undefined)
const cooperationFileName = ref('')
const cooperationGroupId = ref<number | undefined>(undefined)

/** 图表中文标签 */
const chartLabels: Record<string, string> = {
  bug_level: 'BUG等级分布',
  test_result: '用例执行结果分布',
  pass_rate: '用例执行情况统计',
  bug_by_module: '各模块BUG分布'
}

// ==================== 方法定义 ====================

/** 上传文件 */
const handleUpload = async () => {
  if (!testcaseFile.value || !buglistFile.value) {
    ElMessage.warning('请先选择测试用例和 BUG 列表文件')
    return
  }
  uploading.value = true
  try {
    const result = await functionalReportApi.upload(
      testcaseFile.value,
      buglistFile.value,
      sessionId.value
    )
    sessionId.value = result.session_id
    ElMessage.success('文件上传成功')
  } catch (error: any) {
    ElMessage.error('文件上传失败: ' + error.message)
  } finally {
    uploading.value = false
  }
}

/** 生成报告 */
const handleGenerate = async () => {
  if (!sessionId.value) {
    ElMessage.warning('请先上传文件')
    return
  }
  generating.value = true
  try {
    const result = await functionalReportApi.generate(
      sessionId.value,
      projectName.value,
      reportFormat.value
    )
    generateResult.value = result
    ElMessage.success('报告生成成功')
  } catch (error: any) {
    ElMessage.error('报告生成失败: ' + error.message)
  } finally {
    generating.value = false
  }
}

/** 重置所有状态 */
const resetAll = () => {
  testcaseFile.value = null
  buglistFile.value = null
  sessionId.value = ''
  projectName.value = ''
  reportFormat.value = 'docx'
  generateResult.value = null
  previewVisible.value = false
  erpDialogVisible.value = false
  projectDialogVisible.value = false
  cooperationDialogVisible.value = false
  ElMessage.success('已重置')
}

/** 获取图表预览URL */
const getChartUrl = (path: string) => {
  // 图表路径为后端文件系统路径，通过 /api/files 提供访问
  return `/api/files/${encodeURIComponent(path)}`
}

/** 从完整路径提取文件名 */
const getReportFileName = (path: string) => {
  if (!path) return ''
  const parts = path.split(/[\\/]/)
  return parts[parts.length - 1]
}

/** 下载报告 */
const downloadReport = (path: string) => {
  window.open(functionalReportApi.downloadUrl(sessionId.value, getReportFileName(path)), '_blank')
}

/** 预览 Markdown 报告 */
const previewReport = (path: string) => {
  getReportFileName(path)
  previewUrl.value = functionalReportApi.previewUrl(sessionId.value)
  previewLoading.value = true
  previewVisible.value = true
  // 等待 iframe 加载
  setTimeout(() => {
    previewLoading.value = false
  }, 1000)
}

/** 打开 ERP 上传弹窗 */
const openErpDialog = (report: string) => {
  currentErpReport.value = report
  erpDialogVisible.value = true
}

/** 上传报告到 ERP */
const handleErpUpload = async () => {
  if (!currentErpReport.value) {
    ElMessage.warning('请选择要上传的报告')
    return
  }
  erpUploading.value = true
  try {
    const result = await functionalReportApi.uploadToErp(
      sessionId.value,
      getReportFileName(currentErpReport.value),
      developtestingId.value,
      copyuserNames.value,
      createuserName.value || undefined
    )
    if (result.success) {
      ElMessage.success(result.message + (result.report_id ? ` 报告ID: ${result.report_id}` : ''))
      erpDialogVisible.value = false
    } else {
      ElMessage.error(result.message)
    }
  } catch (error: any) {
    ElMessage.error('ERP上传失败: ' + error.message)
  } finally {
    erpUploading.value = false
  }
}

/** 打开项目资料上传弹窗 */
const openProjectUploadDialog = (report: string) => {
  currentProjectReport.value = report
  projectFileName.value = getReportFileName(report)
  projectDialogVisible.value = true
}

/** 上传文件到 ERP 项目资料 */
const handleProjectUpload = async () => {
  if (!currentProjectReport.value) {
    ElMessage.warning('请选择要上传的报告')
    return
  }
  if (!projectId.value) {
    ElMessage.warning('请输入项目ID')
    return
  }
  projectUploading.value = true
  try {
    const result = await functionalReportApi.uploadToProject(
      sessionId.value,
      getReportFileName(currentProjectReport.value),
      projectId.value,
      projectFileName.value || undefined
    )
    if (result.success) {
      ElMessage.success(result.message)
      projectDialogVisible.value = false
    } else {
      ElMessage.error(result.message)
    }
  } catch (error: any) {
    ElMessage.error('项目资料上传失败: ' + error.message)
  } finally {
    projectUploading.value = false
  }
}

/** 打开协作文档上传弹窗 */
const openCooperationUploadDialog = (report: string) => {
  currentCooperationReport.value = report
  cooperationFileName.value = getReportFileName(report)
  cooperationDialogVisible.value = true
}

/** 上传文件到 ERP 协作文档 */
const handleCooperationUpload = async () => {
  if (!currentCooperationReport.value) {
    ElMessage.warning('请选择要上传的报告')
    return
  }
  if (!cooperationProjectId.value) {
    ElMessage.warning('请输入项目ID')
    return
  }
  cooperationUploading.value = true
  try {
    const result = await functionalReportApi.uploadToCooperation(
      sessionId.value,
      getReportFileName(currentCooperationReport.value),
      cooperationProjectId.value,
      cooperationFileName.value || undefined,
      cooperationGroupId.value
    )
    if (result.success) {
      ElMessage.success(result.message)
      cooperationDialogVisible.value = false
    } else {
      ElMessage.error(result.message)
    }
  } catch (error: any) {
    ElMessage.error('协作文档上传失败: ' + error.message)
  } finally {
    cooperationUploading.value = false
  }
}
</script>

<style lang="scss" scoped>
.functional-report-page {
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    h2 {
      margin: 0;
      font-size: 20px;
    }
  }

  .step-card {
    margin-bottom: 20px;

    .card-header {
      display: flex;
      align-items: center;
      gap: 12px;

      .step-title {
        font-size: 16px;
        font-weight: 600;
      }

      .step-tip {
        font-size: 12px;
        color: #909399;
      }
    }

    .upload-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 20px;
      margin-bottom: 16px;

      .upload-item {
        :deep(.el-upload) {
          width: 100%;
        }
      }
    }

    .upload-actions {
      display: flex;
      align-items: center;
      gap: 12px;
    }

    .result-summary {
      .summary-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 12px;
        margin-top: 12px;

        .summary-item {
          display: flex;
          flex-direction: column;
          gap: 4px;
          padding: 12px;
          background: #f5f7fa;
          border-radius: 4px;

          .label {
            font-size: 12px;
            color: #909399;
          }

          .value {
            font-size: 18px;
            font-weight: 600;
            color: #303133;

            &.success { color: #67c23a; }
            &.danger { color: #f56c6c; }
          }
        }
      }
    }

    .charts-block {
      margin-top: 16px;

      .charts-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
        margin-top: 12px;

        .chart-item {
          .chart-label {
            display: block;
            font-size: 13px;
            font-weight: 600;
            margin-bottom: 8px;
            color: #606266;
          }

          .chart-img {
            width: 100%;
            border: 1px solid #ebeef5;
            border-radius: 4px;
          }
        }
      }
    }

    .reports-block {
      margin-top: 16px;

      .report-list {
        margin-top: 12px;

        .report-item {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 10px 12px;
          border: 1px solid #ebeef5;
          border-radius: 4px;
          margin-bottom: 8px;

          &:hover {
            background: #f5f7fa;
          }

          .report-name {
            font-size: 14px;
            color: #303133;
          }

          .report-actions {
            display: flex;
            align-items: center;
            gap: 4px;
          }
        }
      }
    }
  }

  .preview-container {
    height: calc(100vh - 200px);

    .preview-iframe {
      width: 100%;
      height: 100%;
      border: none;
      border-radius: 4px;
    }
  }

  .form-tip {
    margin-left: 8px;
    font-size: 12px;
    color: #909399;
  }
}

/* 底部固定操作栏 */
.sticky-action-bar {
  position: fixed;
  bottom: 0;
  left: 220px; /* 侧边栏宽度 */
  right: 0;
  z-index: 100;
  background: #fff;
  border-top: 1px solid #e4e7ed;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
  padding: 0 24px;

  .action-bar-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 56px;
    max-width: 1200px;
    margin: 0 auto;
  }

  .action-bar-info {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;
    color: #606266;

    .action-bar-summary {
      font-size: 12px;
    }
  }

  .action-bar-buttons {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}
</style>