<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import type { UploadFile, UploadInstance } from 'element-plus';
import { importPerformanceSheetZip, signOffPerformanceSheets } from '@/service/api';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';

defineOptions({ name: 'PerformanceSignOffDialog' });

type OpenMode = 'import' | 'sign-off';
type ActionMode = 'direct' | 'import';

const props = withDefaults(
  defineProps<{
    openMode?: OpenMode;
    employeeIds?: string[] | null;
    initialPeriodMonth?: string;
    teamLabel?: string;
  }>(),
  {
    openMode: 'sign-off',
    employeeIds: undefined,
    initialPeriodMonth: '',
    teamLabel: ''
  }
);

const visible = defineModel<boolean>('visible', { default: false });

const emit = defineEmits<{
  submitted: [];
}>();

const uploadRef = ref<UploadInstance>();
const submitting = ref(false);
const importResult = ref<Api.Performance.Sheet.ImportZipResult | null>(null);

const form = reactive<{
  actionMode: ActionMode;
  periodMonth: string;
  remark: string;
  file: File | null;
  fileName: string;
}>({
  actionMode: 'direct',
  periodMonth: '',
  remark: '',
  file: null,
  fileName: ''
});

const isImportOnly = computed(() => props.openMode === 'import');
const needsZipFile = computed(() => isImportOnly.value || form.actionMode === 'import');
const title = computed(() => (isImportOnly.value ? '导入绩效压缩包' : '一键下签'));
const confirmText = computed(() => (isImportOnly.value ? '开始导入' : '确认执行'));
const teamLabelText = computed(() => {
  if (needsZipFile.value) {
    return '全部下属';
  }

  return props.teamLabel || '当前范围';
});

function resetForm() {
  form.actionMode = 'direct';
  form.periodMonth = props.initialPeriodMonth || '';
  form.remark = '';
  form.file = null;
  form.fileName = '';
  importResult.value = null;
  uploadRef.value?.clearFiles();
}

function handleFileChange(file: UploadFile) {
  const rawFile = file.raw;
  uploadRef.value?.clearFiles();

  if (!rawFile) {
    return;
  }

  if (!rawFile.name.toLowerCase().endsWith('.zip')) {
    window.$message?.warning('请选择 zip 压缩包');
    return;
  }

  form.file = rawFile;
  form.fileName = rawFile.name;
}

async function handleSubmit() {
  if (!form.periodMonth) {
    window.$message?.warning('请选择绩效月份');
    return;
  }

  if (needsZipFile.value && !form.file) {
    window.$message?.warning('请选择绩效压缩包');
    return;
  }

  submitting.value = true;

  if (needsZipFile.value && form.file) {
    const importResponse = await importPerformanceSheetZip({
      file: form.file,
      periodMonth: form.periodMonth,
      employeeIds: props.employeeIds
    });

    if (importResponse.error || !importResponse.data) {
      submitting.value = false;
      return;
    }

    importResult.value = importResponse.data;

    if (isImportOnly.value) {
      submitting.value = false;

      if (importResponse.data.failedCount > 0) {
        window.$message?.warning('导入存在失败项，请处理后重试');
        return;
      }

      window.$message?.success('绩效压缩包导入成功');
      visible.value = false;
      emit('submitted');
      return;
    }

    if (importResponse.data.failedCount > 0) {
      submitting.value = false;
      window.$message?.warning('导入存在失败项，已停止后续下签');
      return;
    }
  }

  if (!isImportOnly.value) {
    const signOffResponse = await signOffPerformanceSheets({
      periodMonth: form.periodMonth,
      employeeIds: props.employeeIds,
      remark: form.remark
    });

    submitting.value = false;

    if (signOffResponse.error) {
      return;
    }

    window.$message?.success('绩效表下签成功');
    visible.value = false;
    emit('submitted');
    return;
  }

  submitting.value = false;
}

watch(visible, isVisible => {
  if (isVisible) {
    resetForm();
  }
});
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    :title="title"
    preset="md"
    append-to-body
    :confirm-text="confirmText"
    :confirm-loading="submitting"
    @confirm="handleSubmit"
  >
    <ElForm label-position="top">
      <ElRow :gutter="16">
        <ElCol v-if="!isImportOnly" :span="24">
          <ElFormItem label="执行方式">
            <ElRadioGroup v-model="form.actionMode">
              <ElRadio value="import">导入绩效压缩包后下签</ElRadio>
              <ElRadio value="direct">直接下签</ElRadio>
            </ElRadioGroup>
          </ElFormItem>
        </ElCol>

        <ElCol :span="12">
          <ElFormItem label="绩效月份" required style="width: 100%">
            <ElDatePicker
              v-model="form.periodMonth"
              class="w-full"
              type="month"
              value-format="YYYY-MM"
              placeholder="请选择绩效月份"
              style="width: 100%"
            />
          </ElFormItem>
        </ElCol>

        <ElCol :span="12">
          <ElFormItem label="适用范围">
            <ElInput :model-value="teamLabelText" readonly />
          </ElFormItem>
        </ElCol>

        <ElCol v-if="needsZipFile" :span="24">
          <ElFormItem label="绩效压缩包" required>
            <div class="performance-sign-off-dialog__upload-row">
              <ElUpload
                ref="uploadRef"
                :auto-upload="false"
                :show-file-list="false"
                accept=".zip"
                :limit="1"
                :on-change="handleFileChange"
              >
                <ElButton plain>选择 zip 文件</ElButton>
              </ElUpload>
              <div
                class="performance-sign-off-dialog__file-name"
                :class="{ 'performance-sign-off-dialog__file-name--placeholder': !form.fileName }"
              >
                {{ form.fileName || '未选择文件' }}
              </div>
            </div>
          </ElFormItem>
        </ElCol>

        <ElCol v-if="!isImportOnly" :span="24">
          <ElFormItem label="备注">
            <ElInput
              v-model="form.remark"
              type="textarea"
              :rows="3"
              maxlength="500"
              show-word-limit
              placeholder="可填写本次下签说明"
            />
          </ElFormItem>
        </ElCol>
      </ElRow>
    </ElForm>

    <ElAlert
      v-if="importResult"
      :type="importResult.failedCount > 0 ? 'warning' : 'success'"
      show-icon
      :closable="false"
      class="mt-12px"
    >
      <template #title>
        导入结果：工作簿 {{ importResult.workbookCount }} 个，工作表 {{ importResult.sheetCount }} 个，成功
        {{ importResult.successCount }} 个，跳过 {{ importResult.skippedCount }} 个，失败
        {{ importResult.failedCount }} 个
      </template>
      <div v-if="importResult.messages.length" class="performance-sign-off-dialog__messages">
        <div v-for="(message, index) in importResult.messages" :key="`${index}-${message}`">
          {{ message }}
        </div>
      </div>
    </ElAlert>
  </BusinessFormDialog>
</template>

<style scoped>
.performance-sign-off-dialog__upload-row {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
}

.performance-sign-off-dialog__file-name {
  min-width: 0;
  height: 36px;
  padding: 0 12px;
  overflow: hidden;
  border: 1px solid var(--el-border-color);
  border-radius: 8px;
  background: var(--el-fill-color-blank);
  color: var(--el-text-color-regular);
  font-size: 13px;
  line-height: 34px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.performance-sign-off-dialog__file-name--placeholder {
  color: var(--el-text-color-placeholder);
}

.performance-sign-off-dialog__messages {
  display: grid;
  gap: 4px;
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.5;
}
</style>
