<template>
  <PageShell>
    <div class="evaluation-page">
      <div class="evaluation-card">
        <EvaluationFilter
          :evaluation-name="queryParams.evaluationName || ''"
          :grade="queryParams.grade || ''"
          :position-type="queryParams.positionType || ''"
          :status="queryParams.status || ''"
          :date-range="dateRange"
          :grade-options="gradeOptions"
          :position-type-options="positionTypeOptions"
          @search="handleQuery"
          @reset="resetQuery"
          @update:evaluation-name="queryParams.evaluationName = $event"
          @update:grade="queryParams.grade = $event"
          @update:position-type="queryParams.positionType = $event"
          @update:status="queryParams.status = $event"
          @update:date-range="dateRange = $event"
        />

        <div class="evaluation-toolbar">
          <el-button class="evaluation-toolbar-button" @click="handleExport">导出数据</el-button>
          <el-button class="evaluation-toolbar-button" @click="getList">刷新</el-button>
          <el-button class="evaluation-toolbar-button" @click="handleOpenSyncDialog">同步至员工</el-button>
        </div>

        <EvaluationTable
          :loading="loading"
          :list="evaluationList"
          :total="total"
          :page-num="queryParams.pageNum"
          :page-size="queryParams.pageSize"
          :grade-options="gradeOptions"
          :position-type-options="positionTypeOptions"
          :switch-loading-map="switchLoadingMap"
          :selected-ids="selectedEvaluationIds"
          @update:page-num="queryParams.pageNum = $event"
          @update:page-size="queryParams.pageSize = $event"
          @update:selected-ids="selectedEvaluationIds = $event"
          @pagination="getList"
          @toggle-status="handleToggleStatus"
          @view-apply-list="handleViewApplyList"
        />
      </div>

      <el-dialog v-model="syncDialog.visible" title="同步测评" width="460px" append-to-body>
        <div class="sync-dialog-content">
          <div class="sync-dialog-row">
            <span class="sync-dialog-label">同步员工</span>
            <el-select v-model="syncDialog.employeeIds" multiple collapse-tags collapse-tags-tooltip placeholder="请选择" class="sync-dialog-select" :loading="syncOptionLoading">
              <el-option v-for="item in employeeOptions" :key="item.id" :label="item.label" :value="item.id" />
            </el-select>
          </div>
        </div>
        <template #footer>
          <div class="sync-dialog-footer">
            <el-button @click="syncDialog.visible = false">取消</el-button>
            <el-button type="primary" :loading="syncLoading" @click="handleConfirmSync">确定</el-button>
          </div>
        </template>
      </el-dialog>
    </div>
  </PageShell>
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, onMounted, reactive, ref, type ComponentInternalInstance } from 'vue';
import { useRouter } from 'vue-router';
import PageShell from '@/components/PageShell/index.vue';
import { getEvaluationParticipantStats, getEvaluationSyncEmployeeOptions, listEvaluation, syncEvaluationToEmployees, updateEvaluationStatus } from '@/api/main/evaluation';
import { EvaluationSyncEmployeeOption, MainExamEvaluationQuery, MainExamEvaluationVO } from '@/api/main/evaluation/types';
import { getDicts } from '@/api/system/dict/data';
import type { DictDataVO } from '@/api/system/dict/data/types';
import EvaluationFilter from './components/EvaluationFilter.vue';
import EvaluationTable from './components/EvaluationTable.vue';

type FilterOption = { label: string; value: string };
type SyncEmployeeOption = EvaluationSyncEmployeeOption & { label: string };

const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const modal = proxy?.$modal as any;
const loading = ref(false);
const total = ref(0);
const evaluationList = ref<MainExamEvaluationVO[]>([]);
const dateRange = ref<[string, string] | []>([]);
const gradeOptions = ref<FilterOption[]>([]);
const positionTypeOptions = ref<FilterOption[]>([]);
const employeeOptions = ref<SyncEmployeeOption[]>([]);
const syncLoading = ref(false);
const syncOptionLoading = ref(false);
const selectedEvaluationIds = ref<Array<string | number>>([]);
const switchLoadingMap = reactive<Record<string, boolean>>({});
const syncDialog = reactive({
  visible: false,
  employeeIds: [] as Array<string | number>
});

const queryParams = reactive<MainExamEvaluationQuery>({
  pageNum: 1,
  pageSize: 10,
  evaluationName: '',
  grade: '',
  positionType: '',
  status: ''
});

const normalizedQuery = computed(() => ({
  ...queryParams,
  params: {
    beginTime: dateRange.value?.[0] || undefined,
    endTime: dateRange.value?.[1] || undefined
  }
}));

const mapDictOptions = (list: DictDataVO[] = []): FilterOption[] =>
  list.map((item) => ({
    label: item.dictLabel,
    value: item.dictValue
  }));

const mergeFieldOptions = (baseOptions: FilterOption[], rows: MainExamEvaluationVO[], field: 'grade' | 'positionType') => {
  const optionMap = new Map(baseOptions.map((item) => [item.value, item]));
  rows.forEach((item) => {
    const value = item[field];
    if (value && !optionMap.has(value)) {
      optionMap.set(value, { label: value, value });
    }
  });
  return Array.from(optionMap.values());
};

