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

import { computed, ref, watch } from 'vue';

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

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

import { api } from '#/api/request';
import { buildKnowledgePath } from '#/views/ai/documentCollection/share-path';

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false,
  },
  knowledgeId: {
    type: String,
    required: true,
  },
  requestClient: {
    type: Object as any,
    default: () => api,
  },
  endpointPrefix: {
    type: String,
    default: '',
  },
});

const emit = defineEmits(['update:modelValue', 'success']);

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

watch(
  () => props.modelValue,
  (visible) => {
    if (!visible) {
      resetDialog();
    }
  },
);

const closeDialog = () => {
  emit('update:modelValue', false);
};

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

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

const onFileRemove = () => {
  currentFile.value = null;
};

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

const downloadTemplate = async () => {
  if (!props.knowledgeId) {
    ElMessage.warning($t('documentCollection.faq.collectionRequired'));
    return;
  }
  downloadLoading.value = true;
  try {
    const blob = await props.requestClient.download(
      buildKnowledgePath(
        props.endpointPrefix,
        `/api/v1/faqItem/downloadImportTemplate?collectionId=${props.knowledgeId}`,
      ),
    );
    downloadFileFromBlob({
      fileName: 'faq_import_template.xlsx',
      source: blob,
    });
  } finally {
    downloadLoading.value = false;
  }
};

const handleImport = async () => {
  if (!currentFile.value) {
    ElMessage.warning($t('documentCollection.faq.import.selectFileRequired'));
    return;
  }
  const formData = new FormData();
  formData.append('file', currentFile.value);
  formData.append('collectionId', props.knowledgeId);
  submitLoading.value = true;
  try {
    const res = await props.requestClient.postFile(
      buildKnowledgePath(props.endpointPrefix, '/api/v1/faqItem/importExcel'),
      formData,
      {
        timeout: 10 * 60 * 1000,
      },
    );
    if (res.errorCode === 0) {
      importResult.value = res.data;
      ElMessage.success($t('documentCollection.faq.import.importFinished'));
      emit('success');
    }
  } finally {
    submitLoading.value = false;
  }
};
</script>

<template>
  <EasyFlowPanelModal
    :model-value="modelValue"
    width="min(980px, 92vw)"
    :title="$t('documentCollection.faq.import.title')"
    :close-on-click-modal="true"
    :show-cancel-button="false"
    :show-confirm-button="false"
    @update:model-value="emit('update:modelValue', $event)"
    @cancel="closeDialog"
  >
    <div class="faq-import-dialog">
      <ElUpload
        :file-list="fileList"
        drag
        action="#"
        accept=".xlsx,.xls"
        :auto-upload="false"
        :on-change="onFileChange"
        :on-remove="onFileRemove"
        :limit="1"
        :show-file-list="false"
        class="faq-upload-area"
      >
        <div
          class="upload-box flex flex-col items-center justify-center p-8 text-center"
        >
          <ElIcon class="mb-4 text-4xl text-gray-400"><UploadFilled /></ElIcon>
          <div
            class="upload-title mb-2 text-[15px] font-semibold text-[var(--el-text-color-primary)]"
          >
            {{ $t('documentCollection.faq.import.uploadTitle') }}
          </div>
          <div
            class="upload-desc text-[13px] text-[var(--el-text-color-secondary)]"
          >
            {{ $t('documentCollection.faq.import.uploadDesc') }}
          </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('documentCollection.faq.import.resultTitle') }}
            </span>
          </div>
        </div>
        <div class="result-stats">
          <div class="stat-item">
            <div class="stat-label">
              {{ $t('documentCollection.faq.import.totalCount') }}
            </div>
            <div class="stat-value">{{ importResult.totalCount || 0 }}</div>
          </div>
          <div class="stat-item">
            <div class="stat-label">
              {{ $t('documentCollection.faq.import.successCount') }}
            </div>
            <div class="stat-value success-text">
              {{ importResult.successCount || 0 }}
            </div>
          </div>
          <div class="stat-item">
            <div class="stat-label">
              {{ $t('documentCollection.faq.import.errorCount') }}
            </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('documentCollection.faq.import.rowNumber')"
            width="100"
          />
          <ElTableColumn
            prop="categoryPath"
            :label="$t('documentCollection.faq.categoryPath')"
            min-width="170"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="question"
            :label="$t('documentCollection.faq.question')"
            min-width="180"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="reason"
            :label="$t('documentCollection.faq.import.reason')"
            min-width="220"
            show-overflow-tooltip
          />
        </ElTable>
      </div>
    </div>
    <template #footer>
      <div class="action-row action-row-footer">
        <ElButton
          type="primary"
          plain
          :icon="Download"
          :disabled="downloadLoading"
          :loading="downloadLoading"
          @click="downloadTemplate"
        >
          {{ $t('documentCollection.faq.import.downloadTemplate') }}
        </ElButton>
        <ElButton
          type="primary"
          :icon="Upload"
          @click="handleImport"
          :loading="submitLoading"
          :disabled="submitLoading"
        >
          {{ $t('documentCollection.faq.import.startImport') }}
        </ElButton>
      </div>
    </template>
  </EasyFlowPanelModal>
</template>

<style scoped>
.faq-import-dialog {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.selected-file-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: var(--el-fill-color-blank);
  border: 1px solid var(--el-border-color-light);
  border-radius: 10px;
}

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

.selected-file-icon {
  font-size: 18px;
  color: var(--el-text-color-secondary);
}

.selected-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 14px;
  font-weight: 500;
  color: var(--el-text-color-primary);
  white-space: nowrap;
}

.remove-file-btn {
  color: var(--el-text-color-placeholder);
}

.remove-file-btn:hover {
  color: var(--el-color-danger);
}

.result-wrap {
  padding: 14px;
  background: var(--el-fill-color-light);
  border: 1px solid var(--el-border-color-light);
  border-radius: 12px;
}

.result-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.result-title-wrap {
  display: flex;
  gap: 8px;
  align-items: center;
}

.result-state-icon {
  font-size: 16px;
}

.result-title-text {
  font-size: 15px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

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

.stat-item {
  padding: 10px 12px;
  background: var(--el-fill-color-blank);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
}

.stat-label {
  margin-bottom: 8px;
  font-size: 12px;
  line-height: 1;
  color: var(--el-text-color-secondary);
}

.stat-value {
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  color: var(--el-text-color-primary);
}

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

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

.result-error-table {
  margin-top: 12px;
}

.action-row {
  display: flex;
  gap: 10px;
}

.action-row-footer {
  justify-content: flex-end;
}

:deep(.faq-upload-area .el-upload-dragger) {
  padding: 0;
  background-color: var(--el-fill-color-blank);
  border-radius: 10px;
  transition: all 0.3s;
}

:deep(.faq-upload-area .el-upload-dragger:hover) {
  background-color: var(--el-color-primary-light-9);
  border-color: var(--el-color-primary);
}

@media (max-width: 768px) {
  .result-stats {
    grid-template-columns: 1fr;
  }
}
</style>
