<script setup lang="ts">
import type { UploadFile } from 'element-plus';

import { computed, ref } from 'vue';

import { EasyFlowPanelModal } from '@easyflow/common-ui';
import { downloadFileFromBlob } from '@easyflow/utils';

import {
  CircleCloseFilled,
  Document,
  Download,
  SuccessFilled,
  UploadFilled,
  WarningFilled,
} from '@element-plus/icons-vue';
import {
  ElButton,
  ElIcon,
  ElMessage,
  ElTable,
  ElTableColumn,
  ElUpload,
} from 'element-plus';

import { api } from '#/api/request';
import { $t } from '#/locales';

const emit = defineEmits(['reload']);

defineExpose({
  openDialog,
});

const dialogVisible = ref(false);
const fileList = ref<any[]>([]);
const currentFile = ref<File | null>(null);
const submitLoading = ref(false);
const downloadLoading = ref(false);
const importResult = ref<any>(null);

const hasErrors = computed(() => (importResult.value?.errorCount || 0) > 0);
const selectedFileName = computed(() => currentFile.value?.name || '');

function openDialog() {
  dialogVisible.value = true;
}

function closeDialog() {
  if (submitLoading.value) {
    return;
  }
  dialogVisible.value = false;
  resetDialog();
}

function resetDialog() {
  fileList.value = [];
  currentFile.value = null;
  submitLoading.value = false;
  downloadLoading.value = false;
  importResult.value = null;
}

function onFileChange(uploadFile: UploadFile) {
  currentFile.value = uploadFile.raw || null;
  fileList.value = uploadFile.raw ? [uploadFile] : [];
  return false;
}

function clearSelectedFile() {
  currentFile.value = null;
  fileList.value = [];
}

async function downloadTemplate() {
  downloadLoading.value = true;
  try {
    const blob = await api.download('/api/v1/sysAccount/downloadImportTemplate');
    downloadFileFromBlob({
      fileName: 'user_import_template.xlsx',
      source: blob,
    });
  } finally {
    downloadLoading.value = false;
  }
}

async function handleImport() {
  if (!currentFile.value) {
    ElMessage.warning($t('sysAccount.importSelectFileRequired'));
    return;
  }
  const formData = new FormData();
  formData.append('file', currentFile.value);
  submitLoading.value = true;
  try {
    const res = await api.postFile('/api/v1/sysAccount/importExcel', formData, {
      timeout: 10 * 60 * 1000,
    });
    if (res.errorCode === 0) {
      importResult.value = res.data;
      ElMessage.success($t('sysAccount.importFinished'));
      emit('reload');
    }
  } finally {
    submitLoading.value = false;
  }
}
</script>

