<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="classTree"
            :data="classTree"
            :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.classificationCode" placeholder="请输入分类编码" clearable size="small" />
            </el-form-item>
            <el-form-item label="分类名称">
              <el-input v-model="queryParams.classificationName" 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="classList" 
            border 
            stripe 
            style="width: 100%" 
            @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55" />
            <el-table-column prop="classificationCode" label="分类编码" width="150" />
            <el-table-column prop="classificationName" 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="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="classificationCode">
          <el-input v-model="form.classificationCode" placeholder="请输入分类编码" />
        </el-form-item>
        <el-form-item label="分类名称" prop="classificationName">
          <el-input v-model="form.classificationName" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="上级分类" prop="parentId">
          <el-cascader
            v-model="form.parentId"
            :options="classTreeOptions"
            :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="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 { listClassification, getClassification, addClassification, updateClassification, delClassification, enableClassification, disableClassification, getClassificationTree, checkClassificationInUse, getChildClassifications, delClassificationBatch } from '@/api/asset/classification'

export default {
  name: 'AssetClassification',
  data() {
    return {
      // 遮罩层
      loading: false,
      // 总条数
      total: 0,
      // 分类列表
      classList: [],
      // 分类树形数据
      classTree: [],
      // 处理后的树形选项数据（用于级联选择器）
      classTreeOptions: [],
      // 默认展开的节点
      defaultExpandedKeys: [],
      // 树形配置（用于树组件）
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      // 弹出层标题
      dialogTitle: '',
      // 是否显示弹出层
      dialogVisible: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        classificationCode: undefined,
        classificationName: undefined,
        status: undefined,
        parentId: undefined
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        classificationCode: [
          { required: true, message: '请输入分类编码', trigger: 'blur' },
          { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
        ],
        classificationName: [
          { 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: {
    /** 展开所有节点 */
    expandAll() {
      const allKeys = this.getExpandedKeys(this.classTree)
      this.defaultExpandedKeys = allKeys
      this.$refs.classTree.setCheckedKeys([]) // 清空选中状态
      this.$nextTick(() => {
        if (this.$refs.classTree) {
          this.$refs.classTree.$forceUpdate()
        }
      })
    },
    
    /** 收起所有节点 */
    collapseAll() {
      this.defaultExpandedKeys = []
      this.$refs.classTree.setCheckedKeys([]) // 清空选中状态
      this.$nextTick(() => {
        if (this.$refs.classTree) {
          this.$refs.classTree.$forceUpdate()
        }
      })
    },
    
    /** 获取分类树形结构 */
    getTree() {
      this.loading = true
      const params = {
        status: undefined // 获取所有状态的分类，包括启用和禁用
      }
      getClassificationTree(params).then(res => {
        if (res.code === '000000') {
          // 处理返回的树形数据，确保字段名称正确
          this.classTree = this.processTreeData(res.data)
          
          // 准备级联选择器的数据源
          this.classTreeOptions = this.prepareTreeSelectOptions(this.classTree)
          
          // 如果之前已经有展开的节点，保持这些节点展开
          // 否则只展开第一级有子节点的节点
          if (!this.defaultExpandedKeys || this.defaultExpandedKeys.length === 0) {
            this.defaultExpandedKeys = this.getFirstLevelKeys(this.classTree)
          }
          
          // 强制刷新树组件
          this.$nextTick(() => {
            if (this.$refs.classTree) {
              this.$refs.classTree.$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.classificationName || node.label || ''}`,
          // 驼峰命名
          classificationName: node.classificationName || node.label || '',
          classificationCode: node.code || '',
          status: node.status || '1',
          parentId: node.parentId || null,
          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
    },
    
    /** 查询分类列表 */
    getList() {
      this.loading = true
      listClassification(this.queryParams).then(res => {
        if (res.code === '000000') {
          // 转换API返回数据结构为驼峰命名
          this.classList = 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
      })
    },
    
    /** 转换下划线命名为驼峰命名 */
    convertSnakeToCamel(list) {
      if (!list || !Array.isArray(list)) return []
      
      return list.map(item => {
        return {
          id: item.id,
          classificationCode: item.classification_code || item.classificationCode || '',
          classificationName: item.classification_name || item.classificationName || '',
          parentId: item.parent_id || item.parentId || null,
          status: item.status || '1',
          remark: item.remark || '',
          createTime: item.create_time || item.createTime || '',
          createUserId: item.create_user_id || item.createUserId || '',
          lastModUserId: item.last_mod_user_id || item.lastModUserId || '',
          lastModTime: item.last_mod_time || item.lastModTime || ''
        }
      })
    },
    
    /** 将驼峰命名转换为下划线命名(API请求前的转换) */
    convertCamelToSnake(data) {
      const result = {}
      
      Object.keys(data).forEach(key => {
        // 将驼峰转换为下划线
        const newKey = key.replace(/([A-Z])/g, '_$1').toLowerCase()
        result[newKey] = data[key]
      })
      
      return result
    },
    
    /** 节点单击事件 */
    handleNodeClick(data) {
      this.queryParams.parentId = data.id
      // 使用新的获取子分类API
      this.loading = true
      getChildClassifications(data.id, {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      }).then(res => {
        if (res.code === '000000') {
          this.classList = 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,
        classificationCode: undefined,
        classificationName: undefined,
        status: undefined,
        parentId: undefined
      }
      this.getList()
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.dialogTitle = '新增分类'
      this.form = {
        classificationCode: '',
        classificationName: '',
        parentId: this.queryParams.parentId || '', // 如果当前有选中节点，则默认为父节点
        status: '1',
        remark: ''
      }
      this.dialogVisible = true
      this.$nextTick(() => {
        if (this.$refs.form) {
          this.$refs.form.clearValidate()
        }
      })
    },
    /** 修改按钮操作 */
    handleEdit(row) {
      const id = row.id
      getClassification(id).then(res => {
        if (res.code === '000000') {
          // 将API响应数据映射到表单字段，使用驼峰命名
          this.form = {
            id: res.data.id,
            classificationCode: res.data.classificationCode,
            classificationName: res.data.classificationName,
            parentId: res.data.parentId || '',
            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,
            classificationCode: this.form.classificationCode,
            classificationName: this.form.classificationName,
            parentId: this.form.parentId,
            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.$store.getters.userId || ''
          }
          
          const method = this.form.id ? updateClassification : addClassification
          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(() => {
        // 先检查分类是否被使用
        checkClassificationInUse(row.id).then(res => {
          if (res.code === '000000' && res.data) {
            this.$message.error('该分类已被使用，无法删除')
            return
          }
          // 未被使用，执行删除操作
          const lastModUserId = this.$store.getters.userId || ''
          delClassification(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' ? disableClassification : enableClassification
        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.classificationCode + '-' + node.classificationName;
          }
          if (node.children && node.children.length > 0) {
            const found = findParentInTree(node.children, id);
            if (found) return found;
          }
        }
        return null;
      };
      
      const parentName = findParentInTree(this.classTree, parentId);
      if (parentName) return parentName;
      
      // 如果在树中没找到，可能在列表数据中
      const parent = this.classList.find(item => item.id === parentId);
      return parent ? (parent.classificationCode + '-' + parent.classificationName) : '未知';
    },
    /** 多选选中项改变 */
    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
        delClassificationBatch(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(() => {})
    }
  }
}
</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> 