<template>
  <section class="df-panel" style="animation-delay: 240ms">
    <div class="df-panel-head">
      <h2 class="df-panel-title">{{ $t('dashboard.activeProjects') }}</h2>
      <router-link to="/projects" class="df-link">{{ $t('dashboard.viewAll') }}</router-link>
    </div>
    <div class="project-list">
      <div v-for="(p, i) in displayProjects" :key="p.id" class="project-row" :style="{ animationDelay: `${300 + i * 50}ms` }">
        <div class="project-row-top">
          <div class="project-identity">
            <span class="project-dot" :class="'dot-' + p.stage"></span>
            <span class="project-name">{{ p.name }}</span>
          </div>
          <span class="project-stage-chip" :class="'chip-' + p.stage">{{ $t('dashboard.stage.' + p.stageLabelKey) }}</span>
        </div>
        <div class="project-bar-wrap">
          <div class="project-bar">
            <div class="project-bar-fill" :class="'fill-' + p.stage" :style="{ width: p.progress + '%' }"></div>
          </div>
          <span class="project-pct">{{ p.progress }}%</span>
        </div>
        <div class="project-meta-row">
          <span class="project-meta-item">
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 3v12"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 01-9 9"/></svg>
            {{ $t('dashboard.taskUnit', { n: p.activeTasks }) }}
          </span>
          <span class="project-meta-time">{{ p.lastActivity }}</span>
        </div>
      </div>
      <div v-if="displayProjects.length === 0" class="empty-hint">{{ t('dashboard.empty.noProjects') }} <router-link to="/projects" class="df-link">{{ t('dashboard.empty.noProjectsLink') }}</router-link></div>
    </div>
  </section>
</template>

<script setup lang="ts">
// 活跃项目面板 — 从 Dashboard.vue 抽出(项目列表 + 进度条 + 阶段 chip + 空态)。
// 共享 project store(全局单例),displayProjects computed 直读 store.projects/tasks,无需父传 props。
// getProjectStage 死键语义对齐 constants/project.ts 的 PROJECT_STAGE_INFO。
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useProjectStore } from '@/stores/project'
import { formatRelativeZh } from '@/utils/time'

const store = useProjectStore()
const { t } = useI18n()

function getProjectStage(status: string): { stage: string; stageLabelKey: string; progress: number } {
  // F-09 对齐:project status 死键(in_progress/paused/cancelled)已从后端映射移除,
  // 此处 switch 同步收敛,与 constants/project.ts 的 PROJECT_STAGE_INFO 语义一致。
  switch (status) {
    case 'planning': return { stage: 'planning', stageLabelKey: 'planning', progress: 20 }
    case 'active': return { stage: 'coding', stageLabelKey: 'coding', progress: 55 }
    case 'completed': return { stage: 'release', stageLabelKey: 'done', progress: 100 }
    default: return { stage: 'planning', stageLabelKey: 'planning', progress: 20 }
  }
}

function getProjectTaskCount(projectId: string): number {
  return store.tasks.filter(t => t.project_id === projectId && t.status === 'in_progress').length
}

// 相对时间复用 utils/time.formatRelativeZh(与 Tasks/AuditLog/MessageList 等同源,根治 NaN)
// 原 formatLastActivity 是其逐行复制,提取为单一来源。
const formatLastActivity = formatRelativeZh

const displayProjects = computed(() =>
  store.projects.map(p => {
    const stageInfo = getProjectStage(p.status)
    return {
      id: p.id,
      name: p.name,
      ...stageInfo,
      activeTasks: getProjectTaskCount(p.id),
      lastActivity: formatLastActivity(p.updated_at),
    }
  })
)
</script>

<style scoped>
/* 仅迁入项目行自身样式;df-panel/df-link 等通用面板类留 Dashboard.vue(多面板共享) */
.project-list { display: flex; flex-direction: column; }
.project-row {
  padding: 10px 0;
  border-bottom: 0.5px solid var(--df-border);
  animation: fadeInUp 0.4s var(--df-ease) both;
}
.project-row:last-child { border-bottom: none; }

.project-row-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.project-identity { display: flex; align-items: center; gap: 8px; }
.project-dot {
  width: 6px; height: 6px; border-radius: 50%;
}
.dot-coding { background: var(--df-accent); }
.dot-testing { background: var(--df-warning); }
.dot-release { background: var(--df-success); }
.dot-planning { background: var(--df-info); }
.dot-cancelled { background: var(--df-text-dim); }

.project-name {
  font-size: 12px;
  font-weight: 500;
  font-family: var(--df-font-mono);
  color: var(--df-text);
}

.project-stage-chip {
  font-size: 9px;
  font-weight: 500;
  padding: 1px 6px;
  border-radius: var(--df-radius-sm);
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.chip-coding { background: rgba(123,111,240,0.12); color: var(--df-accent); }
.chip-testing { background: rgba(240,199,94,0.12); color: var(--df-warning); }
.chip-release { background: rgba(61,219,160,0.12); color: var(--df-success); }
.chip-planning { background: rgba(94,175,240,0.12); color: var(--df-info); }
.chip-cancelled { background: rgba(255,255,255,0.06); color: var(--df-text-dim); }

.project-bar-wrap { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.project-bar {
  flex: 1;
  height: 3px;
  background: rgba(255,255,255,0.06);
  border-radius: var(--df-radius-sm);
  overflow: hidden;
}
.project-bar-fill {
  height: 100%;
  border-radius: var(--df-radius-sm);
  transition: width 0.6s var(--df-ease);
}
.fill-coding { background: var(--df-accent); }
.fill-testing { background: var(--df-warning); }
.fill-release { background: var(--df-success); }
.fill-planning { background: var(--df-info); }
.fill-cancelled { background: var(--df-text-dim); }

.project-pct {
  font-family: var(--df-font-mono);
  font-size: 11px;
  color: var(--df-text-dim);
  min-width: 32px;
  text-align: right;
}

.project-meta-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.project-meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--df-text-dim);
}
.project-meta-time {
  font-size: 11px;
  color: var(--df-text-dim);
  font-family: var(--df-font-mono);
}
</style>