<template>
  <EasyFlowPanelModal
    v-model:open="dialogVisible"
    width="min(960px, 92vw)"
    :title="$t('sysAccount.importTitle')"
    :before-close="closeDialog"
    :show-cancel-button="false"
    :show-confirm-button="false"
  >
    <div class="sys-account-import-dialog">
      <ElUpload
        :file-list="fileList"
        drag
        action="#"
        accept=".xlsx,.xls"
        :auto-upload="false"
        :on-change="onFileChange"
        :limit="1"
        :show-file-list="false"
        class="sys-account-upload-area"
      >
        <div
          class="flex flex-col items-center justify-center gap-2 px-8 py-10 text-center"
        >
          <ElIcon class="text-4xl text-[var(--el-text-color-secondary)]">
            <UploadFilled />
          </ElIcon>
          <div class="text-[15px] font-semibold text-[var(--el-text-color-primary)]">
            {{ $t('sysAccount.importUploadTitle') }}
          </div>
          <div class="text-[13px] text-[var(--el-text-color-secondary)]">
            {{ $t('sysAccount.importUploadDesc') }}
          </div>
        </div>
      </ElUpload>

      <div v-if="selectedFileName" class="selected-file-card">
        <div class="selected-file-main">
          <ElIcon class="selected-file-icon"><Document /></ElIcon>
          <div class="selected-file-name" :title="selectedFileName">
            {{ selectedFileName }}
          </div>
        </div>
        <ElButton
          link
          :icon="CircleCloseFilled"
          class="remove-file-btn"
          @click="clearSelectedFile"
        />
      </div>

      <div v-if="importResult" class="result-wrap">
        <div class="result-head">
          <div class="result-title-wrap">
            <ElIcon
              v-if="hasErrors"
              class="result-state-icon text-[var(--el-color-warning)]"
            >
              <WarningFilled />
            </ElIcon>
            <ElIcon
              v-else
              class="result-state-icon text-[var(--el-color-success)]"
            >
              <SuccessFilled />
            </ElIcon>
            <span class="result-title-text">
              {{ $t('sysAccount.importResultTitle') }}
            </span>
          </div>
        </div>
        <div class="result-stats">
          <div class="stat-item">
            <div class="stat-label">{{ $t('sysAccount.importTotalCount') }}</div>
            <div class="stat-value">{{ importResult.totalCount || 0 }}</div>
          </div>
          <div class="stat-item">
            <div class="stat-label">{{ $t('sysAccount.importSuccessCount') }}</div>
            <div class="stat-value success-text">
              {{ importResult.successCount || 0 }}
            </div>
          </div>
          <div class="stat-item">
            <div class="stat-label">{{ $t('sysAccount.importErrorCount') }}</div>
            <div class="stat-value" :class="hasErrors ? 'danger-text' : ''">
              {{ importResult.errorCount || 0 }}
            </div>
          </div>
        </div>

        <ElTable
          v-if="hasErrors"
          :data="importResult.errorRows || []"
          size="small"
          class="result-error-table"
        >
          <ElTableColumn
            prop="rowNumber"
            :label="$t('sysAccount.importRowNumber')"
            width="96"
          />
          <ElTableColumn
            prop="deptCode"
            :label="$t('sysAccount.importDeptCode')"
            min-width="140"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="loginName"
            :label="$t('sysAccount.loginName')"
            min-width="160"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="reason"
            :label="$t('sysAccount.importReason')"
            min-width="260"
            show-overflow-tooltip
          />
        </ElTable>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <ElButton @click="closeDialog">
          {{ $t('button.cancel') }}
        </ElButton>
        <ElButton
          link
          type="primary"
          :icon="Download"
          :disabled="downloadLoading"
          @click="downloadTemplate"
        >
          {{ $t('sysAccount.downloadTemplate') }}
        </ElButton>
        <ElButton
          type="primary"
          :loading="submitLoading"
          :disabled="submitLoading"
          @click="handleImport"
        >
          {{ $t('button.startImport') }}
        </ElButton>
      </div>
    </template>
  </EasyFlowPanelModal>
</template>

<style scoped>
.sys-account-import-dialog {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sys-account-upload-area :deep(.el-upload-dragger) {
  border-radius: 18px;
  border-color: hsl(var(--border) / 0.68);
  background: hsl(var(--surface) / 0.72);
}

.selected-file-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 1px solid hsl(var(--border) / 0.72);
  border-radius: 16px;
  padding: 12px 16px;
  background: hsl(var(--surface-subtle) / 0.95);
}

.selected-file-main {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.selected-file-icon {
  color: var(--el-color-primary);
}

.selected-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--el-text-color-primary);
}

.result-wrap {
  border: 1px solid hsl(var(--border) / 0.72);
  border-radius: 18px;
  padding: 18px;
  background: hsl(var(--surface-subtle) / 0.94);
}

.result-head {
  margin-bottom: 16px;
}

.result-title-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.result-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.stat-item {
  border-radius: 14px;
  padding: 14px 16px;
  background: hsl(var(--surface) / 0.95);
}

.stat-label {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.stat-value {
  margin-top: 6px;
  font-size: 24px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.success-text {
  color: var(--el-color-success);
}

.danger-text {
  color: var(--el-color-danger);
}

.dialog-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  width: 100%;
}
</style>
