<template>
    <vxe-modal
      resize
      show-maximize
      v-model="showPopup"
      title="文件导入"
      height="100%"
      width="100%"
    >
        <div class="container"  v-show="showSelect">
            <div class="instructions">
                <h3>使用说明</h3>
                <ol>
                    <li>点击"选择Excel文件"按钮或拖放Excel文件到指定区域</li>
                    <li>支持.xlsx和.xls格式的Excel文件</li>
                    <li>解析后的数据将显示在下方的表格中</li>
                    <li>如果Excel文件有多个工作表，可以使用下拉菜单切换</li>
                </ol>
            </div>
            
            <div class="upload-container">
                <input type="file" ref="fileInput" class="file-input" accept=".xlsx, .xls" @change="handleFileUpload">
                <div class="drop-area" 
                    @click="triggerFileInput"
                    @drop="handleDrop"
                    @dragover="handleDragOver"
                    @dragleave="handleDragLeave"
                    :class="{ 'dragover': isDragging }">
                    <i>📊</i>
                    <p>点击或拖放Excel文件到这里</p>
                    <p class="small">支持 .xlsx 和 .xls 格式</p>
                </div>
                <button class="btn" :disabled="isLoading" @click="triggerFileInput">
                    {{ isLoading ? '解析中...' : '选择Excel文件' }}
                </button>
            </div>
        </div>
        <div v-show="!showSelect" style="margin: 10px;height: 80vh;" >
            <vxe-grid v-bind="gridOptions" ref="tableRef">
                <template #toolbarButtons>
                    <vxe-button status="primary" @click="handleSelecFile">重新选择文件</vxe-button>
                    <vxe-button status="primary" @click="handleAdd">保存到数据库</vxe-button>
                    <vxe-button status="primary" @click="handleDels()">删除</vxe-button>
                    <vxe-button status="primary" @click="handleColumnsConfig()">设置列</vxe-button>

                    <div class="sheet-selector-container" v-if="sheetNames.length > 1" style="margin-left:100px">
                        <span style="margin-right: 8px">选择工作表: </span>
                        <vxe-select v-model="activeSheet" placeholder="切换工作表" @change="changeSheet" clearable>
                            <vxe-option v-for="sheetName in sheetNames" :value="sheetName" :label="sheetName" :key="sheetName">
                            </vxe-option>
                        </vxe-select>
                    </div>
                </template>
               
                <!-- <template #top>
                    <div style="background:#C3C3C3;height: 10px;"></div>
                </template> -->
                
            </vxe-grid>
        </div>
        <vxe-modal
            resize
            show-footer
            show-confirm-button
            show-cancel-button
            show-maximize
            v-model="showSubPopup"
            title="配置字段关联"
            height="500"
            width="900"
            :position="{top: '40%'}"
            :mask="false" 
          >
            <vxe-grid ref="configRef" v-bind="configGridOptions"></vxe-grid>
        </vxe-modal>
    </vxe-modal>    
</template>

<script lang="ts" setup> 
import { ref, nextTick, onMounted, reactive, computed } from 'vue';  
import { utils, read } from 'xlsx';  
import type { VxeGridProps, VxeSelectProps } from 'vxe-table'

const emit = defineEmits(['callback','success']);

const isLoading = ref(false)
const fileInput = ref<HTMLInputElement>();
const showPopup = ref(false)
const showSubPopup = ref(false)

const isDragging = ref(false)
const workbook = ref<any>(null)
const currentSheetIndex = ref(0)
const excelData = ref<any[][]>([])
const statusMessage = ref('')
const statusType = ref('')

const showSelect = ref(true)
const tableRef = ref()
const targetColumns = ref()

const configDatas = ref<Array<{c1: string, c2: string, c3?: string}>>([]);

const activeSheet = ref("")
const sheetNames = ref<string[]>([])

const file = ref<File | null>(null)



const fileColumsEditRender = reactive<any>({
  name: 'VxeSelect',
  options: []
})

const configGridOptions = reactive<VxeGridProps<any>>({
  border: true,
  stripe: true,
  loading: false,
  height:'auto',
  columnConfig: {
    resizable: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'cell'
  },
  rowConfig: {
    isHover: true
  },
  checkboxConfig: {
    highlight: true,
    range: true
  },
  columns: [
    {field:"c1",title:"Excel列"},
    {field:"c2",title:"Excel列名称"},
    {field:"c3",title:"目标列", editRender: fileColumsEditRender},
  ],
  data: []
})

const gridOptions = reactive<VxeGridProps<any>>({
  border: true,
  stripe: true,
  loading: false,
  height:'auto',
  columnConfig: {
    resizable: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'cell'
  },
  toolbarConfig: {
    refresh: false,
    zoom: true,
    custom: true,
    export: true,
    print: true,
    slots: {
      buttons: 'toolbarButtons'
    }
  },
  rowConfig: {
    isHover: true
  },
  checkboxConfig: {
    highlight: true,
    range: true
  },
  columns: [],
  data: []
})

