<template>
  <avue-tabs ref="tabsRef" :option="tabsOption" @change="tabsHandleChange"></avue-tabs>
  <InfoVxeTopBtn
    v-show="tabsValue.edit"
    :selectNum="tabsValue.dataKey ? infoSelect[tabsValue.dataKey].length : 0"
    :tabItem="tabsValue"
    :size="size"
    @cell-add="cellAddData"
    @del-data="delTableInfoData"
    @order-data="setInfoOrder"
  />
  <template v-for="tab in tabsOption.column" :key="tab.prop">
    <div v-show="tabsValue.prop === tab.prop">
      <InfoVxeTable
        v-model="infoData[tab.dataKey]"
        :ref="(el) => (tableRefObj[tab.prop] = el)"
        :tabItem="tab"
        :column="tableInfoOption.infoColumn[`${tab.key}Column`]"
        @selection-change="infoSelectionChange"
        @cell-click="cellClick"
        @dropdown-command="dorpdownHandleCommand"
      ></InfoVxeTable>
    </div>
  </template>
  <DesignPopup
    v-model="optionsDialog.dialog.value"
    v-bind="optionsDialog.dialog"
    :isBodyFull="true"
  >
    <template #default>
      <template v-for="(control, key) in optionComponents" :key="key">
        <component
          :ref="(el) => (optionRef[key] = el)"
          v-if="key == optionsDialog.controlType"
          :is="control"
          v-model="optionsDialog.controlValue"
          v-bind="optionsDialog.controlData"
          :show="optionsDialog.dialog.value"
        ></component>
      </template>
    </template>
  </DesignPopup>
</template>

<script setup lang="ts">
import { SqlOption, InfoVxeTable, InfoVxeTopBtn } from '../../tableDesign/components'
import { MonacoEditor } from '@/components/MonacoEditor/index'
import { tableInfoOption, dicObj } from '../designData'
import { formattingLengStr } from '@/utils/lowDesign'
import { cloneDeep } from 'lodash-es'
import * as DictDataApi from '@/api/system/dict/dict.type'

defineOptions({ name: 'TableInfo' })
const message = useMessage()

interface Props {
  formType: string
  editInfoData: any
  size: any
}
const props = withDefaults(defineProps<Props>(), {
  formType: ''
})
const tabsOption = ref({
  column: [{ label: '字段属性', prop: 'tab_field', key: 'field', dataKey: 'basics', edit: true }]
})
const tabsValue = ref(tabsOption.value.column[0])

const infoData = ref({
  basics: [] as any[]
})
const infoSelect = ref({
  basics: []
})
const tableInfoDefault = ref<any[]>([])
const optionsDialog = ref<any>({ dialog: {}, controlData: {} })
const tableRefObj = ref({})

const optionComponents = markRaw({
  sqlOption: SqlOption,
  meditor: MonacoEditor
})
const optionRef = ref({})
const tabsRef = ref()

// 父字段引用
const parentFieldMap = ref(new Map())

const fieldList = computed(() => {
  let dicData: Array<{ label: string; value: string; type: string }> = []
  infoData.value.basics.forEach((item) => {
     
    if (item.fieldCode && item.isDb == 'Y')
      dicData.push({
        label: `${item.fieldCode}${item.fieldName ? '（' + item.fieldName + '）' : ''}`,
        value: item.fieldCode,
        type: item.fieldType
      })
  })
  return dicData
})

watch(
  () => fieldList.value,
  (dicData: any) => {
    const dicDataObj = {}
    dicData.forEach(({ value, label }) => (dicDataObj[value] = label))
  }
)

const dorpdownHandleCommand = (command) => {
  let { dataKey } = tabsValue.value
  if (!dataKey) return
  let { index, type } = command
  if (type == 'up' || type == 'down') {
    const delItem = infoData.value[dataKey].splice(index, 1)[0]
    nextTick(() => infoData.value[dataKey].splice(type == 'up' ? index - 1 : index + 1, 0, delItem))
  } else if (type == 'add') cellAddData(index + 1)
}

const setInfoOrder = () => {
  let { dataKey } = tabsValue.value
  if (!dataKey) return
  message
    .prompt('请输入序号（格式：原序号/最终序号）', '调整排序', { inputValue: '/', type: '' })
    .then(({ value }) => {
      let orderArr = value.split('/')
      if (orderArr.length == 2) {
        const delItem = infoData.value[dataKey].splice(Number(orderArr[0].trim()) - 1, 1)[0]
        nextTick(() => infoData.value[dataKey].splice(Number(orderArr[1].trim()) - 1, 0, delItem))
      } else message.error('请输入正确的格式，如：2/3')
    })
    .catch(() => {})
}

