<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { reportApi } from '@/api/service-monitor'
import { useUserStore } from '@/stores/user'
import type { ReportDetail, CheckItem } from '@/types/service-monitor'

const route = useRoute()
const router = useRouter()
const userStore = useUserStore()

const reportId = route.params.reportId as string
const token = route.query.token as string | undefined

const loading = ref(false)
const error = ref('')
const report = ref<ReportDetail | null>(null)

// Check if guest mode (token auth)
const isGuest = computed(() => !!token)
const isAdmin = computed(() => userStore.isAdmin && !isGuest.value)

// Export menu
const showExportMenu = ref(false)

function toggleExport() {
  showExportMenu.value = !showExportMenu.value
}

function getExportUrl(format: 'md' | 'json' | 'excel' | 'pdf') {
  let url = `/api/service-monitor/reports/${reportId}/export?format=${format}`
  if (token) url += `&token=${token}`
  return url
}

// Format
function formatTime(timeStr: string | undefined) {
  if (!timeStr) return '-'
  return timeStr.replace('T', ' ').slice(0, 19)
}

function suiteLabel(suite: string) {
  return suite === 'quick' ? '⚡ 快速巡检' : '🔍 全量巡检'
}

function targetIcon(type: string) {
  return type === 'local' ? '🖥️' : '🌐'
}

// Abnormal items (warning + critical)
interface AbnormalItem {
  module_name: string
  item: CheckItem
}

const abnormalItems = computed<AbnormalItem[]>(() => {
  if (!report.value) return []
  const result: AbnormalItem[] = []
  for (const mod of report.value.modules) {
    for (const item of mod.items) {
      if (item.status === '警告' || item.status === '严重') {
        result.push({ module_name: mod.name, item })
      }
    }
  }
  return result
})

// Module collapse state
const expandedModules = ref<Set<string>>(new Set())

function toggleModule(moduleId: string) {
  if (expandedModules.value.has(moduleId)) {
    expandedModules.value.delete(moduleId)
  } else {
    expandedModules.value.add(moduleId)
  }
}

function isModuleExpanded(moduleId: string) {
  return expandedModules.value.has(moduleId)
}

// Long value toggle
const expandedValues = ref<Set<string>>(new Set())

function toggleValue(key: string) {
  if (expandedValues.value.has(key)) {
    expandedValues.value.delete(key)
  } else {
    expandedValues.value.add(key)
  }
}

function isValueExpanded(key: string) {
  return expandedValues.value.has(key)
}

function truncateValue(value: string, maxLen: number = 80) {
  if (value.length <= maxLen) return value
  return value.slice(0, maxLen) + '…'
}

// Process table toggle
const expandedProcessTables = ref<Set<string>>(new Set())

function toggleProcessTable(key: string) {
  if (expandedProcessTables.value.has(key)) {
    expandedProcessTables.value.delete(key)
  } else {
    expandedProcessTables.value.add(key)
  }
}

function isProcessTableExpanded(key: string) {
  return expandedProcessTables.value.has(key)
}

function isProcessList(key: string) {
  return key.endsWith('_PROCESS_LIST') || key.endsWith('_PROCESSES_DETAIL')
}

function parseProcessData(value: string) {
  const lines = value.split('|')
  return lines.map(line => {
    const parts = line.trim().split(/\s+/)
    if (parts.length >= 5) {
      return {
        user: parts[0],
        pid: parts[1],
        cpu: parts[2],
        mem: parts[3],
        cmd: parts.slice(4).join(' ')
      }
    }
    return null
  }).filter(Boolean)
}

// Compare modal
const compareModalVisible = ref(false)
const compareReports = ref<{ id: string; summary: any; finished_at: string }[]>([])
const selectedCompareId = ref<string | null>(null)

async function openCompareModal() {
  if (!report.value) return
  compareModalVisible.value = true
  selectedCompareId.value = null
  try {
    const res = await reportApi.getReports({ target_id: report.value.target_id })
    if (res.success && res.reports) {
      compareReports.value = res.reports
        .filter(r => r.id !== reportId)
        .slice(0, 20)
        .map(r => ({
          id: r.id,
          summary: r.summary,
          finished_at: r.finished_at || r.started_at
        }))
    }
  } catch {
    ElMessage.error('加载历史报告失败')
  }
}

function selectCompare(id: string) {
  selectedCompareId.value = id
}

