<script setup lang="ts">
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import { RDMS_REQ_PRIORITY_DICT_CODE } from '@/constants/dict';
import { OBJECT_CONTEXT_QUERY_KEY } from '@/constants/object-context';
import DictTag from '@/components/custom/dict-tag.vue';
import { formatDateRange, getExecutionStatusTagType } from '@/views/project/project/execution/shared';
import { type WorkbenchMyExecutionItem, buildWorkbenchMyExecutionItems } from '../homepage';
import { workbenchMyExecutionMock } from '../mock';
import WorkbenchModuleCard from './workbench-module-card.vue';

defineOptions({ name: 'WorkbenchMyExecution' });

interface Props {
  editing?: boolean;
  collapsed?: boolean;
}
withDefaults(defineProps<Props>(), { editing: false, collapsed: false });
defineEmits<{ (e: 'hide'): void; (e: 'toggle-collapse'): void }>();

const router = useRouter();

const items = computed(() => buildWorkbenchMyExecutionItems(workbenchMyExecutionMock));

// 按项目归类：未完成执行数多的项目在前；项目内按计划结束日升序（更紧的在前）
const groups = computed<Array<{ projectId: string; projectName: string; items: WorkbenchMyExecutionItem[] }>>(() => {
  const map = new Map<string, { projectId: string; projectName: string; items: WorkbenchMyExecutionItem[] }>();
  items.value.forEach(item => {
    if (!map.has(item.projectId)) {
      map.set(item.projectId, { projectId: item.projectId, projectName: item.projectName, items: [] });
    }
    map.get(item.projectId)!.items.push(item);
  });
  const groupsArr = Array.from(map.values());
  groupsArr.forEach(g => {
    g.items.sort((a, b) => {
      const av = a.plannedEndDate ? new Date(a.plannedEndDate).getTime() : Number.POSITIVE_INFINITY;
      const bv = b.plannedEndDate ? new Date(b.plannedEndDate).getTime() : Number.POSITIVE_INFINITY;
      return av - bv;
    });
  });
  return groupsArr.sort((a, b) => b.items.length - a.items.length);
});

function goProjectExecutionPool(projectId: string) {
  router.push({
    path: '/project/project/execution',
    query: { [OBJECT_CONTEXT_QUERY_KEY]: projectId }
  });
}

function goRequirementDetail(item: WorkbenchMyExecutionItem) {
  if (!item.projectRequirementId) return;
  router.push({
    path: '/project/project/requirement',
    query: {
      [OBJECT_CONTEXT_QUERY_KEY]: item.projectId,
      requirementId: item.projectRequirementId
    }
  });
}
</script>

<template>
  <WorkbenchModuleCard
    title="我负责的执行"
    icon="mdi:flag-checkered"
    :badge-count="items.length"
    :editing="editing"
    :collapsed="collapsed"
    @hide="$emit('hide')"
    @toggle-collapse="$emit('toggle-collapse')"
  >
    <div v-if="items.length" class="exec-groups">
      <section v-for="group in groups" :key="group.projectId" class="exec-group">
        <header class="exec-group__head">
          <SvgIcon icon="mdi:briefcase-outline" class="exec-group__icon" />
          <span
            class="exec-group__name"
            role="button"
            tabindex="0"
            :title="`进入「${group.projectName}」执行池`"
            @click="goProjectExecutionPool(group.projectId)"
            @keydown.enter.prevent="goProjectExecutionPool(group.projectId)"
          >
            {{ group.projectName }}
          </span>
          <span class="exec-group__count">{{ group.items.length }}</span>
        </header>
        <ul class="exec-list">
          <li v-for="item in group.items" :key="item.id" class="exec-item">
            <div class="exec-head">
              <span class="exec-name" :title="item.executionName">{{ item.executionName }}</span>
              <DictTag
                class="exec-head__tag"
                :dict-code="RDMS_REQ_PRIORITY_DICT_CODE"
                :value="item.priority"
                effect="light"
                size="small"
              />
              <ElTag
                class="exec-head__tag"
                size="small"
                :type="getExecutionStatusTagType(item.statusCode)"
                effect="light"
              >
                {{ item.statusName }}
              </ElTag>
            </div>
            <div class="exec-meta">
              <div class="exec-meta__row">
                <SvgIcon icon="mdi:flag-outline" class="exec-meta__icon" />
                <span class="exec-meta__text">
                  计划 {{ formatDateRange(item.plannedStartDate, item.plannedEndDate) }}
                </span>
              </div>
              <div class="exec-meta__row">
                <SvgIcon icon="mdi:calendar-outline" class="exec-meta__icon" />
                <span class="exec-meta__text">
                  实际 {{ formatDateRange(item.actualStartDate, item.actualEndDate) }}
                </span>
              </div>
              <div v-if="item.projectRequirementId && item.projectRequirementName" class="exec-meta__row">
                <SvgIcon icon="mdi:link-variant" class="exec-meta__icon" />
                <span
                  class="exec-meta__text exec-meta__link"
                  role="button"
                  tabindex="0"
                  :title="item.projectRequirementName"
                  @click="goRequirementDetail(item)"
                  @keydown.enter.prevent="goRequirementDetail(item)"
                >
                  {{ item.projectRequirementName }}
                </span>
              </div>
            </div>
            <ElProgress :percentage="item.progressRate" :stroke-width="6" />
          </li>
        </ul>
      </section>
    </div>
    <ElEmpty v-else description="暂无进行中的执行" :image-size="60" />
  </WorkbenchModuleCard>
</template>

<style scoped>
.exec-groups {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.exec-group__head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  padding: 0 2px 6px;
  border-bottom: 1px dashed var(--el-border-color-lighter);
}
.exec-group__icon {
  flex-shrink: 0;
  font-size: 14px;
  color: var(--el-text-color-secondary);
}
.exec-group__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 13px;
  font-weight: 600;
  color: var(--el-text-color-regular);
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: color 0.16s ease;
}
.exec-group__name:hover,
.exec-group__name:focus-visible {
  color: var(--el-color-primary);
  outline: none;
}
.exec-group__count {
  flex-shrink: 0;
  min-width: 22px;
  height: 18px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--el-fill-color);
  color: var(--el-text-color-secondary);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  line-height: 18px;
}
.exec-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.exec-item {
  padding: 9px 10px;
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 6px;
  background: var(--el-fill-color-blank);
  transition:
    border-color 0.16s ease,
    background 0.16s ease;
}
.exec-item:hover {
  border-color: var(--el-color-primary-light-5);
  background: var(--el-color-primary-light-9);
}
.exec-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.exec-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-weight: 600;
  font-size: 13px;
  color: var(--el-text-color-primary);
}
.exec-head__tag {
  flex: 0 0 auto;
}
.exec-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 8px;
}
.exec-meta__row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: 12px;
  color: var(--el-text-color-secondary);
}
.exec-meta__icon {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--el-text-color-placeholder);
}
.exec-meta__text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.exec-meta__link {
  color: var(--el-color-primary);
  cursor: pointer;
}
.exec-meta__link:hover,
.exec-meta__link:focus-visible {
  text-decoration: underline;
  outline: none;
}
</style>