// 计算属性获取表头
const headers = computed(() => {
    return excelData.value.length > 0 ? excelData.value[0] : []
})

const triggerFileInput = () => {
    fileInput.value?.click()
}

const handleDrop = (e: DragEvent) => {
    e.preventDefault()
    isDragging.value = false
    
    if (e.dataTransfer?.files) {
        const files = e.dataTransfer.files
        if (files.length > 0) {
            processExcelFile(files[0])
            file.value = files[0]
        }
    }
}

const handleDragOver = (e: DragEvent) => {
    e.preventDefault()
    isDragging.value = true
}

const handleDragLeave = (e: DragEvent) => {
    e.preventDefault()
    isDragging.value = false
}

const handleFileUpload = (e: Event) => {
    const target = e.target as HTMLInputElement
    if (target.files && target.files.length > 0) {
        processExcelFile(target.files[0])
        file.value = target.files[0]
    }
}

const processExcelFile = (file: File) => {
    // 检查文件类型
    if (!file.name.match(/\.(xlsx|xls)$/i)) {
        showStatus('请选择Excel文件(.xlsx或.xls格式)', 'error')
        return
    }
    
    isLoading.value = true
    showStatus('正在解析文件...', '')
    
    const reader = new FileReader()
    
    reader.onload = (e) => {
        try {
            const data = new Uint8Array(e.target?.result as ArrayBuffer)
            // 解析Excel文件
            workbook.value = read(data, { type: 'array' })
            if (workbook.value.SheetNames.length === 0) {
                showStatus('Excel文件中没有找到工作表', 'error')
                return
            }
            
            sheetNames.value = workbook.value.SheetNames
            activeSheet.value = sheetNames.value[0]
            currentSheetIndex.value = 0

            switchSheet()
            
            showStatus('文件解析成功', 'success')
        } catch (error) {
            console.error('解析Excel文件时出错:', error)
            showStatus('解析文件时出错，请检查文件格式', 'error')
        } finally {
            isLoading.value = false
        }
    }
    
    reader.onerror = () => {
        showStatus('读取文件时发生错误', 'error')
        isLoading.value = false
    }
    
    reader.readAsArrayBuffer(file)
}

const switchSheet = () => {
    if (!workbook.value) return
    
    try {
        // 根据当前选中的工作表名称获取索引
        const sheetIndex = sheetNames.value.indexOf(activeSheet.value)
        if (sheetIndex === -1) {
            console.error('未找到对应的工作表:', activeSheet.value)
            return
        }
        
        currentSheetIndex.value = sheetIndex
        const sheetName = workbook.value.SheetNames[sheetIndex]
        const worksheet = workbook.value.Sheets[sheetName]
        const jsonData = utils.sheet_to_json(worksheet, { header: 1 })
        
        const filteredData = jsonData.filter((row: any) => 
            Array.isArray(row) && row.some((cell: any) => 
                cell !== null && cell !== undefined && cell !== ''
            )
        )
        
        const tableData = filteredData.map((row: any[], rowIndex: number) => {
            const obj: Record<string, any> = {}
            obj.id = rowIndex
            row.forEach((cell: any, colIndex: number) => {
                obj[`col${colIndex}`] = removeNonTextAdvanced(cell)
            })
            return obj
        })
        
        const maxColumns = filteredData.reduce((max: number, row: any[]) => 
            Math.max(max, row?.length || 0), 0
        )
        
        const columns = [
            { field: 'id', title:"序号", width: 50 },
            { type: 'checkbox', width: 50 },
            ...Array.from({ length: maxColumns }, (_, index) => ({
                field: `col${index}`,
                title: `第${index + 1}列`,
                sortable: true,
                editRender: { name: 'VxeInput' }
            }))
        ]
    
        excelData.value = filteredData
        gridOptions.columns = columns
        gridOptions.data = tableData

        showSelect.value = false

        // 更新配置选项
        fileColumsEditRender.options = gridOptions.columns
            .filter(col => col.field && col.field !== 'id')
            .map(col => ({
                label: col.title,
                value: col.field
            }))
        
    } catch (error) {
        console.error('切换工作表时出错:', error)
        showStatus('切换工作表时出错', 'error')
    }
}

const showStatus = (message: string, type: string) => {
    statusMessage.value = message
    statusType.value = type
    
    // 3秒后清除状态消息
    if (type !== '') {
        setTimeout(() => {
            statusMessage.value = ''
            statusType.value = ''
        }, 3000)
    }
}

const iniData = (colums: any[]) => {
    targetColumns.value = colums
    showPopup.value = true
    workbook.value = null
    excelData.value = []
    currentSheetIndex.value = 0
    statusMessage.value = ''
    showSelect.value = true
    
    nextTick()

    const currentColumns = targetColumns.value.filter(col => col.field)
    configDatas.value = configGridOptions.data = currentColumns.map(col => ({
        c1: col.title||col.label,
        c2: col.field
    }))

    nextTick()
}

