<template>
  <div class="editable-table">
    <el-form
      ref="formRef"
      :model="{}"
      label-width="120px"
      size="small"
    >
      <el-table
        :data="internalData"
        border
        style="width: 100%"
        :row-style="{ height: '48px' }"
        :cell-style="{ padding: '6px 0' }"
      >
        <el-table-column
          v-for="field in rowConfig"
          :key="field.prop"
          :label="field.label"
          :width="field.width"
          :min-width="field.minWidth"
        >
          <template #default="{ row }">
            <component
              :is="getFieldComponent(field.type)"
              v-bind="getFieldProps(field, row.data)"
              @update:model-value="val => handleFieldChange(val, field, row)"
              @option-change="option => handleOptionChange(option, field, row)"
              @focus="() => loadRemoteOptions(field)"
              @filter-change="keyword => handleFilterChange(keyword, field)"
              :disabled="!!field.disabled || disabled"
            />
          </template>
        </el-table-column>

        <el-table-column label="操作" width="100" fixed="right">
          <template #default="{ $index }">
            <el-button
              type="danger"
              size="small"
              link
              @click="removeRow($index)"
              :disabled="disabled"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-button
        type="primary"
        size="small"
        style="margin-top: 12px"
        @click="addRow"
        :disabled="disabled"
      >
        添加一行
      </el-button>
      <!-- <el-button
        type="success"
        size="small"
        style="margin-left: 12px"
        @click="batchSave"
        :disabled="disabled"
      >
        批量保存
      </el-button> -->
    </el-form>
  </div>
</template>

<script setup>
import { ref, watch, nextTick } from 'vue'
import SelectField from '@/components/csf-form/fields/SelectField.vue'
import InputField from '@/components/csf-form/fields/InputField.vue'
import UploadField from '@/components/csf-form/fields/UploadField.vue'
import { deepEqual } from '@/utils/csf-deepEqual'
import request from '@/utils/request'
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  rowConfig: {
    type: Array,
    required: true
  },
  disabled: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue', 'batch-save'])

const formRef = ref()
const internalData = ref([])

// 远程加载状态 & 缓存
const remoteLoading = ref({})
const optionsCache = ref(new Map()) // prop -> options

// 初始化 internalData
watch(
  () => props.modelValue,
  (newVal) => {
    if (!Array.isArray(newVal)) {
      console.warn('[EditableTable] modelValue is not an array, reset to empty array')
      internalData.value = []
      return
    }

    const currentPlain = internalData.value.map(row => {
      const { id, ...rest } = row.data
      return { ...rest, id: row.id }
    })

    if (!deepEqual(newVal, currentPlain)) {
      internalData.value = newVal.map((item, index) => ({
        id: item.id || Symbol(`row-${index}`),
        data: { ...(item || {}) }
      }))
    }
  },
  { immediate: true }
)

// 同步 internalData → modelValue
let isEmitting = false
watch(
  internalData,
  (newVal) => {
    if (isEmitting) return

    const plainData = newVal.map(row => {
      const { id, ...rest } = row.data
      return { ...rest, id: row.id }
    })

    if (!deepEqual(plainData, props.modelValue)) {
      isEmitting = true
      emit('update:modelValue', plainData)
      nextTick(() => {
        isEmitting = false
      })
    }
  },
  { deep: true }
)

// 字段组件映射
function getFieldComponent(type) {
  switch (type) {
    case 'select':
      return SelectField
    case 'input':
      return InputField
    case 'upload':
      return UploadField
    default:
      return InputField
  }
}

// 获取字段属性
function getFieldProps(field, rowData) {
  const base = {
    modelValue: rowData[field.prop],
    'onUpdate:modelValue': (val) => {
      rowData[field.prop] = val
    }
  }

  switch (field.type) {
    case 'select':
      return {
        ...base,
        multiple: !!field.multiple,
        clearable: true,
        filterable: true,
        loading: remoteLoading.value[field.prop] || false,
        options: optionsCache.value.get(field.prop) || field.options || [],
        placeholder: field.placeholder || `请选择${field.label}`
      }
    case 'input':
      return {
        ...base,
        placeholder: field.placeholder || `请输入${field.label}`
      }
    case 'upload':
      return {
        ...base,
        uploadUrl: field.uploadUrl,
        maxCount: field.maxCount || 1,
        showFileList: field.showFileList !== false
      }
    default:
      return base
  }
}

// 处理字段变更（基础）
function handleFieldChange(val, field, row) {
  row.data[field.prop] = val
}

// 处理 select 选中（带完整 option）
function handleOptionChange(option, field, row) {
  if (!option || !field.onChangeExtraFields) return

  // 兼容对象和数组格式
  let extras = []
  if (Array.isArray(field.onChangeExtraFields)) {
    extras = field.onChangeExtraFields
  } else if (typeof field.onChangeExtraFields === 'object') {
    extras = Object.entries(field.onChangeExtraFields).map(([targetProp, sourceKey]) => ({
      targetProp,
      sourceKey
    }))
  }

  for (const { targetProp, sourceKey } of extras) {
    if (!targetProp || sourceKey == null) continue
    const getValue = (obj, path) => path.split('.').reduce((o, k) => o?.[k], obj)
    const extraValue = getValue(option, sourceKey)
    row.data[targetProp] = extraValue
  }
}

// 加载远程选项（初始加载）
async function loadRemoteOptions(field) {
  if (!field.api || optionsCache.value.has(field.prop)) return

  const key = field.prop
  remoteLoading.value[key] = true
  try {
    const params = {
      ...(field.requestParams || {}),
      [field.keywordField || 'keyword']: ''
    }
    const res = await request(field.api, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      data: JSON.stringify(params)
    }).then(r => r)

    const list = field.transform ? field.transform(res) : (res?.data?.records || [])
    optionsCache.value.set(key, list)
  } catch (err) {
    console.error(`Failed to load options for ${field.prop}:`, err)
  } finally {
    remoteLoading.value[key] = false
  }
}

// 搜索过滤（暂不实现，可扩展）
function handleFilterChange(keyword, field) {
  // 可在此实现远程搜索
}

// 行操作
function addRow() {
  internalData.value.push({
    data: {}
  })
}

function removeRow(index) {
  internalData.value.splice(index, 1)
}

function batchSave() {
  emit('batch-save', internalData.value.map(row => ({ ...row.data, id: row.id })))
}
</script>

<style scoped>
.editable-table :deep(.el-input__wrapper),
.editable-table :deep(.el-select__wrapper) {
  box-shadow: none !important;
}
</style>