function doCompare() {
  if (selectedCompareId.value) {
    router.push({
      name: 'MonitorCompare',
      params: { reportIdA: reportId, reportIdB: selectedCompareId.value }
    })
  }
}

// Load report
async function loadReport() {
  loading.value = true
  error.value = ''
  try {
    const res = await reportApi.getReport(reportId)
    if (res.success && res.report) {
      report.value = res.report
      // Auto expand modules with abnormal items
      for (const mod of res.report.modules) {
        const hasAbnormal = mod.items.some(it => it.status === '警告' || it.status === '严重')
        if (hasAbnormal) {
          expandedModules.value.add(mod.id)
        }
      }
    } else {
      error.value = '报告不存在'
    }
  } catch (e: any) {
    error.value = e?.message || '加载失败'
  } finally {
    loading.value = false
  }
}

onMounted(loadReport)
</script>

<template>
  <div class="page-report" v-loading="loading">
    <!-- Error state -->
    <div v-if="error" class="error-box">
      <div class="error-icon">❌</div>
      <div class="error-msg">{{ error }}</div>
      <el-button type="primary" @click="router.push({ name: 'MonitorReports' })" style="margin-top: 16px;">返回报告列表</el-button>
    </div>

    <template v-else-if="report">
      <!-- Guest banner -->
      <div v-if="isGuest" class="guest-banner">
        <span>👤 访客模式 — 仅可查看本报告</span>
        <a :href="`/login?next=${encodeURIComponent(route.fullPath)}`" class="btn-login">🔑 登录查看更多功能</a>
      </div>

      <!-- Header -->
      <div class="report-head">
        <div class="report-meta">
          <h2>{{ targetIcon(report.target_type) }} {{ report.target_name }}</h2>
          <div class="sub">
            {{ suiteLabel(report.suite) }} ·
            {{ formatTime(report.started_at) }} ~ {{ report.finished_at?.slice(11, 19) || '-' }}
          </div>
        </div>
        <div class="report-actions">
          <el-button v-if="!isGuest" type="success" @click="openCompareModal">📊 对比历史报告</el-button>
          <div class="export-wrap" @click.stop>
            <el-button type="primary" @click="toggleExport">
              ⬇ 导出 ▾
            </el-button>
            <div v-if="showExportMenu" class="export-menu">
              <a :href="getExportUrl('md')" target="_blank">导出 Markdown</a>
              <a :href="getExportUrl('json')" target="_blank">导出 JSON</a>
              <a :href="getExportUrl('excel')" target="_blank">导出 Excel</a>
              <a :href="getExportUrl('pdf')" target="_blank">导出 PDF</a>
            </div>
          </div>
        </div>
      </div>

      <!-- Summary cards -->
      <div class="summary-cards">
        <div class="sum-card sum-total">
          <div class="num">{{ report.summary?.total || 0 }}</div>
          <div class="label">总检测项</div>
        </div>
        <div class="sum-card sum-ok">
          <div class="num">{{ report.summary?.['正常'] || 0 }}</div>
          <div class="label">正常</div>
        </div>
        <div class="sum-card sum-warn">
          <div class="num">{{ report.summary?.['警告'] || 0 }}</div>
          <div class="label">警告</div>
        </div>
        <div class="sum-card sum-crit">
          <div class="num">{{ report.summary?.['严重'] || 0 }}</div>
          <div class="label">严重</div>
        </div>
      </div>

      <!-- Abnormal items -->
      <template v-if="abnormalItems.length > 0">
        <div class="section-title">⚠️ 异常项（{{ abnormalItems.length }}）</div>
        <div class="abnormal-box">
          <div v-for="(ab, idx) in abnormalItems" :key="idx" class="abnormal-row">
            <span class="ab-icon" :class="ab.item.status === '严重' ? 'crit' : 'warn'">
              {{ ab.item.status === '严重' ? '✗' : '⚠' }}
            </span>
            <span class="ab-info">
              <span class="ab-name">{{ ab.item.name }}</span>
              <span class="ab-module">{{ ab.module_name }}</span>
            </span>
            <span class="ab-value" :class="ab.item.status === '严重' ? 'crit' : 'warn'">
              {{ ab.item.value }}
            </span>
            <span class="ab-threshold">{{ ab.item.threshold || '-' }}</span>
            <span class="item-status" :class="'stt-' + ab.item.status">{{ ab.item.status }}</span>
            <button v-if="isAdmin" class="btn-fix">修复</button>
          </div>
        </div>
      </template>
      <template v-else>
        <div class="section-title">✅ 全部正常</div>
      </template>

      <!-- Module details -->
      <div class="section-title">📋 检测明细（点击展开）</div>
      <div
        v-for="mod in report.modules"
        :key="mod.id"
        class="module-block"
        :class="{ open: isModuleExpanded(mod.id) }"
      >
        <div class="module-header" @click="toggleModule(mod.id)">
          <span class="module-toggle">▶</span>
          <span class="module-title">{{ mod.name }}</span>
          <span class="module-mini">
            <span v-if="mod.summary?.['正常']" class="stt-正常">✓{{ mod.summary['正常'] }}</span>
            <span v-if="mod.summary?.['警告']" class="stt-警告">⚠{{ mod.summary['警告'] }}</span>
            <span v-if="mod.summary?.['严重']" class="stt-严重">✗{{ mod.summary['严重'] }}</span>
          </span>
        </div>
        <div class="module-body">
          <template v-for="item in mod.items" :key="item.key">
            <!-- Process list special rendering -->
            <div v-if="isProcessList(item.key)" class="process-row">
              <div class="process-summary">
                <span>{{ item.name }}</span>
                <el-button size="small" @click="toggleProcessTable(item.key)">
                  {{ isProcessTableExpanded(item.key) ? '收起详情' : '展开详情' }}
                </el-button>
              </div>
              <div v-if="isProcessTableExpanded(item.key)" class="process-table-wrap">
                <table class="process-table">
                  <thead>
                    <tr>
                      <th>用户</th>
                      <th>PID</th>
                      <th>CPU%</th>
                      <th>内存%</th>
                      <th>命令</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(p, idx) in parseProcessData(item.value)" :key="idx">
                      <td>{{ p?.user }}</td>
                      <td>{{ p?.pid }}</td>
                      <td>{{ p?.cpu }}</td>
                      <td>{{ p?.mem }}</td>
                      <td class="cmd-cell" :title="p?.cmd">{{ p?.cmd }}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <!-- Normal item -->
            <div v-else class="item-row">
              <span class="item-name">{{ item.name }}</span>
              <span
                v-if="item.value.length > 80"
                class="item-value long-value"
                :class="{ expanded: isValueExpanded(item.key) }"
                @click="toggleValue(item.key)"
              >
                <span class="truncated">{{ truncateValue(item.value) }}</span>
                <span class="full">{{ item.value }}</span>
              </span>
              <span v-else class="item-value">{{ item.value }}</span>
              <span class="item-threshold">{{ item.threshold || '-' }}</span>
              <span class="item-status" :class="'stt-' + item.status">{{ item.status }}</span>
            </div>
          </template>
        </div>
      </div>

      <!-- Compare modal -->
      <el-dialog
        v-model="compareModalVisible"
        title="选择对比报告"
        width="500px"
      >
        <div v-if="compareReports.length === 0" class="compare-empty">
          暂无其他历史报告
        </div>
        <div v-else class="compare-list">
          <div
            v-for="r in compareReports"
            :key="r.id"
            class="compare-item"
            :class="{ selected: selectedCompareId === r.id }"
            @click="selectCompare(r.id)"
          >
            <el-radio :model-value="selectedCompareId ?? undefined" :value="r.id" @click.stop>&nbsp;</el-radio>
            <div class="compare-info">
              <div class="compare-date">{{ formatTime(r.finished_at) }}</div>
              <div class="compare-summary">
                正常 {{ r.summary?.['正常'] || 0 }} / 警告 {{ r.summary?.['警告'] || 0 }} / 严重 {{ r.summary?.['严重'] || 0 }}
              </div>
            </div>
          </div>
        </div>
        <template #footer>
          <el-button @click="compareModalVisible = false">取消</el-button>
          <el-button type="primary" :disabled="!selectedCompareId" @click="doCompare">开始对比</el-button>
        </template>
      </el-dialog>
    </template>
  </div>