const loadFilterOptions = async () => {
  const [gradeRes, positionTypeRes] = await Promise.allSettled([getDicts('main_position_level'), getDicts('main_position_type')]);

  if (gradeRes.status === 'fulfilled') {
    gradeOptions.value = mapDictOptions(gradeRes.value.data || []);
  }
  if (positionTypeRes.status === 'fulfilled') {
    positionTypeOptions.value = mapDictOptions(positionTypeRes.value.data || []);
  }
};

const loadParticipantStats = async (rows: MainExamEvaluationVO[]) => {
  const ids = rows.map((item) => item.id).filter((id): id is string | number => id !== undefined && id !== null);
  if (!ids.length) {
    return rows.map((item) => ({
      ...item,
      participantCount: 0,
      totalCount: 0
    }));
  }
  const res = await getEvaluationParticipantStats(ids);
  const statsMap = res.data || {};
  return rows.map((item) => {
    const stats = statsMap[String(item.id)] || statsMap[item.id as keyof typeof statsMap];
    return {
      ...item,
      participantCount: Number(stats?.participantCount || 0),
      totalCount: Number(stats?.totalCount || 0)
    };
  });
};

const loadSyncEmployeeOptions = async () => {
  syncOptionLoading.value = true;
  try {
    const res = await getEvaluationSyncEmployeeOptions();
    const rows = res.data || [];
    employeeOptions.value = rows.map((item) => ({
      ...item,
      label: [item.name, item.mobile, item.studentNo].filter(Boolean).join(' / ')
    }));
  } finally {
    syncOptionLoading.value = false;
  }
};

const getList = async () => {
  loading.value = true;
  try {
    const res = await listEvaluation(normalizedQuery.value);
    evaluationList.value = await loadParticipantStats(res.rows || []);
    total.value = res.total || 0;
    gradeOptions.value = mergeFieldOptions(gradeOptions.value, evaluationList.value, 'grade');
    positionTypeOptions.value = mergeFieldOptions(positionTypeOptions.value, evaluationList.value, 'positionType');
  } finally {
    loading.value = false;
  }
};

const handleQuery = () => {
  queryParams.pageNum = 1;
  getList();
};

const resetQuery = () => {
  queryParams.evaluationName = '';
  queryParams.grade = '';
  queryParams.positionId = '';
  queryParams.positionType = '';
  queryParams.status = '';
  dateRange.value = [];
  queryParams.pageNum = 1;
  queryParams.pageSize = 10;
  getList();
};

const handleToggleStatus = async (row: MainExamEvaluationVO, value: boolean | string | number) => {
  const rowKey = String(row.id);
  try {
    switchLoadingMap[rowKey] = true;
    await updateEvaluationStatus(row.id, value ? '1' : '2');
    modal?.msgSuccess('状态更新成功');
    await getList();
  } finally {
    switchLoadingMap[rowKey] = false;
  }
};

const handleViewApplyList = (row: MainExamEvaluationVO) => {
  router.push({
    path: '/evaluation/apply-list',
    query: {
      evaluationId: String(row.id),
      evaluationName: row.evaluationName || '',
      backPath: '/evaluation'
    }
  });
};

const handleExport = () => {
  proxy?.download(
    '/main/examEvaluation/export',
    {
      ...normalizedQuery.value
    },
    `evaluation_${new Date().getTime()}.xlsx`
  );
};

const handleOpenSyncDialog = () => {
  if (!selectedEvaluationIds.value.length) {
    modal?.msgWarning('请先勾选测评');
    return;
  }
  syncDialog.employeeIds = [];
  syncDialog.visible = true;
  if (!employeeOptions.value.length) {
    loadSyncEmployeeOptions();
  }
};

const handleConfirmSync = async () => {
  if (!syncDialog.employeeIds.length) {
    modal?.msgWarning('请选择员工');
    return;
  }
  syncLoading.value = true;
  try {
    await syncEvaluationToEmployees({
      evaluationIds: selectedEvaluationIds.value,
      studentIds: syncDialog.employeeIds
    });
    syncDialog.visible = false;
    selectedEvaluationIds.value = [];
    modal?.msgSuccess('同步成功');
    await getList();
  } finally {
    syncLoading.value = false;
  }
};

onMounted(() => {
  loadFilterOptions().finally(() => {
    getList();
  });
});
</script>

<style scoped lang="scss">
.evaluation-page {
  min-height: 100%;
}

.evaluation-card {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 180px);
  padding: 16px;
  border-radius: 8px;
  background: #fff;
  box-sizing: border-box;
}

.evaluation-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-bottom: 16px;
}

.evaluation-toolbar-button {
  color: #303133;
  background: #fff;
  border-color: #303133;
}

.evaluation-toolbar-button:hover,
.evaluation-toolbar-button:focus {
  color: #303133;
  background: #fff;
  border-color: #303133;
}

.sync-dialog-content {
  padding: 10px 4px 24px;
}

.sync-dialog-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.sync-dialog-label {
  width: 56px;
  color: #303133;
  flex-shrink: 0;
}

.sync-dialog-select {
  flex: 1;
}

.sync-dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>
