<template>
  <div class="aggregate-container">
    <el-row :gutter="24">
      <!-- 任务配置卡片 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="10">
        <el-card class="config-card" shadow="hover">
          <template #header>
            <div class="card-header">
              <el-icon class="header-icon"><Setting /></el-icon>
              <span class="card-title">任务配置</span>
            </div>
          </template>

          <el-form :model="form" label-width="100px" label-position="left">
            <el-form-item label="源目录" required>
              <el-input
                v-model="form.srcDir"
                placeholder="选择需要递归扫描的起始目录"
                clearable
              >
                <template #prefix>
                  <el-icon><Folder /></el-icon>
                </template>
              </el-input>
            </el-form-item>

            <el-form-item label="目标目录" required>
              <el-input
                v-model="form.dstDir"
                placeholder="汇聚后的扁平目录"
                clearable
              >
                <template #prefix>
                  <el-icon><FolderOpened /></el-icon>
                </template>
              </el-input>
            </el-form-item>

            <el-form-item label="模式">
              <el-radio-group v-model="form.mode" size="default">
                <el-radio-button value="copy">
                  <el-icon><DocumentCopy /></el-icon>
                  <span style="margin-left: 4px">复制模式</span>
                </el-radio-button>
                <el-radio-button value="move">
                  <el-icon><Right /></el-icon>
                  <span style="margin-left: 4px">移动模式</span>
                </el-radio-button>
              </el-radio-group>
            </el-form-item>

            <el-form-item>
              <el-button
                type="primary"
                :loading="submitting"
                :disabled="!canStart"
                @click="startTask"
                size="large"
                style="width: 100%"
              >
                <el-icon v-if="!submitting"><VideoPlay /></el-icon>
                <span style="margin-left: 4px">{{ submitting ? '处理中...' : '开始汇聚' }}</span>
              </el-button>
            </el-form-item>

            <el-form-item>
              <el-button @click="reset" size="default" style="width: 100%">
                <el-icon><Refresh /></el-icon>
                <span style="margin-left: 4px">重置</span>
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>

      <!-- 任务进度卡片 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="14">
        <el-card class="progress-card" shadow="hover">
          <template #header>
            <div class="card-header">
              <el-icon class="header-icon"><DataLine /></el-icon>
              <span class="card-title">任务进度</span>
              <el-tag
                v-if="progress.taskId && progress.completed"
                type="info"
                size="small"
                effect="plain"
                class="connection-tag"
              >
                <el-icon class="connection-icon"><CircleCheck /></el-icon>
                <span class="connection-text">已结束</span>
              </el-tag>
              <el-tag
                v-else-if="progress.taskId && wsConnected"
                type="success"
                size="small"
                effect="plain"
                class="connection-tag"
              >
                <el-icon class="connection-icon"><Connection /></el-icon>
                <span class="connection-text">已连接</span>
              </el-tag>
              <el-tag
                v-else-if="progress.taskId && !wsConnected"
                type="warning"
                size="small"
                effect="plain"
                class="connection-tag"
              >
                <el-icon class="connection-icon"><Loading /></el-icon>
                <span class="connection-text">连接中</span>
              </el-tag>
            </div>
          </template>

          <div v-if="!progress.taskId" class="empty-state">
            <el-icon class="empty-icon"><Document /></el-icon>
            <p class="empty-text">等待开始任务...</p>
          </div>

          <div v-else class="progress-content">
            <!-- 统计信息 -->
            <div class="stats-grid">
              <div class="stat-item">
                <div class="stat-label">总数</div>
                <div class="stat-value">{{ progress.total }}</div>
              </div>
              <div class="stat-item">
                <div class="stat-label">已处理</div>
                <div class="stat-value success">{{ progress.processed }}</div>
              </div>
              <div class="stat-item">
                <div class="stat-label">成功</div>
                <div class="stat-value success">{{ progress.success }}</div>
              </div>
              <div class="stat-item">
                <div class="stat-label">失败</div>
                <div class="stat-value failed">{{ progress.failed }}</div>
              </div>
            </div>

            <!-- 进度条 -->
            <div class="progress-section">
              <el-progress
                :percentage="percentage"
                :status="progress.completed ? 'success' : progress.failed > 0 ? 'exception' : undefined"
                :stroke-width="12"
                :show-text="true"
                :format="formatProgress"
              />
            </div>

            <!-- 当前文件 -->
            <div v-if="progress.currentFile" class="current-file-section">
              <el-icon class="file-icon"><Document /></el-icon>
              <span class="file-text">{{ progress.currentFile }}</span>
            </div>

            <!-- 消息提示 -->
            <div v-if="progress.message" class="message-section">
              <el-alert
                :type="progress.completed ? (progress.failed > 0 ? 'warning' : 'success') : 'info'"
                :closable="false"
                show-icon
              >
                <template #title>
                  <span>{{ progress.message }}</span>
                </template>
              </el-alert>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import {
  Setting,
  Folder,
  FolderOpened,
  DocumentCopy,
  Right,
  VideoPlay,
  Refresh,
  DataLine,
  Connection,
  CircleCheck,
  Loading,
  Warning,
  Document
} from '@element-plus/icons-vue';
import { startAggregate } from '../api/aggregate';
import { getProgress } from '../api/progress';
import { useWebSocket, type ProgressMessage } from '../composables/useWebSocket';