</template>

<style scoped lang="scss">
.page-report {
  padding: 0 0 40px;
  max-width: 960px;
  margin: 0 auto;
}

.guest-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #fef3c7;
  border: 1px solid #f59e0b;
  border-radius: 8px;
  padding: 10px 16px;
  margin-bottom: 16px;
  font-size: 14px;
  color: #92400e;
  flex-wrap: wrap;
  gap: 10px;

  .btn-login {
    background: #2563eb;
    color: #fff;
    padding: 6px 14px;
    border-radius: 6px;
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;

    &:hover {
      background: #1d4ed8;
    }
  }
}

.report-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
  flex-wrap: wrap;
  gap: 12px;
}

.report-meta h2 {
  font-size: 20px;
  color: $gray-900;
  margin-bottom: 4px;
}

.report-meta .sub {
  font-size: 13px;
  color: $gray-500;
}

.report-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.export-wrap {
  position: relative;
}

.export-menu {
  position: absolute;
  right: 0;
  top: 44px;
  background: #fff;
  border: 1px solid $gray-200;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  z-index: 10;

  a {
    display: block;
    padding: 10px 20px;
    font-size: 14px;
    color: $gray-700;
    text-decoration: none;

    &:hover {
      background: $gray-50;
    }
  }
}

/* Summary cards */
.summary-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}

