<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import type { UploadFile, UploadFiles, UploadRawFile } from 'element-plus';
import dayjs from 'dayjs';
import {
  activatePerformanceTemplate,
  batchImportPerformanceTemplates,
  fetchPerformanceTemplatePage,
  uploadFile,
  uploadSinglePerformanceTemplate
} from '@/service/api';
import { useAuth } from '@/hooks/business/auth';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import { PerformancePermission, formatDateTime } from './performance-shared';

defineOptions({ name: 'PerformanceTemplateDialog' });

interface Props {
  scope?: Api.Performance.Template.UploadScope | null;
}

const props = withDefaults(defineProps<Props>(), {
  scope: null
});

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

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

const { hasAuth } = useAuth();
const canQueryTemplate = computed(() => hasAuth(PerformancePermission.TemplateQuery));
const canUpdateTemplate = computed(() => hasAuth(PerformancePermission.TemplateUpdate));
const employeeOptions = computed(() => props.scope?.employees || []);
const isOrgLeader = computed(() => Boolean(props.scope?.orgLeader));
const currentYear = dayjs().year();

const searchParams = reactive<Api.Performance.Template.SearchParams>({
  pageNo: 1,
  pageSize: 10,
  templateName: undefined,
  employeeId: undefined,
  employeeName: undefined,
  templateYear: undefined,
  uploadUserName: undefined,
  activeFlag: undefined
});

const singleForm = reactive({
  employeeId: '',
  templateName: '',
  templateYear: currentYear,
  remark: '',
  file: null as UploadRawFile | null
});

const batchForm = reactive({
  templateYear: currentYear,
  remark: '',
  files: [] as UploadRawFile[]
});

const tableData = ref<Api.Performance.Template.Template[]>([]);
const total = ref(0);
const loading = ref(false);
const singleUploading = ref(false);
const batchUploading = ref(false);
const activatingId = ref('');

const singleFileName = computed(() => singleForm.file?.name || '');
const batchFileNames = computed(() => batchForm.files.map(file => file.name));

function resetSingleForm() {
  Object.assign(singleForm, {
    employeeId: '',
    templateName: '',
    templateYear: currentYear,
    remark: '',
    file: null
  });
}

function resetBatchForm() {
  Object.assign(batchForm, {
    templateYear: currentYear,
    remark: '',
    files: []
  });
}

async function loadTemplatePage(page = searchParams.pageNo ?? 1) {
  if (!canQueryTemplate.value) return;

  searchParams.pageNo = page;
  loading.value = true;
  const { error, data } = await fetchPerformanceTemplatePage(searchParams);
  loading.value = false;

  if (error || !data) {
    tableData.value = [];
    total.value = 0;
    return;
  }

  tableData.value = data.list;
  total.value = data.total;
}

function handleSearch() {
  loadTemplatePage(1);
}

function handleReset() {
  Object.assign(searchParams, {
    pageNo: 1,
    pageSize: 10,
    templateName: undefined,
    employeeId: undefined,
    employeeName: undefined,
    templateYear: undefined,
    uploadUserName: undefined,
    activeFlag: undefined
  });
  loadTemplatePage(1);
}

function handleSingleFileChange(file: UploadFile) {
  const rawFile = file.raw;
  if (!rawFile) return;

  singleForm.file = rawFile;
  if (!singleForm.templateName) {
    singleForm.templateName = rawFile.name.replace(/\.[^.]+$/u, '');
  }
}

function handleBatchFileChange(_file: UploadFile, files: UploadFiles) {
  batchForm.files = files.reduce<UploadRawFile[]>((list, item) => {
    if (item.raw) {
      list.push(item.raw);
    }
    return list;
  }, []);
}

async function uploadSourceFile(file: File) {
  return uploadFile(file, 'performance/template-sources');
}

