<template>
  <div class="material-selector-container" style="overflow: hidden;">
    <splitpanes class="default-theme">
      <!-- 左侧分类树 -->
      <pane size="16" style="overflow: auto;">
        <TreeComponent
          ref="treeComponent"
          :tree-data="categoryTreeData"
          :tree-props="treeProps"
          :node-key="nodeKey"
          :show-search="true"
          search-placeholder="请输入分类名称"
          :default-expand-all="true"
          :highlight-current="true"
          :loading="loadingTree"
          @node-click="handleTreeClick"
        >
          <template #node-content="{ node, data }">
            <span class="custom-tree-node">{{ node.label }}</span>
          </template>
        </TreeComponent>
      </pane>

      <!-- 右侧物料列表 -->
      <pane size="84" style="overflow: auto;">
        <div style="padding: 10px; display: flex; flex-direction: column;">
          <!-- 查询表单 -->
          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="88px">
            <el-form-item label="SAP物料号" prop="sapNo">
              <el-input
                v-model="queryParams.sapNo"
                placeholder="请输入SAP物料号"
                clearable
                @keyup.enter.native="handleQuery"
              />
            </el-form-item>
            <el-form-item label="物料名称" prop="materialName">
              <el-input
                v-model="queryParams.materialName"
                placeholder="请输入物料名称"
                clearable
                @keyup.enter.native="handleQuery"
              />
            </el-form-item>
            <el-form-item label="物料分类" prop="categoryNameInput">
              <el-input
                v-model="queryParams.categoryNameInput"
                placeholder="请输入物料分类"
                clearable
                @keyup.enter.native="handleQuery"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>

          <!-- 物料表格 -->
          <el-table
            ref="materialTable"
            v-loading="loading"
            :data="materialsList"
            @selection-change="handleSelectionChange"
            :scroll-x="true"
            :row-key="row => row.sapNo" 
            @row-click="handleRowClick"
            :select-on-indeterminate="false"
            @select="handleTableSelect" 
          >
            <el-table-column 
              type="selection" 
              width="55" 
              align="center"
            />
            <el-table-column type="index" label="序号" align="center"/>
            <el-table-column label="SAP物料号" align="center" prop="sapNo" />
            <el-table-column label="物料名称" align="center" prop="materialName" width="150"/>
            <el-table-column label="TS Code" align="center" prop="tsCode" />
            <el-table-column label="物料分类" align="center" prop="categoryCode">
              <template slot-scope="scope">
                {{ scope.row.displayCategory || categoryMap[scope.row.categoryCode] || scope.row.categoryCode || '-' }}
              </template>
            </el-table-column>
            <el-table-column label="规格型号" align="center" prop="specification" />
            <el-table-column label="计量单位" align="center" prop="materialUnit" />
            <el-table-column label="是否批次管理" align="center" prop="isBatchManaged">
              <template slot-scope="scope">
                <el-tag :type="scope.row.isBatchManaged === 1 ? 'success' : 'info'" size="mini">
                  {{ scope.row.isBatchManaged === 1 ? '是' : '否' }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>

          <!-- 分页 -->
          <pagination
            v-show="total>0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
          />
        </div>
      </pane>
    </splitpanes>
  </div>
</template>

<script>
import { listMaterials } from "@/api/inventory/materials"
import { listMaterials_category } from "@/api/inventory/materials_category"
import TreeComponent from '@/views/inventory/materials_category/treeComponent.vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'

export default {
  name: "MaterialSelector",
  components: { TreeComponent, Splitpanes, Pane },
  props: {
    value: {
      type: [Array, String],
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: true
    },
    defaultCategoryCodes: {
      type: Array,
      default: () => []
    },
    // 新增：父页面传递的反显参数（兼容原逻辑）
    selectedMaterialCodes: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      categoryTreeData: [],
      treeProps: { children: 'children', label: 'label', value: 'sid' },
      nodeKey: 'sid',
      loadingTree: false,
      categoryMap: {},
      categoryNameToCodeMap: {},
      categoryCodeToSidMap: {},
      currentNodeId: null,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        sapNo: null,
        materialName: null,
        tsCode: null,
        categoryCode: null,
        categoryNameInput: null,
        specification: null,
      },
      materialsList: [],
      total: 0,
      loading: false,
      selectedRows: [],
      singleSelectedSapNo: null,
      isSelecting: false
    }
  },
  watch: {
    // 核心修复1：同时监听value和selectedMaterialCodes，兼容两种传参方式
    value: {
      immediate: true,
      deep: true,
      handler(val) {
        this.handleValueChange(val)
      }
    },
    selectedMaterialCodes: {
      immediate: true,
      deep: true,
      handler(val) {
        // 优先使用selectedMaterialCodes，兼容父页面旧传参
        if (val && val.length) {
          this.handleValueChange(val)
        }
      }
    },
    multiple: {
      immediate: true,
      handler(val) {
        if (this.$refs.materialTable) {
          this.isSelecting = true
          try {
            this.$refs.materialTable.clearSelection()
            this.selectedRows = []
            this.singleSelectedSapNo = null
            this.$nextTick(() => this.handleValueSync())
          } finally {
            this.isSelecting = false
          }
        }
      }
    },
    defaultCategoryCodes: {
      immediate: true,
      handler(val) {
        if (val && val.length && this.categoryTreeData.length) {
          this.$nextTick(() => this.selectCategoryNodes(val))
        }
      }
    }
  },
  async created() {
    await Promise.all([this.getCategoryList(), this.getCategoryTreeData()])
    this.getList()
  },
  methods: {
    // 新增：统一处理值变更
    handleValueChange(val) {
      if (this.isSelecting) return

      // 空值直接清空选中
      if (!val || (Array.isArray(val) && !val.length)) {
        this.clearSelection()
        return
      }

      // 有值时：先清空筛选，保证列表全量
      if (this.currentNodeId || this.queryParams.categoryCode) {
        this.currentNodeId = null
        this.queryParams.categoryCode = null
        this.getList()
        return
      }

      // 列表未加载完成则等待，已加载则直接反显
      if (this.loading || !this.materialsList.length) {
        // 延长等待时间，确保列表加载完成
        const timer = setTimeout(() => {
          this.handleValueSync()
          clearTimeout(timer)
        }, 500)
      } else {
        this.handleValueSync()
      }
    },
    async getCategoryList() {
      try {
        const response = await listMaterials_category({ pageNum: 1, pageSize: 1000 })
        if (response.rows && response.rows.length > 0) {
          this.categoryMap = {}
          this.categoryNameToCodeMap = {}
          response.rows.forEach(item => {
            if (item.isUsed !== 0 && item.isUsed !== '0') {
              const code = item.categoryCode
              this.categoryMap[code] = item.categoryName
              if (!this.categoryNameToCodeMap[item.categoryName]) {
                this.categoryNameToCodeMap[item.categoryName] = code
              } else if (!Array.isArray(this.categoryNameToCodeMap[item.categoryName])) {
                this.categoryNameToCodeMap[item.categoryName] = [this.categoryNameToCodeMap[item.categoryName], code]
              } else {
                this.categoryNameToCodeMap[item.categoryName].push(code)
              }
            }
          })
        }
      } catch (error) {
        console.error('获取分类列表失败:', error)
      }
    },
    async getCategoryTreeData() {
      this.loadingTree = true
      try {
        const response = await listMaterials_category({ pageNum: 1, pageSize: 1000 })
        if (response.rows && response.rows.length > 0) {
          const activeCategories = response.rows.filter(item => item.isUsed !== 0 && item.isUsed !== '0')
          this.categoryTreeData = this.buildTreeData(activeCategories)
          this.buildCategoryCodeToSidMap(this.categoryTreeData)
        }
      } catch (error) {
        console.error('获取分类树数据失败:', error)
      } finally {
        this.loadingTree = false
      }
    },
    buildTreeData(list, parentId = null) {
      return list
        .filter(item => parentId === null 
          ? (!item.parentId || item.parentId === 0 || item.parentId === '0') 
          : Number(item.parentId) === Number(parentId)
        )
        .map(item => ({
          ...item,
          sid: String(item.id),
          label: item.categoryName,
          children: this.buildTreeData(list, item.id).length 
            ? this.buildTreeData(list, item.id) 
            : undefined
        }))
    },
    buildCategoryCodeToSidMap(treeData) {
      treeData.forEach(node => {
        if (node.categoryCode) {
          this.categoryCodeToSidMap[node.categoryCode] = node.sid
          const rawCode = node.categoryCode.replace(/-/g, '')
          if (rawCode !== node.categoryCode) {
            this.categoryCodeToSidMap[rawCode] = node.sid
          }
        }
        if (node.children && node.children.length) {
          this.buildCategoryCodeToSidMap(node.children)
        }
      })
    },
    selectCategoryNodes(categoryCodes) {
      if (!this.$refs.treeComponent || !this.$refs.treeComponent.$refs.tree) return
      const tree = this.$refs.treeComponent.$refs.tree
      categoryCodes.forEach(code => {
        const rawCode = code.replace(/-/g, '')
        const sid = this.categoryCodeToSidMap[rawCode] || this.categoryCodeToSidMap[code]
        if (sid) {
          tree.setCurrentKey(sid)
          this.currentNodeId = sid
          const node = tree.getNode(sid)
          if (node) tree.expandNode(node)
        }
      })
    },
    handleTreeClick(data) {
      this.currentNodeId = data.sid
      this.queryParams.categoryCode = data.categoryCode
      this.queryParams.categoryNameInput = null
      this.queryParams.pageNum = 1
      this.getList()
    },
    getList() {
      this.loading = true
      listMaterials(this.queryParams).then(response => {
        this.materialsList = (response.rows || []).filter(item => item.isUsed !== 0 && item.isUsed !== '0').map(item => ({
          ...item,
          displayCategory: this.categoryMap[item.categoryCode] || `${item.categoryCode}（未匹配分类）`,
          // 核心修复2：存储SAP号的大写和原始值，用于反显匹配
          sapNoUpper: item.sapNo ? item.sapNo.trim().toUpperCase() : ''
        }))
        this.total = response.total || 0
        // 确保列表渲染完成后再反显
        this.$nextTick(() => {
          setTimeout(() => this.handleValueSync(), 300)
        })
      }).catch(error => {
        console.error('获取物料列表失败:', error)
        this.materialsList = []
        this.total = 0
      }).finally(() => {
        this.loading = false
      })
    },
    handleQuery() {
      const inputName = this.queryParams.categoryNameInput
      if (inputName) {
        const matchedCode = this.categoryNameToCodeMap[inputName]
        if (matchedCode) {
          this.queryParams.categoryCode = Array.isArray(matchedCode) ? matchedCode[0] : matchedCode
        } else {
          const matchedCodes = Object.entries(this.categoryMap)
            .filter(([code, name]) => name.includes(inputName))
            .map(([code]) => code)
          if (matchedCodes.length > 0) {
            this.queryParams.categoryCode = matchedCodes[0]
          }
        }
      }
      this.queryParams.pageNum = 1
      this.getList()
    },
    // 核心修复：重置所有状态（对外暴露）
    resetQuery() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        sapNo: null,
        materialName: null,
        tsCode: null,
        categoryCode: null,
        categoryNameInput: null,
        specification: null,
      }
      this.currentNodeId = null
      if (this.$refs.treeComponent && this.$refs.treeComponent.$refs.tree) {
        this.$refs.treeComponent.$refs.tree.setCurrentKey(null)
      }
      this.clearSelection()
      this.getList()
    },
    handleSelectionChange(selection) {
      if (this.isSelecting || !this.$refs.materialTable) return

      this.isSelecting = true
      try {
        if (!this.multiple) {
          if (selection.length > 1) {
            const lastRow = selection.pop()
            this.$refs.materialTable.clearSelection()
            this.$refs.materialTable.toggleRowSelection(lastRow, true)
            this.selectedRows = [lastRow]
            this.singleSelectedSapNo = lastRow.sapNo
          } else {
            this.selectedRows = selection
            this.singleSelectedSapNo = selection.length > 0 ? selection[0].sapNo : null
          }
        } else {
          this.selectedRows = selection
        }

        const selectedSapNos = this.selectedRows.map(row => row.sapNo)
        const selectedData = this.selectedRows.map(item => ({
          sapNo: item.sapNo,
          materialName: item.materialName,
          categoryId: item.categoryCode || ''
        }))

        // 核心修复3：新增selection-change事件，兼容父页面旧逻辑
        this.$emit('selection-change', {
          materialCodes: selectedSapNos,
          names: selectedData.map(item => item.materialName),
          categoryIds: selectedData.map(item => item.categoryId)
        })

        if (this.multiple) {
          this.$emit('input', selectedSapNos)
          this.$emit('change', selectedData)
        } else {
          const singleSapNo = selectedSapNos.length > 0 ? selectedSapNos[0] : ''
          const singleData = selectedData.length > 0 ? selectedData[0] : null
          this.$emit('input', singleSapNo)
          this.$emit('change', singleData)
        }
      } finally {
        this.isSelecting = false
      }
    },
    handleTableSelect(selection, row) {
      if (this.isSelecting || this.multiple) return

      this.isSelecting = true
      try {
        const isSelected = selection.includes(row)
        this.$refs.materialTable.clearSelection()
        if (isSelected) {
          this.$refs.materialTable.toggleRowSelection(row, true)
          this.singleSelectedSapNo = row.sapNo
          this.selectedRows = [row]
          this.$emit('input', row.sapNo)
          this.$emit('change', { sapNo: row.sapNo, materialName: row.materialName })
          // 兼容selection-change事件
          this.$emit('selection-change', {
            materialCodes: [row.sapNo],
            names: [row.materialName],
            categoryIds: [row.categoryCode || '']
          })
        } else {
          this.singleSelectedSapNo = null
          this.selectedRows = []
          this.$emit('input', '')
          this.$emit('change', null)
          this.$emit('selection-change', {
            materialCodes: [],
            names: [],
            categoryIds: []
          })
        }
      } finally {
        this.isSelecting = false
      }
    },
    handleRowClick(row) {
      if (this.isSelecting || !this.$refs.materialTable) return

      this.isSelecting = true
      try {
        if (!this.multiple) {
          const isCurrentlySelected = this.singleSelectedSapNo === row.sapNo
          this.$refs.materialTable.clearSelection()
          
          if (!isCurrentlySelected) {
            this.$refs.materialTable.toggleRowSelection(row, true)
            this.singleSelectedSapNo = row.sapNo
            this.selectedRows = [row]
            this.$emit('input', row.sapNo)
            this.$emit('change', { sapNo: row.sapNo, materialName: row.materialName })
            this.$emit('selection-change', {
              materialCodes: [row.sapNo],
              names: [row.materialName],
              categoryIds: [row.categoryCode || '']
            })
          } else {
            this.singleSelectedSapNo = null
            this.selectedRows = []
            this.$emit('input', '')
            this.$emit('change', null)
            this.$emit('selection-change', {
              materialCodes: [],
              names: [],
              categoryIds: []
            })
          }
        } else {
          this.$refs.materialTable.toggleRowSelection(row)
        }
      } finally {
        this.isSelecting = false
      }
    },
    // 核心修复：彻底清空选中状态并同步父页面（对外暴露）
    clearSelection() {
      if (this.isSelecting || !this.$refs.materialTable) return

      this.isSelecting = true
      try {
        this.$refs.materialTable.clearSelection()
        this.selectedRows = []
        this.singleSelectedSapNo = null
        this.$emit('input', this.multiple ? [] : '')
        this.$emit('change', this.multiple ? [] : null)
        this.$emit('selection-change', {
          materialCodes: [],
          names: [],
          categoryIds: []
        })
      } finally {
        this.isSelecting = false
      }
    },
    // 核心修复4：增强反显同步逻辑，兼容大小写和多页数据
    handleValueSync() {
      if (this.loading || this.isSelecting || !this.$refs.materialTable) return
      
      // 优先使用selectedMaterialCodes，兼容父页面传参
      const val = this.selectedMaterialCodes.length ? this.selectedMaterialCodes : this.value
      if (!val || (Array.isArray(val) && !val.length)) {
        this.clearSelection()
        return
      }

      // 统一处理值格式：转数组 + 去空 + 转大写（用于匹配）
      const targetSapNos = this.multiple 
        ? Array.isArray(val) ? val : [val]
        : [Array.isArray(val) ? val[0] : val]
      const targetSapNosUpper = targetSapNos.map(code => code ? code.trim().toUpperCase() : '')
        .filter(code => code)

      this.isSelecting = true
      try {
        this.$refs.materialTable.clearSelection()
        
        // 遍历列表匹配（兼容原始值和大写值）
        this.materialsList.forEach(row => {
          const rowSapUpper = row.sapNoUpper || row.sapNo.trim().toUpperCase()
          if (targetSapNos.includes(row.sapNo) || targetSapNosUpper.includes(rowSapUpper)) {
            this.$refs.materialTable.toggleRowSelection(row, true)
          }
        })

        // 更新选中行数据
        this.selectedRows = this.materialsList.filter(row => {
          const rowSapUpper = row.sapNoUpper || row.sapNo.trim().toUpperCase()
          return targetSapNos.includes(row.sapNo) || targetSapNosUpper.includes(rowSapUpper)
        })
        this.singleSelectedSapNo = this.multiple ? null : (this.selectedRows[0]?.sapNo || null)
      } finally {
        this.isSelecting = false
      }
    },
    // 核心修复5：对外暴露反显方法，供父页面主动调用
    setSelectedCodes(codes) {
      if (this.isSelecting) return
      
      this.isSelecting = true
      try {
        // 先清空筛选，保证列表全量
        this.currentNodeId = null
        this.queryParams.categoryCode = null
        
        // 重新加载列表后再反显
        this.getList().then(() => {
          this.$nextTick(() => {
            // 赋值给selectedMaterialCodes触发反显
            this.$props.selectedMaterialCodes = codes
            this.handleValueSync()
          })
        })
      } finally {
        this.isSelecting = false
      }
    },
    getSelectedMaterials() {
      if (this.multiple) {
        return this.selectedRows.map(row => ({ sapNo: row.sapNo, materialName: row.materialName }))
      } else {
        return this.selectedRows[0] ? { sapNo: this.selectedRows[0].sapNo, materialName: this.selectedRows[0].materialName } : null
      }
    },
    setSingleSelection(sapNo) {
      if (this.isSelecting || this.multiple) return

      this.isSelecting = true
      try {
        this.singleSelectedSapNo = sapNo
        this.$nextTick(() => {
          this.$refs.materialTable.clearSelection()
          const targetRow = this.materialsList.find(row => {
            const rowSapUpper = row.sapNoUpper || row.sapNo.trim().toUpperCase()
            return row.sapNo === sapNo || rowSapUpper === sapNo.trim().toUpperCase()
          })
          if (targetRow) {
            this.$refs.materialTable.toggleRowSelection(targetRow, true)
            this.selectedRows = [targetRow]
            this.$emit('input', sapNo)
            this.$emit('change', { sapNo: targetRow.sapNo, materialName: targetRow.materialName })
            this.$emit('selection-change', {
              materialCodes: [targetRow.sapNo],
              names: [targetRow.materialName],
              categoryIds: [targetRow.categoryCode || '']
            })
          }
        })
      } finally {
        this.isSelecting = false
      }
    }
  }
}
</script>

<style scoped>
.material-selector-container {
  height: 100%;
  min-height: 500px;
}
.custom-tree-node {
  font-size: 14px;
}
/deep/ .el-table .el-table__header .cell {
  text-align: center;
}
/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
  background-color: #f5f7fa;
}
/deep/ .el-table__fixed-right,
/deep/ .el-table__fixed-left {
  pointer-events: auto !important;
}
</style>