<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';

interface ImportErrorDetail {
  fieldName?: string;
  fieldValue?: null | string;
  reason?: string;
}

interface ImportErrorRow {
  rowNumber?: number;
  deptName?: string;
  loginName?: string;
  nickname?: string;
  roleNames?: string;
  positionNames?: string;
  details?: ImportErrorDetail[];
}

interface ImportResult {
  totalCount?: number;
  successCount?: number;
  errorCount?: number;
  errorRows?: ImportErrorRow[];
}

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<ImportResult | null>(null);

const hasErrors = computed(() => (importResult.value?.errorCount || 0) > 0);
const hasSuccess = computed(() => (importResult.value?.successCount || 0) > 0);
const selectedFileName = computed(() => currentFile.value?.name || '');
const errorDetailRows = computed(() => {
  return (importResult.value?.errorRows || []).flatMap((row) =>
    (row.details || []).map((detail) => ({
      rowNumber: row.rowNumber,
      loginName: row.loginName,
      fieldName: detail.fieldName,
      fieldValue: detail.fieldValue,
      reason: detail.reason,
    })),
  );
});

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;
      const successCount = res.data?.successCount || 0;
      const errorCount = res.data?.errorCount || 0;
      if (errorCount === 0) {
        ElMessage.success($t('sysAccount.importFinished'));
      } else if (successCount === 0) {
        ElMessage.error($t('sysAccount.importAllFailed'));
      } else {
        ElMessage.warning(
          $t('sysAccount.importPartialSuccess', { successCount, errorCount }),
        );
      }
      if (successCount > 0) {
        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 class="import-guide-card">
        <div class="guide-title">{{ $t('sysAccount.importGuideTitle') }}</div>
        <div class="guide-text">{{ $t('sysAccount.importGuideNameRule') }}</div>
        <div class="guide-text">{{ $t('sysAccount.importGuideRequired') }}</div>
        <div class="guide-text">
          {{ $t('sysAccount.importGuideMultiValue') }}
        </div>
      </div>

      <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 class="result-summary">
            <span v-if="hasErrors && hasSuccess">
              {{
                $t('sysAccount.importPartialSuccess', {
                  successCount: importResult?.successCount || 0,
                  errorCount: importResult?.errorCount || 0,
                })
              }}
            </span>
            <span v-else-if="hasErrors">
              {{ $t('sysAccount.importAllFailed') }}
            </span>
            <span v-else>
              {{ $t('sysAccount.importFinished') }}
            </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="errorDetailRows"
          size="small"
          class="result-error-table"
        >
          <ElTableColumn
            prop="rowNumber"
            :label="$t('sysAccount.importRowNumber')"
            width="96"
          />
          <ElTableColumn
            prop="loginName"
            :label="$t('sysAccount.loginName')"
            min-width="140"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="fieldName"
            :label="$t('sysAccount.importFieldName')"
            min-width="140"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="fieldValue"
            :label="$t('sysAccount.importFieldValue')"
            min-width="180"
            show-overflow-tooltip
          >
            <template #default="{ row }">
              {{ row.fieldValue || '-' }}
            </template>
          </ElTableColumn>
          <ElTableColumn
            prop="reason"
            :label="$t('sysAccount.importReason')"
            min-width="320"
          >
            <template #default="{ row }">
              <div class="error-reason-cell">{{ row.reason }}</div>
            </template>
          </ElTableColumn>
        </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) {
  background: hsl(var(--surface) / 72%);
  border-color: hsl(var(--border) / 68%);
  border-radius: 18px;
}

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

.import-guide-card {
  padding: 14px 16px;
  background: hsl(var(--surface-subtle) / 94%);
  border: 1px solid hsl(var(--border) / 72%);
  border-radius: 16px;
}

.guide-title {
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.guide-text {
  font-size: 12px;
  line-height: 1.6;
  color: var(--el-text-color-secondary);
}

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

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

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

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

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

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

.result-summary {
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--el-text-color-secondary);
}

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

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

.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);
}

.error-reason-cell {
  word-break: normal;
  overflow-wrap: anywhere;
  white-space: normal;
}

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