async function handleSingleUpload() {
  if (!canUpdateTemplate.value || !isOrgLeader.value) return;

  if (!singleForm.employeeId) {
    window.$message?.warning('请选择员工');
    return;
  }
  if (!singleForm.templateName.trim()) {
    window.$message?.warning('请输入模板名称');
    return;
  }
  if (!singleForm.file) {
    window.$message?.warning('请选择 Excel 文件');
    return;
  }

  singleUploading.value = true;
  const fileResult = await uploadSourceFile(singleForm.file);
  if (fileResult.error || !fileResult.data) {
    singleUploading.value = false;
    return;
  }

  const result = await uploadSinglePerformanceTemplate({
    employeeId: singleForm.employeeId,
    templateName: singleForm.templateName.trim(),
    templateYear: singleForm.templateYear || undefined,
    sourceFileId: fileResult.data.id,
    sourceFileName: singleForm.file.name,
    remark: singleForm.remark.trim() || undefined
  });
  singleUploading.value = false;

  if (result.error) return;

  window.$message?.success('绩效模板上传成功');
  resetSingleForm();
  await loadTemplatePage(1);
  emit('updated');
}

async function handleBatchImport() {
  if (!canUpdateTemplate.value || !isOrgLeader.value) return;

  if (!batchForm.files.length) {
    window.$message?.warning('请选择要导入的 Excel 文件');
    return;
  }

  batchUploading.value = true;
  const uploadResults = await Promise.all(
    batchForm.files.map(async file => {
      const fileResult = await uploadSourceFile(file);
      return { file, fileResult };
    })
  );

  const failedUpload = uploadResults.find(item => item.fileResult.error || !item.fileResult.data);
  if (failedUpload) {
    batchUploading.value = false;
    return;
  }

  const files: Api.Performance.Template.BatchImportFileItem[] = uploadResults.map(item => ({
    sourceFileId: item.fileResult.data!.id,
    sourceFileName: item.file.name
  }));

  const result = await batchImportPerformanceTemplates({
    templateYear: batchForm.templateYear || undefined,
    remark: batchForm.remark.trim() || undefined,
    files
  });
  batchUploading.value = false;

  if (result.error || !result.data) return;

  await showBatchImportResult(result.data);
  resetBatchForm();
  await loadTemplatePage(1);
  emit('updated');
}

async function showBatchImportResult(result: Api.Performance.Template.BatchImportResult) {
  const lines = [`成功 ${result.successCount} 条`, `失败 ${result.failureCount} 条`];

  result.failures.slice(0, 20).forEach(item => {
    const sheetName = item.sheetName ? ` / ${item.sheetName}` : '';
    lines.push(`${item.sourceFileName}${sheetName}：${item.reason}`);
  });

  if (result.failures.length > 20) {
    lines.push(`其余 ${result.failures.length - 20} 条失败明细请查看后端日志或再次筛查源文件`);
  }

  await ElMessageBox.alert(lines.join('\n'), '批量导入结果', {
    confirmButtonText: '知道了'
  });
}

async function handleActivate(row: Api.Performance.Template.Template) {
  if (!canUpdateTemplate.value) return;

  activatingId.value = row.id;
  const { error } = await activatePerformanceTemplate(row.id);
  activatingId.value = '';

  if (error) return;

  window.$message?.success('绩效模板已启用');
  await loadTemplatePage(searchParams.pageNo ?? 1);
  emit('updated');
}