const handleSelecFile = () => {
    showSelect.value = true
}

// 获取选中的记录
function getSelectRecords() {
    const $table = tableRef.value
    if ($table) {
        return $table.getCheckboxRecords()
    }
    return []
}

async function handleDels() {
    const selectedRecords = getSelectRecords()
    
    if (selectedRecords.length === 0) {
        alert('请先选择要删除的记录')
        return false
    }
    
    if (!confirm(`确定要删除选中的 ${selectedRecords.length} 条记录吗？`)) {
        return false
    }
    
    try {
        const selectedIds = selectedRecords.map(record => record.id)
        gridOptions.data = gridOptions.data.filter(record => 
            !selectedIds.includes(record.id)
        )

        excelData.value = excelData.value.filter((_, index) => 
            !selectedIds.includes(index)
        )
        
    } catch (error) {
        console.error('删除记录时出错:', error)
    }
}

const handleAdd = () => {
    if (!configDatas.value?.length || !gridOptions.data?.length) {
        console.warn('数据为空，无法处理')
        alert('没有数据可以保存')
        return
    }
    
    const fieldMapping = Object.fromEntries(
        configDatas.value
            .filter(item => item.c3 && item.c2)
            .map(item => [item.c3, item.c2])
    )
    
    const newArray = gridOptions.data.map(item => 
        Object.entries(item).reduce((acc, [key, value]) => {
            if (value != null) {
                const newKey = fieldMapping[key]
                if(newKey) {
                    acc[newKey] = value
                }
            }
            return acc
        }, {} as Record<string, any>)
    )
    
    showPopup.value = false
    emit("callback", newArray)
}

const handleColumnsConfig = () => {
    showSubPopup.value = true
}

function removeNonTextAdvanced(str: any) {
    if (str === null || str === undefined) return ''
    return String(str).replace(/[^a-zA-Z0-9\u4e00-\u9fa5 ，。！？；：'"]/g, '')
}

const changeSheet = async() => {
    await switchSheet()
}

defineExpose({
    iniData,
})
</script>

<style scoped>
/* 样式保持不变 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
    background-color: #f5f7fa;
    color: #333;
    padding: 20px;
}
.container {
    width: 100%;
    height: 100%;
    margin: 0 auto;
}
header {
    text-align: center;
    margin-bottom: 30px;
    padding: 20px;
}
h1 {
    color: #2c3e50;
    margin-bottom: 10px;
}
.description {
    color: #7f8c8d;
    font-size: 1.1em;
}
.upload-container {
    background: white;
    border-radius: 10px;
    padding: 30px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    margin-bottom: 30px;
    text-align: center;
}
.drop-area {
    border: 2px dashed #3498db;
    border-radius: 8px;
    padding: 40px 20px;
    margin: 20px 0;
    cursor: pointer;
    transition: all 0.3s;
}
.drop-area:hover, .drop-area.dragover {
    background-color: rgba(52, 152, 219, 0.05);
    border-color: #2980b9;
}
.drop-area i {
    font-size: 48px;
    color: #3498db;
    margin-bottom: 15px;
    display: block;
}
.file-input {
    display: none;
}
.btn {
    background: #3498db;
    color: white;
    border: none;
    padding: 12px 24px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 16px;
    transition: background 0.3s;
}
.btn:hover {
    background: #2980b9;
}
.btn:disabled {
    background: #bdc3c7;
    cursor: not-allowed;
}
.data-container {
    background: white;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    overflow-x: auto;
    margin-top: 20px;
}
.table-wrapper {
    overflow-x: auto;
    max-height: 400px;
    overflow-y: auto;
}
table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
}
th, td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #e0e0e0;
    white-space: nowrap;
}
th {
    background-color: #f8f9fa;
    font-weight: 600;
    color: #2c3e50;
    position: sticky;
    top: 0;
}
tr:hover {
    background-color: #f5f7fa;
}
.status {
    margin-top: 15px;
    padding: 10px;
    border-radius: 6px;
}
.status.success {
    background-color: #d4edda;
    color: #155724;
}
.status.error {
    background-color: #f8d7da;
    color: #721c24;
}
.sheet-selector-container {
    margin: 15px 0;
    padding: 10px;
    background: #f8f9fa;
    border-radius: 6px;
}
.sheet-selector-container select {
    padding: 8px 12px;
    border-radius: 6px;
    border: 1px solid #ddd;
    margin-left: 10px;
}
.instructions {
    background: #e3f2fd;
    padding: 15px;
    border-radius: 8px;
    margin-bottom: 20px;
}
.instructions h3 {
    margin-bottom: 10px;
    color: #1565c0;
}
.instructions ol {
    margin-left: 20px;
}
.instructions li {
    margin-bottom: 8px;
}
.small {
    font-size: 0.9em;
    color: #7f8c8d;
}

</style>