interface Progress {
  taskId: string | null;
  total: number;
  processed: number;
  success: number;
  failed: number;
  currentFile: string;
  message: string;
  completed: boolean;
}

const form = reactive({
  srcDir: '',
  dstDir: '',
  mode: 'copy' as 'copy' | 'move'
});

const submitting = ref(false);
const wsConnected = ref(false);

const progress = reactive<Progress>({
  taskId: null,
  total: 0,
  processed: 0,
  success: 0,
  failed: 0,
  currentFile: '',
  message: '',
  completed: false
});

const canStart = computed(() => {
  return form.srcDir.trim() && form.dstDir.trim() && !submitting.value;
});

const percentage = computed(() => {
  if (!progress.total) return 0;
  return Math.round((progress.processed / progress.total) * 100);
});

// WebSocket 连接
let wsDisconnect: (() => void) | null = null;
let pollTimer: number | null = null;

function startPolling(taskId: string) {
  stopPolling();
  pollTimer = window.setInterval(async () => {
    try {
      const latest = await getProgress(taskId);
      if (latest) {
        handleProgressMessage(latest);
        if (latest.completed) {
          stopPolling();
        }
      }
    } catch {
      // 忽略轮询错误
    }
  }, 800);
}

function stopPolling() {
  if (pollTimer) {
    clearInterval(pollTimer);
    pollTimer = null;
  }
}

watch(
  () => progress.taskId,
  (newTaskId) => {
    if (newTaskId) {
      const { connect, disconnect, connected } = useWebSocket(newTaskId, handleProgressMessage);
      wsDisconnect = disconnect;
      watch(connected, (val) => {
        wsConnected.value = val;
      });
      connect();
      // 兜底轮询：防止任务很快完成导致 WebSocket 消息丢失
      startPolling(newTaskId);
    }
  }
);

function handleProgressMessage(msg: ProgressMessage) {
  progress.total = msg.total;
  progress.processed = msg.processed;
  progress.success = msg.success;
  progress.failed = msg.failed;
  progress.currentFile = msg.currentFile || '';
  progress.message = msg.message || '';
  progress.completed = msg.completed;

  if (msg.completed) {
    submitting.value = false;
    if (wsDisconnect) {
      wsDisconnect();
      wsDisconnect = null;
    }
    stopPolling();
  }
}

async function startTask() {
  if (!canStart.value) {
    ElMessage.warning('请填写源目录和目标目录');
    return;
  }

  submitting.value = true;
  progress.completed = false;
  progress.total = 0;
  progress.processed = 0;
  progress.success = 0;
  progress.failed = 0;
  progress.currentFile = '';
  progress.message = '';

  try {
    const response = await startAggregate({
      srcDir: form.srcDir.trim(),
      dstDir: form.dstDir.trim(),
      mode: form.mode
    });

    progress.taskId = response.taskId;
    ElMessage.success('任务已启动，正在处理...');
  } catch (error: any) {
    submitting.value = false;
    ElMessage.error(error.message || '启动任务失败');
  }
}

function reset() {
  if (wsDisconnect) {
    wsDisconnect();
    wsDisconnect = null;
  }
  stopPolling();
  form.srcDir = '';
  form.dstDir = '';
  form.mode = 'copy';
  progress.taskId = null;
  progress.total = 0;
  progress.processed = 0;
  progress.success = 0;
  progress.failed = 0;
  progress.currentFile = '';
  progress.message = '';
  progress.completed = false;
  submitting.value = false;
  wsConnected.value = false;
}

function formatProgress(percentage: number): string {
  return `${percentage}%`;
}

onUnmounted(() => {
  if (wsDisconnect) {
    wsDisconnect();
  }
  stopPolling();
});
</script>

<style scoped>
.aggregate-container {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
}

.config-card,
.progress-card {
  height: 100%;
  min-height: 500px;
}

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

.connection-tag {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  padding: 2px 8px;
  font-size: 12px;
  line-height: 1.2;
  height: auto;
}

.connection-icon {
  font-size: 12px;
  margin-right: 2px;
}

.connection-text {
  font-size: 12px;
  white-space: nowrap;
}

.header-icon {
  font-size: 18px;
  color: var(--el-color-primary);
}

.card-title {
  font-size: 16px;
  font-weight: 600;
  flex: 1;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: var(--el-text-color-secondary);
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-text {
  font-size: 14px;
  margin: 0;
}

.progress-content {
  padding: 8px 0;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.stat-item {
  text-align: center;
  padding: 16px;
  background: var(--el-bg-color-page);
  border-radius: 8px;
  transition: all 0.3s;
}

.stat-item:hover {
  background: var(--el-bg-color);
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.stat-label {
  font-size: 13px;
  color: var(--el-text-color-secondary);
  margin-bottom: 8px;
}

.stat-value {
  font-size: 24px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.stat-value.success {
  color: var(--el-color-success);
}

.stat-value.failed {
  color: var(--el-color-danger);
}

.progress-section {
  margin-bottom: 20px;
}

.current-file-section {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: var(--el-bg-color-page);
  border-radius: 6px;
  margin-bottom: 16px;
}

.file-icon {
  color: var(--el-color-primary);
  font-size: 18px;
}

.file-text {
  flex: 1;
  font-size: 13px;
  color: var(--el-text-color-regular);
  word-break: break-all;
  line-height: 1.5;
}

.message-section {
  margin-top: 16px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }
}
</style>

