<template>
  <div class="panel-tab__content">
    <a-table
      :dataSource="elementPropertyList"
      :columns="columns"
      size="small"
      :pagination="false"
      bordered
      :scroll="{ y: 240 }"
    >
      <template #bodyCell="{ column, record, index }">
        <template v-if="column.key === 'index'">
          {{ index + 1 }}
        </template>
        <template v-if="column.key === 'operation'">
          <a-button size="small" type="link" @click="openAttributesForm(record, index)">
            编辑
          </a-button>
          <a-divider type="vertical" />
          <a-button size="small" type="link" danger @click="removeAttributes(record, index)">
            移除
          </a-button>
        </template>
      </template>
    </a-table>
    <div class="element-drawer__button">
      <a-button size="small" type="primary" @click="openAttributesForm(null, -1)">
        <template #icon><plus-outlined /></template>
        添加属性
      </a-button>
    </div>

    <a-modal
      v-model:open="propertyFormModelVisible"
      title="属性配置"
      width="600px"
      :getContainer="false"
      :destroyOnClose="true"
      @cancel="handleCancel"
      @ok="saveAttribute"
    >
    <div style="margin:10px;"> 
      <a-form
          :model="propertyForm"
          layout="vertical"
          size="small"
          ref="attributeFormRef"
        >
        <a-form-item label="属性名：" name="name" :rules="[{ required: true, message: '请输入属性名' }]">
          <a-input v-model:value="propertyForm.name" allow-clear />
        </a-form-item>
        <a-form-item label="属性值：" name="value" :rules="[{ required: true, message: '请输入属性值' }]">
          <a-input v-model:value="propertyForm.value" allow-clear />
        </a-form-item>
      </a-form>
    </div>  
      <template #footer>
        <a-button size="small" @click="propertyFormModelVisible = false">取 消</a-button>
        <a-button size="small" type="primary" @click="saveAttribute">确 定</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch, reactive, nextTick, onMounted } from 'vue'
import { Modal, message } from 'ant-design-vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { StrUtil } from "../common/StrUtil"
import { Form } from 'ant-design-vue'
import { useModelerStore } from '../store/modeler-store.js'

interface PropertyItem {
  name: string
  value: string
}

interface PropertyForm {
  name?: string
  value?: string
}

const props = defineProps<{
  id: string
}>()

const useForm = Form.useForm
const elementPropertyList = ref<PropertyItem[]>([])
const otherExtensionList = ref<any[]>([])
const bpmnElementPropertyList = ref<any[]>([])
const bpmnElement = ref<any>(null)
const propertyForm = reactive<PropertyForm>({})
const editingPropertyIndex = ref(-1)
const propertyFormModelVisible = ref(false)
const attributeFormRef = ref()

// 表格列定义
const columns = [
  {
    title: '序号',
    key: 'index',
    width: '50px'
  },
  {
    title: '属性名',
    dataIndex: 'name',
    key: 'name',
    ellipsis: true,
    width: '100px'
  },
  {
    title: '属性值',
    dataIndex: 'value',
    key: 'value',
    ellipsis: true,
    width: '100px'
  },
  {
    title: '操作',
    key: 'operation',
    width: '90px'
  }
]

const modelerStore = useModelerStore()

// 在组件挂载时初始化
onMounted(() => {
  resetAttributesList()
})

// 监听 id 变化
watch(() => props.id, (val) => {
  if (StrUtil.isNotBlank(val)) {
    resetAttributesList()
  }
})

// 监听元素变化
watch(() => modelerStore.element, (newElement) => {
  if (newElement) {
    resetAttributesList()
  }
})

// 重置属性列表
const resetAttributesList = () => {
  console.log('重置属性列表，当前元素:', modelerStore.element)
  
  bpmnElement.value = modelerStore.element
  otherExtensionList.value = []
  
  if (!bpmnElement.value?.businessObject) {
    elementPropertyList.value = []
    bpmnElementPropertyList.value = []
    return
  }
  
  const extensionElements = bpmnElement.value.businessObject?.extensionElements
  
  // 查找 flowable:Properties
  const bpmnElementProperties = extensionElements?.values?.filter((ex: any) => {
    if (ex.$type !== 'flowable:Properties') {
      otherExtensionList.value.push(ex)
      return false
    }
    return true
  }) ?? []

  console.log('找到的属性元素:', bpmnElementProperties)

  // 保存所有的扩展属性字段
  bpmnElementPropertyList.value = bpmnElementProperties.reduce((pre: any[], current: any) => 
    pre.concat(current.values || []), [])

  // 复制用于显示
  elementPropertyList.value = JSON.parse(JSON.stringify(bpmnElementPropertyList.value.map((prop: any) => ({
    name: prop.name,
    value: prop.value
  })) ?? []))

  console.log('提取的属性列表:', elementPropertyList.value)
}

// 打开属性表单
const openAttributesForm = (attr: PropertyItem | null, index: number) => {
  editingPropertyIndex.value = index
  if (index === -1) {
    propertyForm.name = ''
    propertyForm.value = ''
  } else {
    propertyForm.name = attr?.name || ''
    propertyForm.value = attr?.value || ''
  }
  propertyFormModelVisible.value = true
  nextTick(() => {
    if (attributeFormRef.value) {
      attributeFormRef.value.clearValidate()
    }
  })
}

