<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 左侧树形结构 -->
      <el-col :span="6">
        <div class="tree-container">
          <div class="tree-header">
            <span class="tree-title">资产位置</span>
            
          </div>
          <el-divider class="tree-divider"></el-divider>
          <el-tree
            ref="locationTree"
            :data="locationTree"
            :props="defaultProps"
            node-key="id"
            :expand-on-click-node="false"
            highlight-current
            @node-click="handleNodeClick"
            :default-expanded-keys="defaultExpandedKeys">
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ node.label }}</span>
              <span v-if="data.children && data.children.length > 0" class="node-count">
                ({{ data.children.length }})
              </span>
            </span>
          </el-tree>
        </div>
      </el-col>

      <!-- 右侧列表 -->
      <el-col :span="18">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>位置列表</span>
            <el-button
              style="float: right; margin-left: 10px;"
              type="primary"
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd">新增位置</el-button>
            <el-button
              style="float: right;"
              type="danger"
              icon="el-icon-delete"
              size="mini"
              :disabled="multipleSelection.length === 0"
              @click="handleBatchDelete">批量删除</el-button>
          </div>
          
          <!-- 搜索表单 -->
          <el-form :inline="true" :model="queryParams" class="demo-form-inline">
            <el-form-item label="位置编码">
              <el-input v-model="queryParams.locationCode" placeholder="请输入位置编码" clearable size="small" />
            </el-form-item>
            <el-form-item label="位置名称">
              <el-input v-model="queryParams.locationName" placeholder="请输入位置名称" clearable size="small" />
            </el-form-item>
            <el-form-item label="状态">
              <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
                <el-option label="启用" value="1" />
                <el-option label="禁用" value="0" />
              </el-select>
            </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 
            v-loading="loading" 
            :data="locationList" 
            border 
            stripe 
            style="width: 100%"
            @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55" />
            <el-table-column prop="locationCode" label="位置编码" width="150" />
            <el-table-column prop="locationName" label="位置名称" width="200" />
            <el-table-column label="上级位置" width="200">
              <template slot-scope="scope">
                <span>{{ getParentName(scope.row.parentId) }}</span>
              </template>
            </el-table-column>
            <!-- <el-table-column prop="levelCode" label="层级编码" width="120" /> -->
            <el-table-column prop="status" label="状态" width="100">
              <template slot-scope="scope">
                <el-tag :type="scope.row.status === '1' ? 'success' : 'info'">
                  {{ scope.row.status === '1' ? '启用' : '禁用' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="remark" label="备注" />
            <el-table-column label="操作" width="180" fixed="right">
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="handleEdit(scope.row)">修改</el-button>
                <el-button 
                  size="mini" 
                  type="text" 
                  @click="handleStatusChange(scope.row)">
                  {{ scope.row.status === '1' ? '禁用' : '启用' }}
                </el-button>
                <el-button 
                  size="mini" 
                  type="text" 
                  style="color: #F56C6C" 
                  @click="handleDelete(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <!-- 分页 -->
          <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="queryParams.pageNum"
            :page-sizes="[10, 20, 50, 100]"
            :page-size="queryParams.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            class="pagination">
          </el-pagination>
        </el-card>
      </el-col>
    </el-row>

    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="位置编码" prop="locationCode">
          <el-input v-model="form.locationCode" placeholder="请输入位置编码" />
        </el-form-item>
        <el-form-item label="位置名称" prop="locationName">
          <el-input v-model="form.locationName" placeholder="请输入位置名称" />
        </el-form-item>
        <el-form-item label="上级位置" prop="parentId">
          <el-cascader
            v-model="form.parentId"
            :options="locationTreeOptions"
            :props="{ 
              checkStrictly: true,
              emitPath: false,
              expandTrigger: 'hover',
              value: 'id',
              label: 'label'
            }"
            clearable
            filterable
            placeholder="请选择上级位置"
            style="width: 100%">
          </el-cascader>
        </el-form-item>
        <!-- <el-form-item label="层级编码" prop="levelCode">
          <el-input v-model="form.levelCode" placeholder="请输入层级编码" />
        </el-form-item> -->
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio label="1">启用</el-radio>
            <el-radio label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitForm">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listLocation, getLocation, addLocation, updateLocation, delLocation, enableLocation, disableLocation, getLocationTree, checkLocationInUse, getChildLocations, delLocationBatch, checkLocationCode } from '@/api/asset/location'

export default {
  name: 'AssetLocation',
  data() {
    return {
      // 遮罩层
      loading: false,
      // 总条数
      total: 0,
      // 位置列表
      locationList: [],
      // 位置树形数据
      locationTree: [],
      // 处理后的树形选项数据（用于级联选择器）
      locationTreeOptions: [],
      // 默认展开的节点
      defaultExpandedKeys: [],
      // 树形配置
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      // 弹出层标题
      dialogTitle: '',
      // 是否显示弹出层
      dialogVisible: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        locationCode: undefined,
        locationName: undefined,
        status: undefined,
        parentId: undefined
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        locationCode: [
          { required: true, message: '请输入位置编码', trigger: 'blur' },
          { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
          { validator: this.validateLocationCode, trigger: 'blur' }
        ],
        locationName: [
          { required: true, message: '请输入位置名称', trigger: 'blur' },
          { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
        ],
        parentId: [
          { required: false, message: '请选择上级位置', trigger: 'change' }
        ],
        remark: [
          { max: 200, message: '长度不能超过200个字符', trigger: 'blur' }
        ]
      },
      // 多选选中项
      multipleSelection: []
    }
  },
  created() {
    this.getTree()
    this.getList()
  },
  methods: {
    /** 检验位置编码唯一性 */
    validateLocationCode(rule, value, callback) {
      if (value === '') {
        callback()
        return
      }
      checkLocationCode(this.form.id, value).then(res => {
        if (res.code === '000000') {
          if (res.data) {
            callback()
          } else {
            callback(new Error('该位置编码已存在'))
          }
        } else {
          callback()
        }
      }).catch(() => {
        callback()
      })
    },
    /** 获取位置树形结构 */
    getTree() {
      this.loading = true
      const params = {
        status: undefined // 获取所有状态的位置
      }
      getLocationTree(params).then(res => {
        if (res.code === '000000') {
          // 处理返回的树形数据，确保字段名称正确
          this.locationTree = this.processTreeData(res.data)
          
          // 准备级联选择器的数据源
          this.locationTreeOptions = this.prepareTreeSelectOptions(this.locationTree)
          
          // 如果之前已经有展开的节点，保持这些节点展开
          // 否则只展开第一级有子节点的节点
          if (!this.defaultExpandedKeys || this.defaultExpandedKeys.length === 0) {
            this.defaultExpandedKeys = this.getFirstLevelKeys(this.locationTree)
          }
          
          // 强制刷新树组件
          this.$nextTick(() => {
            if (this.$refs.locationTree) {
              this.$refs.locationTree.$forceUpdate()
            }
          })
        } else {
          this.$message.error(res.msg || '获取位置树失败')
        }
        this.loading = false
      }).catch(error => {
        console.error('获取位置树失败', error)
        this.$message.error('系统错误，获取位置树失败')
        this.loading = false
      })
    },
    
    /** 获取第一级节点的key，仅展开有子节点的 */
    getFirstLevelKeys(tree) {
      if (!tree || !Array.isArray(tree)) return []
      
      return tree
        .filter(node => node.children && node.children.length > 0)
        .map(node => node.id)
    },
    
    /** 获取所有节点key，用于全部展开 */
    getExpandedKeys(tree, keys = []) {
      for (const node of tree) {
        if (node.children && node.children.length > 0) {
          keys.push(node.id)
          this.getExpandedKeys(node.children, keys)
        }
      }
      return keys
    },
    
    /** 处理树形数据，确保字段名称正确 */
    processTreeData(data) {
      if (!data || !Array.isArray(data)) return []
      
      const processNode = (node) => {
        // 创建一个新对象，使用驼峰命名
        const processedNode = {
          id: node.id,
          // 转换label，格式为"编码-名称"
          label: `${node.code || ''}-${node.locationName || node.label || ''}`,
          // 驼峰命名
          locationName: node.locationName || node.label || '',
          locationCode: node.code || '',
          status: node.status || '1',
          parentId: node.parentId || null,
          levelCode: node.levelCode || '',
          children: []
        }
        
        // 递归处理子节点
        if (node.children && Array.isArray(node.children) && node.children.length > 0) {
          processedNode.children = node.children.map(child => processNode(child))
        }
        
        return processedNode
      }
      
      return data.map(item => processNode(item))
    },
    
    /** 准备级联选择器的数据源 */
    prepareTreeSelectOptions(data) {
      if (!data || !Array.isArray(data)) return []
      
      // 创建一个无上级选项
      const options = [{
        id: '',
        label: '无上级位置',
        children: []
      }]
      
      // 添加所有位置节点
      const cloneData = JSON.parse(JSON.stringify(data))
      options.push(...cloneData)
      
      return options
    },
    
    /** 转换下划线命名为驼峰命名 */
    convertSnakeToCamel(list) {
      if (!list || !Array.isArray(list)) return []
      
      return list.map(item => {
        return {
          id: item.id,
          locationCode: item.locationCode || '',
          locationName: item.locationName || '',
          parentId: item.parentId || null,
          levelCode: item.levelCode || '',
          status: item.status || '1',
          remark: item.remark || '',
          createTime:  item.createTime || '',
          createUserId:  item.createUserId || '',
          lastModUserId:  item.lastModUserId || '',
          lastModTime:  item.lastModTime || ''
        }
      })
    },
    /** 查询位置列表 */
    getList() {
      this.loading = true
      listLocation(this.queryParams).then(res => {
        if (res.code === '000000') {
          // 转换API返回数据结构为驼峰命名
          this.locationList = this.convertSnakeToCamel(res.data.list)
          this.total = res.data.total
        } else {
          this.$message.error(res.msg || '获取位置列表失败')
        }
        this.loading = false
      }).catch(error => {
        console.error('获取位置列表失败', error)
        this.$message.error('系统错误，获取位置列表失败')
        this.loading = false
      })
    },
    /** 节点单击事件 */
    handleNodeClick(data) {
      this.queryParams.parentId = data.id
      // 使用新的获取子位置API
      this.loading = true
      getChildLocations(data.id, {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      }).then(res => {
        if (res.code === '000000') {
          this.locationList = this.convertSnakeToCamel(res.data.list)
          this.total = res.data.total
        } else {
          this.$message.error(res.msg || '获取子位置列表失败')
        }
        this.loading = false
      }).catch(error => {
        console.error('获取子位置列表失败', error)
        this.$message.error('系统错误，获取子位置列表失败')
        this.loading = false
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.queryParams.parentId = undefined
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        locationCode: undefined,
        locationName: undefined,
        status: undefined,
        parentId: undefined
      }
      this.getList()
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.dialogTitle = '新增位置'
      this.form = {
        locationCode: '',
        locationName: '',
        parentId: this.queryParams.parentId || '', // 如果当前有选中节点，则默认为父节点
        levelCode: '',
        status: '1',
        remark: '',
        createUserId: this.$store.getters.userId || ''
      }
      this.dialogVisible = true
      this.$nextTick(() => {
        if (this.$refs.form) {
          this.$refs.form.clearValidate()
        }
      })
    },
    /** 修改按钮操作 */
    handleEdit(row) {
      const id = row.id
      getLocation(id).then(res => {
        if (res.code === '000000') {
          // 将API响应数据映射到表单字段，使用驼峰命名
          this.form = {
            id: res.data.id,
            locationCode: res.data.locationCode,
            locationName: res.data.locationCode,
            parentId: res.data.parentId || '',
            levelCode: res.data.levelCode || '',
            status: res.data.status,
            remark: res.data.remark,
            // 添加最后修改人
            lastModUserId: this.$store.getters.userId || ''
          }
          
          this.dialogTitle = '编辑位置'
          this.dialogVisible = true
          // 重置表单验证
          this.$nextTick(() => {
            if (this.$refs.form) {
              this.$refs.form.clearValidate()
            }
          })
        } else {
          this.$message.error(res.msg || '获取位置详情失败')
        }
      }).catch(error => {
        console.error('获取位置详情失败', error)
        this.$message.error('系统错误，获取位置详情失败')
      })
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (valid) {
          // A. 构建提交数据，映射表单字段到API字段
          const submitData = {
            id: this.form.id,
            locationCode: this.form.locationCode,
            locationName: this.form.locationName,
            parentId: this.form.parentId,
            levelCode: this.form.levelCode,
            status: this.form.status,
            remark: this.form.remark
          }
          
          // B. 添加创建/修改用户信息
          if (this.form.id) {
            submitData.lastModUserId = this.form.lastModUserId || this.$store.getters.userId || ''
          } else {
            submitData.createUserId = this.form.createUserId || this.$store.getters.userId || ''
          }
          
          const method = this.form.id ? updateLocation : addLocation
          method(submitData).then(res => {
            if (res.code === '000000') {
              this.$message.success('操作成功')
              this.dialogVisible = false
              
              // 重新获取树形结构，确保更新多级结构
              this.getTree()
              
              // 如果是新增子位置，更新当前列表
              if (this.queryParams.parentId && !this.form.id) {
                this.handleNodeClick({ id: this.queryParams.parentId })
              } else {
                this.getList()
              }
            } else {
              this.$message.error(res.msg || '操作失败')
            }
          }).catch(error => {
            console.error('提交表单失败', error)
            this.$message.error('系统错误，提交失败')
          })
        }
      })
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除该位置?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 先检查位置是否被使用
        checkLocationInUse(row.id).then(res => {
          if (res.code === '000000' && res.data) {
            this.$message.error('该位置已被使用，无法删除')
            return
          }
          // 未被使用，执行删除操作
          const lastModUserId = this.$store.getters.userId || ''
          delLocation(row.id, lastModUserId).then(res => {
            if (res.code === '000000') {
              this.$message.success('删除成功')
              // 重新获取树形结构，确保更新多级结构
              this.getTree()
              this.getList()
            } else {
              this.$message.error(res.msg || '删除失败')
            }
          }).catch(error => {
            console.error('删除操作失败', error)
            this.$message.error('系统错误，删除失败')
          })
        })
      }).catch(() => {})
    },
    /** 状态修改按钮操作 */
    handleStatusChange(row) {
      const action = row.status === '1' ? '禁用' : '启用'
      this.$confirm(`是否确认${action}该位置?`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 获取当前用户ID
        const lastModUserId = this.$store.getters.userId || ''
        const method = row.status === '1' ? disableLocation : enableLocation
        method(row.id, lastModUserId).then(res => {
          if (res.code === '000000') {
            this.$message.success(`${action}成功`)
            // 状态变更后，可能会影响树的显示，所以也需要刷新树
            this.getTree()
            this.getList()
          } else {
            this.$message.error(res.msg || `${action}失败`)
          }
        }).catch(error => {
          console.error(`${action}操作失败`, error)
          this.$message.error(`系统错误，${action}失败`)
        })
      }).catch(() => {})
    },
    /** 分页大小改变 */
    handleSizeChange(val) {
      this.queryParams.pageSize = val
      this.getList()
    },
    /** 分页页码改变 */
    handleCurrentChange(val) {
      this.queryParams.pageNum = val
      this.getList()
    },
    /** 获取上级位置名称 */
    getParentName(parentId) {
      if (!parentId) return '无';
      
      // 先在树形数据中查找
      const findParentInTree = (tree, id) => {
        for (const node of tree) {
          if (node.id === id) {
            return node.locationCode + '-' + node.locationName;
          }
          if (node.children && node.children.length > 0) {
            const found = findParentInTree(node.children, id);
            if (found) return found;
          }
        }
        return null;
      };
      
      const parentName = findParentInTree(this.locationTree, parentId);
      if (parentName) return parentName;
      
      // 如果在树中没找到，可能在列表数据中
      const parent = this.locationList.find(item => item.id === parentId);
      return parent ? (parent.locationCode + '-' + parent.locationName) : '未知';
    },
    /** 多选选中项改变 */
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    /** 批量删除按钮操作 */
    handleBatchDelete() {
      if (this.multipleSelection.length === 0) {
        this.$message.warning('请至少选择一个位置')
        return
      }
      
      this.$confirm('是否确认删除选中的位置?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 获取选中的位置ID列表
        const selectedIds = this.multipleSelection.map(item => item.id)
        // 获取当前用户ID
        const lastModUserId = this.$store.getters.userId || ''
        
        // 执行批量删除操作
        this.loading = true
        delLocationBatch(selectedIds, lastModUserId).then(res => {
          if (res.code === '000000') {
            this.$message.success('批量删除成功')
            // 重新获取树形结构，确保更新多级结构
            this.getTree()
            this.getList()
          } else {
            this.$message.error(res.msg || '批量删除失败')
          }
          this.loading = false
        }).catch(error => {
          console.error('批量删除操作失败', error)
          this.$message.error('系统错误，批量删除失败')
          this.loading = false
        })
      }).catch(() => {})
    },
    /** 展开所有节点 */
    expandAll() {
      const allKeys = this.getExpandedKeys(this.locationTree)
      this.defaultExpandedKeys = allKeys
      this.$nextTick(() => {
        if (this.$refs.locationTree) {
          this.$refs.locationTree.$forceUpdate()
        }
      })
    },
    /** 收起所有节点 */
    collapseAll() {
      this.defaultExpandedKeys = []
      this.$nextTick(() => {
        if (this.$refs.locationTree) {
          this.$refs.locationTree.$forceUpdate()
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  .tree-container {
    background-color: #fff;
    padding: 15px;
    margin-bottom: 20px;
    border-radius: 4px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
    height: calc(100vh - 140px);
    overflow-y: auto;
  }
  
  .tree-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 5px;
  }
  
  .tree-title {
    font-size: 15px;
    font-weight: 500;
    color: #303133;
  }
  
  .tree-actions {
    display: flex;
    gap: 8px;
  }
  
  .tree-divider {
    margin: 5px 0 15px;
  }

  .box-card {
    margin-bottom: 20px;
  }

  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
  
  .node-count {
    font-size: 12px;
    color: #909399;
    margin-left: 5px;
  }

  .pagination {
    margin-top: 15px;
    text-align: right;
  }

  /* 让所有输入框和下拉框保持一致宽度 */
  .el-input, .el-select, .el-textarea {
    width: 100%;
  }

  /* 确保所有表单元素的高度和边距一致 */
  ::v-deep .el-form-item {
    margin-bottom: 18px;

    .el-form-item__content {
      line-height: 36px;
    }
  }

  /* 确保el-select和普通输入框宽度一致 */
  ::v-deep .el-select, ::v-deep .el-tree-select {
    width: 100%;
  }

  /* 树形选择器样式优化 */
  ::v-deep .el-tree-select .el-select-dropdown__item {
    height: auto;
    padding: 0;
  }
  
  /* 树节点样式优化 */
  ::v-deep .el-tree-node__content {
    height: 32px;
  }
  
  ::v-deep .el-tree-node__expand-icon {
    padding: 6px;
  }
}
</style> 