.sum-card {
  background: #fff;
  border-radius: 12px;
  padding: 18px;
  text-align: center;
  border: 1px solid $gray-200;

  .num {
    font-size: 28px;
    font-weight: 700;
  }

  .label {
    font-size: 13px;
    color: $gray-500;
    margin-top: 4px;
  }
}

.sum-total .num { color: $gray-900; }
.sum-ok .num { color: $green; }
.sum-warn .num { color: $yellow; }
.sum-crit .num { color: $red; }

/* Section title */
.section-title {
  font-size: 16px;
  font-weight: 700;
  color: $gray-900;
  margin: 24px 0 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Abnormal box */
.abnormal-box {
  background: #fff;
  border-radius: 12px;
  border: 1px solid $gray-200;
  overflow: hidden;
}

.abnormal-row {
  display: grid;
  grid-template-columns: 24px 2fr 1fr 1fr 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 12px 18px;
  border-bottom: 1px solid $gray-100;
  font-size: 14px;

  &:last-child {
    border-bottom: none;
  }
}

.ab-icon {
  text-align: center;

  &.crit { color: $red; }
  &.warn { color: $yellow; }
}

.ab-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ab-name {
  font-weight: 600;
  color: $gray-900;
}

.ab-module {
  font-size: 12px;
  color: $gray-500;
}

.ab-value {
  font-weight: 600;

  &.crit { color: $red; }
  &.warn { color: $yellow; }
}

.ab-threshold {
  font-size: 13px;
  color: $gray-500;
}

.item-status {
  font-weight: 600;
}

.stt-正常 { color: $green; }
.stt-警告 { color: $yellow; }
.stt-严重 { color: $red; }

.btn-fix {
  background: #fef3c7;
  color: #92400e;
  border: none;
  padding: 5px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

/* Module block */
.module-block {
  background: #fff;
  border-radius: 12px;
  border: 1px solid $gray-200;
  margin-bottom: 12px;
  overflow: hidden;

  .module-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    cursor: pointer;
    user-select: none;

    &:hover {
      background: $gray-50;
    }
  }

  .module-toggle {
    font-size: 12px;
    color: $gray-500;
    transition: transform 0.2s;
    flex-shrink: 0;
  }

  &.open .module-toggle {
    transform: rotate(90deg);
  }

  .module-title {
    font-weight: 700;
    color: $gray-900;
    flex: 1;
  }

  .module-mini {
    display: flex;
    gap: 8px;
    font-size: 13px;
  }

  .module-body {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.35s ease;
  }

  &.open .module-body {
    max-height: 5000px;
  }
}

/* Item row */
.item-row {
  display: grid;
  grid-template-columns: 2fr 1.5fr 1fr 1fr;
  gap: 12px;
  padding: 10px 18px;
  border-top: 1px solid $gray-100;
  font-size: 14px;
}

.item-name {
  color: $gray-700;
}

.item-value {
  color: $gray-900;
  font-weight: 600;
  word-break: break-all;

  &.long-value {
    cursor: pointer;
    color: $primary;

    .full {
      display: none;
    }

    &.expanded {
      .truncated {
        display: none;
      }
      .full {
        display: inline;
        white-space: pre-wrap;
        word-break: break-all;
      }
    }
  }
}

.item-threshold {
  color: $gray-500;
  font-size: 13px;
}

/* Process row */
.process-row {
  border-top: 1px solid $gray-100;
  padding: 10px 18px;
}

.process-summary {
  font-weight: 600;
  color: $gray-900;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.process-table-wrap {
  overflow-x: auto;
  margin-top: 8px;
}

.process-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;

  th {
    background: $gray-50;
    padding: 8px 10px;
    text-align: left;
    font-weight: 600;
    color: $gray-700;
    border-bottom: 2px solid $gray-200;
  }

  td {
    padding: 6px 10px;
    border-bottom: 1px solid $gray-100;
    color: $gray-900;
  }

  tr:hover td {
    background: $gray-50;
  }

  .cmd-cell {
    font-family: monospace;
    font-size: 12px;
    max-width: 300px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* Compare modal */
.compare-empty {
  text-align: center;
  padding: 20px;
  color: $gray-500;
}

.compare-list {
  max-height: 400px;
  overflow-y: auto;
}

.compare-item {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border: 1px solid $gray-200;
  border-radius: 8px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: all 0.15s;

  &:hover {
    border-color: $primary;
    background: $gray-50;
  }

  &.selected {
    border-color: $primary;
    background: #eff6ff;
  }
}

.compare-info {
  flex: 1;
  margin-left: 12px;
}

.compare-date {
  font-size: 14px;
  font-weight: 600;
  color: $gray-900;
}

.compare-summary {
  font-size: 12px;
  color: $gray-500;
  margin-top: 2px;
}

/* Error box */
.error-box {
  text-align: center;
  padding: 40px 20px;

  .error-icon {
    font-size: 48px;
    margin-bottom: 12px;
  }

  .error-msg {
    color: $red;
    font-size: 16px;
    font-weight: 600;
  }
}

@media screen and (max-width: 768px) {
  .page-report {
    padding: 0 12px 40px;
  }

  .guest-banner {
    flex-direction: column;
    text-align: center;
    gap: 8px;
    padding: 12px;
  }

  .report-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .report-meta h2 {
    font-size: 16px;
  }

  .report-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  .export-wrap {
    width: 100%;
  }

  .export-menu {
    position: fixed;
    left: 12px;
    right: 12px;
    top: auto;
    bottom: 12px;
    border-radius: 12px;
  }

  .summary-cards {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  .sum-card {
    padding: 12px;
    .num { font-size: 22px; }
  }

  .abnormal-row {
    grid-template-columns: 20px 1fr auto;
    gap: 6px;
    padding: 10px 12px;
    font-size: 13px;

    .ab-threshold, .ab-module, .btn-fix {
      display: none;
    }
  }

  .ab-name {
    font-size: 13px;
  }

  .module-header {
    padding: 12px 14px;
  }

  .module-title {
    font-size: 14px;
    word-break: break-word;
  }

  .module-mini {
    font-size: 12px;
  }

  .item-row {
    grid-template-columns: 1fr auto;
    gap: 4px;
    padding: 8px 14px;
    font-size: 13px;
  }

  .item-threshold {
    display: none;
  }

  .item-status {
    white-space: nowrap;
  }

  .process-table {
    font-size: 11px;

    th, td {
      padding: 4px 6px;
    }

    .cmd-cell {
      max-width: 120px;
    }
  }
}

@media screen and (max-width: 480px) {
  .report-meta h2 {
    font-size: 14px;
  }

  .report-meta .sub {
    font-size: 12px;
  }

  .summary-cards {
    gap: 6px;
  }

  .sum-card {
    padding: 10px;
    .num { font-size: 18px; }
    .label { font-size: 11px; }
  }

  .abnormal-row {
    padding: 8px 10px;
    font-size: 12px;
    gap: 4px;
  }

  .module-header {
    padding: 10px 12px;
  }

  .module-title {
    font-size: 13px;
  }

  .item-row {
    padding: 7px 12px;
    font-size: 12px;
  }

  .item-value {
    font-size: 12px;
    word-break: break-word;
  }

  .process-table {
    font-size: 10px;

    .cmd-cell {
      max-width: 90px;
    }
  }

  .guest-banner {
    padding: 10px;
    font-size: 13px;
  }

  .btn-login {
    padding: 5px 10px;
    font-size: 12px;
  }
}
</style>