watch(visible, isVisible => {
  if (!isVisible) return;

  if (!singleForm.employeeId && employeeOptions.value.length === 1) {
    singleForm.employeeId = employeeOptions.value[0].employeeId;
  }

  if (canQueryTemplate.value) {
    loadTemplatePage(1);
  }
});
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    title="绩效模板"
    preset="lg"
    append-to-body
    :show-footer="false"
    max-body-height="78vh"
  >
    <div class="performance-template-dialog">
      <ElAlert
        v-if="canUpdateTemplate && !isOrgLeader"
        type="warning"
        :closable="false"
        show-icon
        title="当前账号不是组织负责人，不能上传绩效模板"
      />

      <div v-if="canUpdateTemplate && isOrgLeader" class="performance-template-dialog__upload-sections">
        <ElCard shadow="never">
          <template #header>
            <div class="performance-template-dialog__section-title">单人上传</div>
          </template>

          <ElForm :model="singleForm" label-position="top" class="performance-template-dialog__form">
            <div class="performance-template-dialog__grid">
              <ElFormItem label="员工">
                <ElSelect v-model="singleForm.employeeId" filterable placeholder="请选择员工">
                  <ElOption
                    v-for="item in employeeOptions"
                    :key="item.employeeId"
                    :label="
                      item.employeeDeptName ? `${item.employeeName}（${item.employeeDeptName}）` : item.employeeName
                    "
                    :value="item.employeeId"
                  />
                </ElSelect>
              </ElFormItem>

              <ElFormItem label="模板名称">
                <ElInput v-model="singleForm.templateName" placeholder="请输入模板名称" />
              </ElFormItem>

              <ElFormItem label="模板年份">
                <ElInputNumber v-model="singleForm.templateYear" :min="2000" :max="2100" controls-position="right" />
              </ElFormItem>

              <ElFormItem label="Excel 文件" class="performance-template-dialog__full">
                <div class="performance-template-dialog__file-line">
                  <ElUpload
                    :auto-upload="false"
                    :show-file-list="false"
                    :limit="1"
                    accept=".xlsx"
                    @change="handleSingleFileChange"
                  >
                    <ElButton>
                      <template #icon>
                        <icon-mdi-upload class="text-icon" />
                      </template>
                      选择文件
                    </ElButton>
                  </ElUpload>
                  <span class="performance-template-dialog__file-text">
                    {{ singleFileName || '未选择文件，仅支持 .xlsx' }}
                  </span>
                </div>
              </ElFormItem>

              <ElFormItem label="备注" class="performance-template-dialog__full">
                <ElInput v-model="singleForm.remark" type="textarea" :rows="2" maxlength="500" show-word-limit />
              </ElFormItem>
            </div>

            <div class="performance-template-dialog__actions">
              <ElButton type="primary" :loading="singleUploading" @click="handleSingleUpload">上传模板</ElButton>
            </div>
          </ElForm>
        </ElCard>

        <ElCard shadow="never">
          <template #header>
            <div class="performance-template-dialog__section-title">批量导入</div>
          </template>

          <ElForm :model="batchForm" label-position="top" class="performance-template-dialog__form">
            <div class="performance-template-dialog__grid">
              <ElFormItem label="模板年份">
                <ElInputNumber v-model="batchForm.templateYear" :min="2000" :max="2100" controls-position="right" />
              </ElFormItem>

              <ElFormItem label="Excel 文件" class="performance-template-dialog__full">
                <div class="performance-template-dialog__file-line">
                  <ElUpload
                    :auto-upload="false"
                    :show-file-list="false"
                    multiple
                    accept=".xlsx"
                    @change="handleBatchFileChange"
                  >
                    <ElButton>
                      <template #icon>
                        <icon-mdi-upload class="text-icon" />
                      </template>
                      选择多个文件
                    </ElButton>
                  </ElUpload>
                  <div class="performance-template-dialog__batch-files">
                    <span v-if="!batchFileNames.length" class="performance-template-dialog__file-text">
                      未选择文件，仅支持 .xlsx
                    </span>
                    <ElTag v-for="name in batchFileNames" :key="name" effect="plain">{{ name }}</ElTag>
                  </div>
                </div>
              </ElFormItem>

              <ElFormItem label="备注" class="performance-template-dialog__full">
                <ElInput v-model="batchForm.remark" type="textarea" :rows="2" maxlength="500" show-word-limit />
              </ElFormItem>
            </div>

            <div class="performance-template-dialog__actions">
              <ElButton type="primary" :loading="batchUploading" @click="handleBatchImport">批量导入</ElButton>
            </div>
          </ElForm>
        </ElCard>
      </div>

      <ElCard v-if="canQueryTemplate" shadow="never">
        <template #header>
          <div class="performance-template-dialog__section-title">模板列表</div>
        </template>

        <ElForm :model="searchParams" inline label-position="top" class="performance-template-dialog__search">
          <ElFormItem label="模板名称">
            <ElInput v-model="searchParams.templateName" clearable placeholder="请输入模板名称" />
          </ElFormItem>
          <ElFormItem label="员工姓名">
            <ElInput v-model="searchParams.employeeName" clearable placeholder="请输入员工姓名" />
          </ElFormItem>
          <ElFormItem label="模板年份">
            <ElInputNumber
              v-model="searchParams.templateYear"
              :min="2000"
              :max="2100"
              controls-position="right"
              placeholder="年份"
            />
          </ElFormItem>
          <ElFormItem label="上传人">
            <ElInput v-model="searchParams.uploadUserName" clearable placeholder="请输入上传人" />
          </ElFormItem>
          <ElFormItem label="状态">
            <ElSelect v-model="searchParams.activeFlag" clearable placeholder="全部">
              <ElOption :value="true" label="已启用" />
              <ElOption :value="false" label="未启用" />
            </ElSelect>
          </ElFormItem>
          <ElFormItem class="performance-template-dialog__search-actions">
            <ElButton type="primary" @click="handleSearch">查询</ElButton>
            <ElButton @click="handleReset">重置</ElButton>
          </ElFormItem>
        </ElForm>

        <ElTable v-loading="loading" :data="tableData" border>
          <ElTableColumn type="index" label="序号" width="64" />
          <ElTableColumn prop="templateName" label="模板名称" min-width="180" show-overflow-tooltip />
          <ElTableColumn prop="employeeName" label="员工" min-width="110" show-overflow-tooltip />
          <ElTableColumn prop="employeeDeptName" label="部门" min-width="120" show-overflow-tooltip />
          <ElTableColumn prop="templateYear" label="年份" width="90" />
          <ElTableColumn label="状态" width="100" align="center">
            <template #default="{ row }">
              <ElTag :type="row.activeFlag ? 'success' : 'info'">{{ row.activeFlag ? '已启用' : '未启用' }}</ElTag>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="uploadUserName" label="上传人" width="110" />
          <ElTableColumn label="上传时间" width="180">
            <template #default="{ row }">
              {{ formatDateTime(row.uploadTime) }}
            </template>
          </ElTableColumn>
          <ElTableColumn label="操作" width="100" fixed="right" align="center">
            <template #default="{ row }">
              <ElButton
                v-if="canUpdateTemplate"
                link
                type="primary"
                :disabled="row.activeFlag || activatingId === row.id"
                @click="handleActivate(row)"
              >
                启用
              </ElButton>
            </template>
          </ElTableColumn>
        </ElTable>

        <div class="performance-template-dialog__pagination">
          <ElPagination
            :current-page="searchParams.pageNo || 1"
            :page-size="searchParams.pageSize || 10"
            :total="total"
            layout="total, prev, pager, next, sizes"
            @current-change="loadTemplatePage"
            @size-change="
              size => {
                searchParams.pageSize = size;
                loadTemplatePage(1);
              }
            "
          />
        </div>
      </ElCard>

      <ElEmpty
        v-if="!canQueryTemplate && !canUpdateTemplate"
        :image-size="80"
        description="当前账号没有绩效模板相关权限"
      />
    </div>
  </BusinessFormDialog>
</template>

<style scoped lang="scss">
.performance-template-dialog {
  display: grid;
  gap: 16px;
}

.performance-template-dialog__upload-sections {
  display: grid;
  gap: 16px;
}

.performance-template-dialog__section-title {
  font-size: 16px;
  font-weight: 600;
}

.performance-template-dialog__form {
  display: grid;
  gap: 12px;
}

.performance-template-dialog__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.performance-template-dialog__full {
  grid-column: 1 / -1;
}

.performance-template-dialog__file-line {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: center;
}

.performance-template-dialog__file-text {
  color: var(--el-text-color-secondary);
  word-break: break-all;
}

.performance-template-dialog__batch-files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.performance-template-dialog__actions {
  display: flex;
  justify-content: flex-end;
}

.performance-template-dialog__search {
  margin-bottom: 8px;
}

.performance-template-dialog__search-actions {
  align-self: end;
}

.performance-template-dialog__pagination {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}

@media (max-width: 960px) {
  .performance-template-dialog__grid {
    grid-template-columns: 1fr;
  }

  .performance-template-dialog__full {
    grid-column: auto;
  }

  .performance-template-dialog__file-line {
    grid-template-columns: 1fr;
  }
}
</style>