const infoSelectionChange = (selectObj) => {
  let { dataKey } = tabsValue.value
  if (!dataKey) return
  infoSelect.value[dataKey] = selectObj.records
}

const delTableInfoData = () => {
  let { dataKey, prop } = tabsValue.value
  if (!dataKey) return
  const keyArr = infoSelect.value[dataKey].map((item) => item._X_ROW_KEY)
  infoData.value[dataKey] = infoData.value[dataKey].filter(
    (item) => !keyArr.includes(item._X_ROW_KEY)
  )
  tableRefObj.value[prop].vxeTableRef.clearCheckboxRow()
  infoSelect.value[dataKey] = []
}

const tabsHandleChange = (column) => {
  tabsValue.value = column
}

const setTabsValue = (prop) => {
  tabsOption.value.column.forEach((item, index) => {
    if (item.prop == prop) {
      tabsRef.value.changeTabs(index)
    }
  })
}

const cellAddData = (addIndex) => {
  let { key, dataKey } = tabsValue.value
  if (!dataKey) return
  let addData = cloneDeep(tableInfoOption.infoDefaultData[dataKey]) || {}
  let index = infoData.value[dataKey].length
  infoData.value[dataKey].splice(addIndex === undefined ? index : addIndex, 0, addData)
  tableScrollIndex(key, index, addIndex)
}

const tableScrollIndex = (key, index, addIndex?) => {
  setTimeout(() => {
    const tableBodyDom = document.querySelector(`.${key}-vxe-table .vxe-table--body-wrapper`)
    if (tableBodyDom) {
      const bool = addIndex === undefined
      tableBodyDom.scrollTop =
        (bool ? index : addIndex) * 40 - (bool ? 0 : tableBodyDom['offsetHeight'] / 2)
    }
    tableRefObj.value[`tab_${key}`].vxeTableRef.setEditRow(
      tableRefObj.value[`tab_${key}`].vxeTableRef.getData(addIndex ? addIndex : index)
    )
  }, 300)
}

const cellClick = ({ rowIndex }) => {
  let { prop } = tabsValue.value
  // 普通行点击进入编辑状态
  tableRefObj.value[prop].vxeTableRef.setEditRow(
    tableRefObj.value[prop].vxeTableRef.getData(rowIndex)
  )
}

// 添加子字段行
const addSubFieldRow = (parentField, parentRowIndex) => {
  let { key, dataKey } = tabsValue.value
  if (!dataKey) return
  
  // 创建子字段数据
  let subFieldData = cloneDeep(tableInfoOption.infoDefaultData[dataKey]) || {}
  subFieldData.parentFieldId = parentField._X_ROW_KEY
  subFieldData.isSubField = true
  subFieldData.parentFieldName = parentField.fieldName

  parentField.hasChildren = 'Y'
  // 确保子字段不能包含子字段
  subFieldData.hasChildren = 'N'
  
  // 在父字段下方插入子字段行
  let insertIndex = parentRowIndex + 1
  infoData.value[dataKey].splice(insertIndex, 0, subFieldData)
  
  // 记录父子关系
  parentFieldMap.value.set(subFieldData._X_ROW_KEY, parentField._X_ROW_KEY)
  
  // 滚动到新添加的行并设置为编辑状态
  tableScrollIndex(key, insertIndex, insertIndex)
  
  // 给出成功提示
  nextTick(() => {
    message.success(`已为字段 "${parentField.fieldName}" 添加子字段`)  
  })
}

const initEditInfoData = () => {
  const data = tableInfoOption.formattingInitData(props.editInfoData)
  const fieldList: any[] = []
  
  // 重建父子字段关系
  const fieldCodeMap = new Map()
  
  // 第一遍遍历：建立字段编码映射
  data.infoData.forEach((item, index) => {
    if (item.fieldCode) {
      fieldCodeMap.set(item.fieldCode, { ...item, originalIndex: index })
    }
  })
  
  // 第二遍遍历：处理子字段关系
  data.infoData.forEach((item) => {
    const fieldItem = cloneDeep(item)
    
    // 如果是子字段且有父字段编码
    if (fieldItem.parentFieldCode && fieldCodeMap.has(fieldItem.parentFieldCode)) {
      fieldItem.isSubField = true
      fieldItem.parentFieldId = fieldCodeMap.get(fieldItem.parentFieldCode)._X_ROW_KEY
      // 设置父字段显示名称（只显示字段名称）
      const parentField = fieldCodeMap.get(fieldItem.parentFieldCode)
      fieldItem.parentFieldName = parentField.fieldName
      
      // 记录父子关系
      parentFieldMap.value.set(fieldItem._X_ROW_KEY, fieldItem.parentFieldId)
    }
    
    // 如果字段包含子字段，设置相应标识
    if (fieldItem.hasChildren === 'Y') {
      fieldItem.hasChildren = 'Y'
    }
    if (!!fieldItem.isHideDimension&&Object.prototype.toString.call(fieldItem.isHideDimension) == '[object String]') {
      fieldItem.isHideDimension=fieldItem.isHideDimension.split(',')
    }
    fieldList.push(fieldItem)
  })
  
  tableInfoDefault.value = data.infoData.filter((item) => {
    return false
  })
  infoData.value.basics = fieldList
}

