<template>
  <a-col :style="computedStyles">
    <div
      class="x-form-col-wrapper"
      :class="{ 'addLabelMinWidth': mode !== '查询' }"
      :style="computedWrapperStyles"
    >
      <slot></slot>
    </div>
  </a-col>
</template>

<script>
const BREAKPOINTS = {
  xs: 576,
  sm: 768,
  md: 992,
  lg: 1200,
  xl: 1600
}

const queryDefaultFlex = {
    xs: 24,
    sm: 12,
    md: 8,
    lg: 6,
    xl: 6,
    xxl: 6
}


const addOrEditDefaultFlex = {
  xs: 24, // 超小屏(<576px)：1个/行
  sm: 12, // 小屏(576px-768px)：2个/行
  md: 8, // 中屏(768px-992px)：3个/行
  lg: 8, // 大屏(992px-1200px)：3个/行
  xl: 6, // 超大屏(1200px-1600px)：4个/行
  xxl: 6, // 超超大屏(>1600px)：4个/行
}

function debounce (fn, delay) {
  let timeout = null
  return function (...args) {
    if (timeout) clearTimeout(timeout)
    timeout = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

export default {
  name: 'XFormCol',
  props: {
    flex: {
      type: Object,
      default: null,
    },
    occupyCol: {
      type: Number,
      default: 1,
    },
    layout: {
      type: String,
      default: 'horizontal',
    },
    labelCol: {
      type: Object,
      default: () => { return { span: 8 } }
    },
    mode: {
      type: String,
      default: '查询',
    },
    attrType: {
      type: String,
      default: '',
    }
  },
  computed: {
    // 根据mode、layout、attrType计算最终的flex值
    finalFlex () {
      // 如果外部传入了flex，优先使用外部传入的flex
      if (this.flex) {
        return this.flex
      }

      // 如果没有传入flex，根据mode、layout、attrType计算默认flex
      if (this.mode === '新增/修改') {
        if (
          ['horizontal', 'vertical'].includes(this.layout) ||
          ['textarea', 'file', 'image','signature'].includes(this.attrType)
        ) {
          // 新增修改表单 horizontal 模式下默认为一行
          return {
            xs: 24,
            sm: 24,
            md: 24,
            lg: 24,
            xl: 24,
            xxl: 24,
            fullWidth: true
          }
        } else {
          // 新增修改表单 vertical 模式下默认为1列
          return addOrEditDefaultFlex
        }
      } else {
        // 查询模式默认flex
         return queryDefaultFlex
      }
    },
    computedFlex () {
      const parentWidth = this.parentWidth
      return this.getFlex(parentWidth, this.finalFlex)
    },
    computedWrapperStyles () {
      // 修复bug: 当fullWidth为true时，应该使用finalFlex而不是defaultFlex
      const singleFlex = this.finalFlex.fullWidth
        ? this.getFlex(this.parentWidth, this.addOrEditDefaultFlex)
        : this.computedFlex

      // 2. 计算单列（occupyCol=1）的列数
      const columnsCount = 24 / singleFlex

      // 3. 计算单列的基准列宽（所有表单项统一使用此宽度计算label）
      const baseColumnWidth = this.parentWidth / columnsCount - (columnsCount - 1) * 16

      // 4. 计算label宽度（统一基于单列宽度，不考虑occupyCol）
      const labelWidth = Math.max(baseColumnWidth * (this.labelCol.span / 24), 80)

      // 5. 计算偏移量
      const offset = this.labelCol.offset ? (this.labelCol.offset / 24) * 100 : 0

      if (this.layout === 'vertical') {
        return {
          '--form-label-width': '',
          '--form-offset': ''
        }
      }

      return {
        '--form-label-width': `${labelWidth}px`,
        '--form-offset': `${offset}%`
      }
    },
    computedStyles () {
      // 使用computedFlex计算样式，确保使用正确的flex值
      const realFlex = Math.min(this.computedFlex * this.occupyCol, 24)
      const flexValue = (realFlex / 24) * 100

      return {
        flex: `0 0 ${flexValue}%`,
        maxWidth: `${flexValue}%`,
      }
    },
  },
  data () {
    return {
      parentWidth: 0,
    }
  },
  methods: {
    getFlex (parentWidth, flex = addOrEditDefaultFlex) {
      if (parentWidth === 0) {
        return flex.md
      }
      if (parentWidth < BREAKPOINTS.xs) return flex.xs
      if (parentWidth < BREAKPOINTS.sm) return flex.sm
      if (parentWidth < BREAKPOINTS.md) return flex.md
      if (parentWidth < BREAKPOINTS.lg) return flex.lg
      if (parentWidth < BREAKPOINTS.xl) return flex.xl
      return flex.xxl
    },
  },
  mounted () {
    // 根据父容器宽度响应式
    this.$nextTick(() => {
      const container = this.$el.parentNode
      this.parentWidth = container.offsetWidth
      const updateWidth = debounce((width) => {
        this.parentWidth = width
      }, 100)

      this.resizeObserver = new ResizeObserver((entries) => {
        for (const entry of entries) {
          updateWidth(entry.contentRect.width)
        }
      })
      this.resizeObserver.observe(container)
    })
  },
  beforeUnmount () {
    if (this.resizeObserver) {
      this.resizeObserver.disconnect()
    }
  },
}
</script>

<style lang="less" scoped>
.x-form-col-wrapper {
  :deep(.ant-form-item) {
    .ant-form-item-label {
      max-width: var(--form-label-width);
    }
    .ant-form-item-control-wrapper {
      width: calc(100% - var(--form-label-width) - var(--form-offset) - var(--form-offset));
    }
  }
}
.addLabelMinWidth{
  :deep(.ant-form-item) {
    .ant-form-item-label {
      min-width: var(--form-label-width);
    }
  }
}
</style>
