<script setup lang="ts">
import { computed, toRef } from 'vue';
import type { PaginationProps } from 'element-plus';
import { formatDateRange, formatDateTime, getTaskStatusName, getTaskStatusTagType } from '../shared';
import { useTaskActions } from '../composables/use-task-actions';

defineOptions({ name: 'ProjectExecutionTaskTableView' });

interface Props {
  data: Api.Project.ProjectTask[];
  loading: boolean;
  pagination: Partial<PaginationProps & Record<string, any>>;
}

interface Emits {
  (e: 'detail', row: Api.Project.ProjectTask): void;
  (e: 'edit', row: Api.Project.ProjectTask): void;
  (e: 'report', row: Api.Project.ProjectTask): void;
  (e: 'delete', row: Api.Project.ProjectTask): void;
  (
    e: 'status-action',
    row: Api.Project.ProjectTask,
    action: Api.Project.LifecycleAction<Api.Project.ProjectTaskActionCode> | null
  ): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

const { createActions } = useTaskActions(toRef(props, 'data'), {
  edit: row => emit('edit', row),
  report: row => emit('report', row),
  remove: row => emit('delete', row),
  statusAction: (row, action) => emit('status-action', row, action)
});

const paginationVisible = computed(() => Boolean(props.pagination.total));

const taskTitleMap = computed(() => {
  const map = new Map<string, string>();
  props.data.forEach(item => {
    if (item.id && item.taskTitle) {
      map.set(item.id, item.taskTitle);
    }
  });
  return map;
});

function getParentTaskLabel(parentTaskId: string | null) {
  if (!parentTaskId) {
    return '--';
  }
  return taskTitleMap.value.get(parentTaskId) || '--';
}

function handlePageChange(page: number) {
  props.pagination['current-change']?.(page);
}

function handleSizeChange(pageSize: number) {
  props.pagination['size-change']?.(pageSize);
}
</script>

<template>
  <ElCard class="task-table-card" body-class="business-table-card-body">
    <div class="flex-1">
      <ElTable v-loading="loading" :data="data" height="100%" border row-key="id" highlight-current-row>
        <ElTableColumn type="index" label="序号" width="64" align="center" />
        <ElTableColumn label="任务名称" min-width="220" show-overflow-tooltip>
          <template #default="{ row }">
            <span
              v-if="row.taskTitle"
              class="task-table-title"
              role="button"
              tabindex="0"
              @click.stop="emit('detail', row)"
              @keydown.enter.prevent="emit('detail', row)"
            >
              {{ row.taskTitle }}
            </span>
            <span v-else>--</span>
          </template>
        </ElTableColumn>
        <ElTableColumn label="状态" width="100" align="center">
          <template #default="{ row }">
            <ElTag effect="plain" :type="getTaskStatusTagType(row.statusCode)">{{ getTaskStatusName(row) }}</ElTag>
          </template>
        </ElTableColumn>
        <ElTableColumn label="负责人" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">{{ row.ownerNickname || row.ownerId || '--' }}</template>
        </ElTableColumn>
        <ElTableColumn label="父任务" min-width="140" show-overflow-tooltip>
          <template #default="{ row }">{{ getParentTaskLabel(row.parentTaskId) }}</template>
        </ElTableColumn>
        <ElTableColumn label="进度" width="160">
          <template #default="{ row }">
            <div class="task-table-progress">
              <ElProgress :percentage="row.progressRate" :stroke-width="18" text-inside />
            </div>
          </template>
        </ElTableColumn>
        <ElTableColumn label="计划周期" min-width="190" show-overflow-tooltip>
          <template #default="{ row }">{{ formatDateRange(row.plannedStartDate, row.plannedEndDate) }}</template>
        </ElTableColumn>
        <ElTableColumn label="实际周期" min-width="190" show-overflow-tooltip>
          <template #default="{ row }">{{ formatDateRange(row.actualStartDate, row.actualEndDate) }}</template>
        </ElTableColumn>
        <ElTableColumn label="最近更新" width="170">
          <template #default="{ row }">{{ formatDateTime(row.updateTime) }}</template>
        </ElTableColumn>
        <ElTableColumn label="操作" width="210" fixed="right" align="center" class-name="task-operate-column">
          <template #default="{ row }">
            <div class="task-action-cell" @click.stop>
              <ElTooltip v-for="action in createActions(row)" :key="action.key" :content="action.tooltip">
                <ElButton link :type="action.type" class="task-action-btn" @click="action.onClick()">
                  <component :is="action.icon" class="text-15px" />
                </ElButton>
              </ElTooltip>
            </div>
          </template>
        </ElTableColumn>
      </ElTable>
    </div>

    <div v-if="paginationVisible" class="task-table-pagination">
      <ElPagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        v-bind="pagination"
        @current-change="handlePageChange"
        @size-change="handleSizeChange"
      />
    </div>
  </ElCard>
</template>

<style scoped lang="scss">
.task-table-card {
  min-height: 0;
  flex: 1;
}

.task-table-title {
  color: var(--el-color-primary);
  cursor: pointer;

  &:hover {
    text-decoration: underline;
  }
}

.task-table-progress {
  padding: 0 8px;
}

.task-action-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.task-action-cell :deep(.el-button + .el-button) {
  margin-left: 0;
}

:deep(.task-action-btn) {
  padding: 3px;
  min-width: auto;
  height: auto;
  line-height: 1;
}

.task-table-pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}

:deep(.el-table__row.current-row > td.el-table__cell) {
  background-color: rgb(64 158 255 / 8%);
}

:deep(.task-operate-column) {
  background-color: var(--el-bg-color, #ffffff) !important;
}

:deep(.el-table__row.current-row) {
  .task-operate-column {
    background-color: var(--el-bg-color, #ffffff) !important;
  }

  td.el-table__cell.is-fixed-right {
    background-color: var(--el-bg-color, #ffffff) !important;
  }
}
</style>