onMounted(() => {
  tableInfoDefault.value = []
  infoData.value.basics = []
  if (props.formType != 'add') initEditInfoData()
  
  // 设置字段国际化配置的点击事件
  tableInfoOption.infoColumn.fieldColumn.labelI18n.editRender.events = {
    click: (row) => {
      nextTick(() => {
        tableRefObj.value['tab_field'].vxeTableRef.setRow(row, {
          labelI18n: formattingLengStr(row.labelI18n, row.fieldName)
        })
      })
    }
  }
  tableInfoOption.infoColumn.fieldColumn.isHideDimension.editRender.dicData = infoData.value.basics.map(({fieldCode,fieldName})=>{
    return {label:fieldName,value:fieldCode}
  })
  // 设置父字段下拉选项
  const updateParentFieldOptions = () => {
    // 获取所有parentFieldCode为空的字段作为可选父字段
    const parentFieldOptions = infoData.value.basics
      .filter(field => !field.parentFieldCode && field.fieldCode && field.fieldName)
      .map(field => ({
        label: `${field.fieldName}`,
        value: field.fieldCode
      }))
    
    // 更新父字段列的下拉选项
    tableInfoOption.infoColumn.fieldColumn.parentFieldName.editRender.dicData = parentFieldOptions
  }
  // 用于跟踪上次选中的值，避免重复触发
  let _lastSelectedValue = ''
  
  // 父字段选择事件处理
  tableInfoOption.infoColumn.fieldColumn.parentFieldName.editRender.events = {
    // 简化的change事件处理
    change: (row) => {
      console.log('父字段选择change事件触发:', row.parentFieldName);
      const selectdItem = row.parentFieldName.item;

      if(!selectdItem) return;

      // 获取选中的字段编码
      let selectedParentCode = selectdItem.value;
      console.log('选中的值:', selectedParentCode);


      _lastSelectedValue = selectedParentCode;
      
      if (selectedParentCode && selectedParentCode.trim() !== '') {
        // 检查是否在有效选项中
        const isValidOption = infoData.value.basics.some(field => 
          field.fieldCode === selectedParentCode && !field.parentFieldCode
        );
        
        if (isValidOption) {
          handleParentFieldSelection(row, selectedParentCode);
        } else {
          console.log('无效的选项:', selectedParentCode);
          // 重置无效选择
          row.parentFieldName = '';
          row.parentFieldCode = '';
          row.parentFieldId = '';
          row.isSubField = false;
          _lastSelectedValue = '';
        }
      } else {
        // 清空选择
        handleParentFieldClear(row);
        _lastSelectedValue = '';
      }
      // 更新父字段选项
      updateParentFieldOptions();
    },
    // 添加clear事件专门处理清空操作
    clear: (row) => {
      console.log('父字段清空事件触发');
      handleParentFieldClear(row);
      _lastSelectedValue = '';
      updateParentFieldOptions();
    }
  }
  
  // 处理父字段选择
  const handleParentFieldSelection = (row, selectedParentCode) => {
    // 找到选中的父字段
    const parentField = infoData.value.basics.find(field => field.fieldCode === selectedParentCode);
    if (!parentField) return;
    
    // 检查是否形成循环引用
    if (checkCircularReference(row, parentField)) {
      message.warning('不能形成循环引用！');
      // 先清空显示值，再x用清空处理函数
      handleParentFieldClear(row);
      // 强制刷新表格以确保UI更新
      nextTick(() => {
        if (tableRefObj.value && tableRefObj.value['tab_field'] && tableRefObj.value['tab_field'].vxeTableRef) {
          tableRefObj.value['tab_field'].vxeTableRef.refreshColumn();
        }
      });
      
      return;
    }
    
    // 保存旧的父字段信息用于清理
    const oldParentFieldCode = row.parentFieldCode;
    
    // 设置当前字段的父子关系
    row.parentFieldCode = selectedParentCode;
    row.parentFieldId = parentField._X_ROW_KEY;
    row.isSubField = true;
    row.parentFieldName = parentField.fieldName; // 显示选中的字段名称
    
    // 设置父字段的hasChildren为'Y'
    parentField.hasChildren = 'Y';
    
    // 清理旧父字段的关系
    if (oldParentFieldCode && oldParentFieldCode !== selectedParentCode) {
      const oldParentField = infoData.value.basics.find(field => field.fieldCode === oldParentFieldCode);
      if (oldParentField) {
        const hasOtherChildren = infoData.value.basics.some(child => 
          child.parentFieldCode === oldParentFieldCode && child !== row
        );
        if (!hasOtherChildren) {
          oldParentField.hasChildren = 'N';
        }
      }
    }
    
    message.success(`已将 "${row.fieldName}" 设置为 "${parentField.fieldName}" 的子字段`);
  };
  
  // 处理父字段清空
  const handleParentFieldClear = (row) => {
    const oldParentFieldCode = row.parentFieldCode;
    
    // 清空所有父子关系相关字段
    row.parentFieldCode = '';
    row.parentFieldId = '';
    row.parentFieldName = '';
    row.isSubField = false;
    
    // 清理旧父字段的关系
    if (oldParentFieldCode) {
      const oldParentField = infoData.value.basics.find(field => field.fieldCode === oldParentFieldCode);
      if (oldParentField) {
        const hasOtherChildren = infoData.value.basics.some(child => 
          child.parentFieldCode === oldParentFieldCode && child !== row
        );
        if (!hasOtherChildren) {
          oldParentField.hasChildren = 'N';
        }
      }
    }
  };
  
  // 检查循环引用
  const checkCircularReference = (childField, parentField) => {
    // 如果子字段本身就是父字段，则不允许
    if (childField.fieldCode === parentField.fieldCode) {
      return true
    }
    
    // 检查父字段是否已经是该子字段的子字段
    let currentParent = parentField
    while (currentParent && currentParent.parentFieldCode) {
      if (currentParent.parentFieldCode === childField.fieldCode) {
        return true
      }
      currentParent = infoData.value.basics.find(field => field.fieldCode === currentParent.parentFieldCode)
    }
    
    return false
  }
  
  // 监听数据变化，更新父字段选项
  watch(() => infoData.value.basics, updateParentFieldOptions, { deep: true })
  
  // 监听字段名称变化，同步更新父字段显示
  watch(() => infoData.value.basics, (newBasics) => {
    newBasics.forEach(field => {
      if (field.parentFieldCode) {
        const parentField = newBasics.find(f => f.fieldCode === field.parentFieldCode)
        if (parentField) {
          // 更新为被选择字段的fieldName
          field.parentFieldName = parentField.fieldName
        }
      }
    })
    updateParentFieldOptions()
  }, { deep: true })
  
  // 初始化父字段选项
  updateParentFieldOptions()
  
  // 设置字典Code的下拉选项
  DictDataApi.getSimpleDictTypeList().then((dicData) => {
    const dicObj = {}
    dicData = dicData.map(({ type, name }) => {
      dicObj[type] = `${type}（${name}）`
      return { label: dicObj[type], value: type }
    })
    Object.assign(tableInfoOption.infoColumn.fieldColumn.dictCode.editRender, { dicData, dicObj })
  })
  
  // 为主字段列添加点击事件处理添加子字段按钮
  tableInfoOption.infoColumn.fieldColumn.hasChildren.editRender.events = {
    click: (row) => {
      // 子字段不显示按钮，这个检查主要是保险
      if (row.isSubField === true) {
        return
      }
      
      // 获取当前行的索引
      const currentIndex = infoData.value.basics.findIndex(item => item._X_ROW_KEY === row._X_ROW_KEY)
      if (currentIndex !== -1) {
        addSubFieldRow(row, currentIndex)
      }
    }
  }
  
  // 动态控制包含子字段选项的禁用状态
  tableInfoOption.infoColumn.fieldColumn.hasChildren.editRender.disabled = (row) => {
    // 子字段不能包含子字段
    return row.isSubField === true
  }
})

defineExpose({
  infoData,
  tableInfoDefault,
  fieldList,
  tableRefObj,
  setTabsValue,
  tableScrollIndex,
  initEditInfoData,
  parentFieldMap
})
</script>

<style lang="scss">
.low-summary-buttom-sql__popover {
  .el-popper__arrow {
    left: 20px !important;
  }
}

// 为子字段的子字段列添加特殊样式
::v-deep(.field-vxe-table) {
  .vxe-body--column {
    &[field="hasChildren"] {
      .vxe-cell {
        // 为子字段添加视觉提示
        .is-sub-field {
          text-align: center;
          color: #909399;
          font-size: 14px;
        }
      }
    }
  }
}
</style>
<style lang="scss" scoped>
::v-deep(.virtual-hide-row) {
  display: none;
}
</style>