// 移除属性
const removeAttributes = (attr: PropertyItem, index: number) => {
  Modal.confirm({
    title: '提示',
    content: '确认移除该属性吗？',
    okText: '确认',
    cancelText: '取消',
    onOk: () => {
      elementPropertyList.value.splice(index, 1)
      bpmnElementPropertyList.value.splice(index, 1)
      
      // 使用安全的更新方式
      updateElementProperties()
      message.success('移除成功')
    },
    onCancel: () => {
      console.info('操作取消')
    }
  })
}

// 保存属性
const saveAttribute = async () => {
  try {
    // 验证表单
    if (!propertyForm.name || !propertyForm.value) {
      message.warning('请填写完整信息')
      return
    }

    // 检查属性名是否已存在
    const existingIndex = elementPropertyList.value.findIndex((item, index) => 
      item.name === propertyForm.name && index !== editingPropertyIndex.value
    )
    if (existingIndex !== -1) {
      message.warning('属性名已存在')
      return
    }

    if (editingPropertyIndex.value !== -1) {
      // 编辑现有属性
      const updatedProperty = { name: propertyForm.name, value: propertyForm.value }
      elementPropertyList.value[editingPropertyIndex.value] = updatedProperty
      
      // 更新实际的属性对象
      if (bpmnElementPropertyList.value[editingPropertyIndex.value]) {
        bpmnElementPropertyList.value[editingPropertyIndex.value].name = updatedProperty.name
        bpmnElementPropertyList.value[editingPropertyIndex.value].value = updatedProperty.value
      }
    } else {
      // 添加新属性
      const newProperty = { name: propertyForm.name, value: propertyForm.value }
      elementPropertyList.value.push(newProperty)
      
      // 新建属性字段
      const newPropertyObject = modelerStore.moddle.create('flowable:Property', newProperty)
      bpmnElementPropertyList.value.push(newPropertyObject)
    }
    
    // 统一更新元素属性
    updateElementProperties()
    
    propertyFormModelVisible.value = false
    // 重置表单
    propertyForm.name = ''
    propertyForm.value = ''
    editingPropertyIndex.value = -1
    message.success('保存成功')
    
  } catch (error) {
    console.error('保存属性失败:', error)
    message.error('保存失败')
  }
}

// 安全的更新元素属性方法
const updateElementProperties = () => {
  if (!modelerStore.modeler || !bpmnElement.value) {
    console.warn('Modeler 或元素不可用')
    return false
  }

  try {
    const modeling = modelerStore.modeler.get('modeling')
    const moddle = modelerStore.modeler.get('moddle')
    
    if (!modeling || !moddle) {
      console.warn('Modeler 组件不可用')
      return false
    }

    // 创建 properties 元素
    let propertiesElement = null
    if (bpmnElementPropertyList.value.length > 0) {
      try {
        propertiesElement = moddle.create('flowable:Properties', {
          values: [...bpmnElementPropertyList.value]
        })
      } catch (error) {
        console.error('创建 properties 元素失败:', error)
        return false
      }
    }

    // 合并所有扩展元素
    const allExtensions = [...otherExtensionList.value]
    if (propertiesElement) {
      allExtensions.push(propertiesElement)
    }

    // 创建或更新扩展元素
    let extensionElements = null
    if (allExtensions.length > 0) {
      try {
        extensionElements = moddle.create('bpmn:ExtensionElements', {
          values: allExtensions
        })
      } catch (error) {
        console.error('创建扩展元素失败:', error)
        return false
      }
    }

    // 使用安全的属性更新方式
    try {
      // 避免直接更新可能包含只读属性的对象
      const propertiesToUpdate: any = {}
      
      // 只更新必要的属性
      if (extensionElements) {
        propertiesToUpdate.extensionElements = extensionElements
      } else {
        // 如果没有扩展元素，设置为 undefined 来移除
        propertiesToUpdate.extensionElements = undefined
      }

      // 使用建模服务更新属性
      modeling.updateProperties(bpmnElement.value, propertiesToUpdate)
      
      console.log('元素属性更新成功')
      return true
    } catch (error) {
      console.error('更新元素属性失败:', error)
      // 尝试使用备选方案
      return updateElementPropertiesFallback()
    }
  } catch (error) {
    console.error('更新元素属性失败:', error)
    return false
  }
}

// 备选更新方案
const updateElementPropertiesFallback = () => {
  try {
    const modeling = modelerStore.modeler.get('modeling')
    const moddle = modelerStore.modeler.get('moddle')
    
    // 创建新的扩展元素，避免代理问题
    const allExtensions = [...otherExtensionList.value]
    
    if (bpmnElementPropertyList.value.length > 0) {
      const propertiesElement = moddle.create('flowable:Properties', {
        values: bpmnElementPropertyList.value
      })
      allExtensions.push(propertiesElement)
    }

    const extensionElements = allExtensions.length > 0 
      ? moddle.create('bpmn:ExtensionElements', { values: allExtensions })
      : undefined

    // 使用更安全的方式更新
    modeling.updateProperties(bpmnElement.value, {
      extensionElements
    })
    
    return true
  } catch (error) {
    console.error('备选更新方案也失败:', error)
    return false
  }
}

// 取消操作
const handleCancel = () => {
  propertyFormModelVisible.value = false
  propertyForm.name = ''
  propertyForm.value = ''
  editingPropertyIndex.value = -1
}
</script>

<style lang="scss" scoped>
.panel-tab__content {
  .element-drawer__button {
    margin-top: 10px;
    text-align: center;
  }
}
</style>