<template>
  <div class="unit-converter" :style="{ width: width + 'px' }">
    <!-- 数值输入框 -->
    <input v-model.number="inputValue" :disabled="inputDisable" class="input-field" type="number" ref="inputRef"
      :style="{ width: inputWidth + 'px', height: height + 'px' }" @change="handleInputChange" @focus="selectAllText" />
    <!-- 单位标签 -->
    <span v-if="enableConvert" ref="unitLabel" @click="cycleUnit" @dblclick="toggleUnitSelector" class="unit-label"
      :style="{ color: 'blue', height: height + 'px' }">
      {{ textUnitName }}
    </span>
    <span v-else ref="unitLabel" class="unit-label" :style="{ color: 'blue', height: height + 'px' }">
      {{ textUnitName }}
    </span>
    <!-- 单位选择弹出窗口 -->
    <div v-if="showUnitSelector" class="unit-selector" ref="unitSelector"
      :style="{ left: unitSelectorLeft + 'px', top: unitSelectorTop + 'px' }">
      <div v-for="unit in sortedUnits" :key="unit.id" @click="selectUnit(unit)" class="unit-option">
        {{ showEnglishOnly ? unit.unitName.split('(')[0] : unit.unitName }}
      </div>
    </div>
  </div>
</template>

<script>
  import {
    listSysUnitConvert
  } from '@/api/system/sysUnitConvert.js';

  export default {
    name: 'UnitConverter',
    props: {
      unitType: {
        // 当前单位类型 (required)
        type: String,
        required: true
      },
      unitOrder: {
        // 当前单位序号 (sync)
        type: Number,
        default: 0
      },
      value: {
        // 输入数值 (sync)
        type: Number,
        required: true
      },
      showEnglishOnly: {
        // 是否只显示英文
        type: Boolean,
        default: false
      },
      decimalPlaces: {
        // 小数位数
        type: Number,
        default: 5,
        validator: (v) => v >= 0 && v <= 10
      },
      width: {
        type: Number,
        required: false,
        default: 180
      },
      height: {
        type: Number,
        required: false,
        default: 32
      },
      enableConvert: {
        //是否能够进行单位换算
        type: Boolean,
        default: true
      },
      userDefined: {
        //自定义输入单位显示
        type: Boolean,
        default: false
      },
      userDefinedunitName: {
        //自定义输入单位显示
        type: String,
        default: ''
      },
      inputDisable: {
        type: Boolean,
        required: false,
        default: false
      }
    },
    mounted() {
      this.$nextTick(() => {
        this.updateInputWidth();
      });
      // 在挂载时添加全局点击事件监听器
      document.addEventListener('click', this.handleClickOutside);

    },
    beforeUnmount() {
      // 在组件销毁前移除全局点击事件监听器
      document.removeEventListener('click', this.handleClickOutside);
    },
    data() {
      return {
        inputValue: this.value,
        unitData: [], // 原始单位数据
        showUnitSelector: false, // 显示选择器
        currentUnit: null, // 当前选中单位
        baseUnit: null, // 基准单位
        inputWidth: 120, //输入框的宽度
        textUnitName: '',
        unitSelectorLeft: 0,
        unitSelectorTop: 0,
        // 新增三个数据项
        originalValue: this.value, // 原始输入值
        originalUnit: null, // 原始输入单位
        isInternalUpdate: false // 更新锁定标志
      };
    },
    computed: {
      // 显示的单位文本
      displayUnitText() {
        if (!this.currentUnit) return '';
        return this.showEnglishOnly ? this.currentUnit.unitName.split('(')[0].trim() : this.currentUnit.unitName;
      },

      // 当前类型的单位列表（按unitOrder排序）
      sortedUnits() {
        return this.unitData.filter((u) => u.unitType === this.unitType).sort((a, b) => a.unitOrder - b.unitOrder);
      },

      // 弹窗定位样式
      popupPosition() {
        if (!this.$refs.unitLabel) return {};
        const rect = this.$refs.unitLabel.getBoundingClientRect();
        return {
          top: `${rect.bottom + window.scrollY}px`,
          left: `${rect.left + window.scrollX}px`
        };
      }
    },
    watch: {
      // 监听单位类型变化
      unitType: {
        immediate: true,
        async handler(newType) {
          if (this.userDefined) {
            this.textUnitName = this.userDefinedunitName;
            this.$nextTick(() => {
              this.updateInputWidth();
            });
          } else {
            await this.loadUnits(newType);
            this.initCurrentUnit();
          }
        }
      },

      // 监听外部单位序号变化
      unitOrder(newOrder) {
        if (this.userDefined) {
          this.textUnitName = this.userDefinedunitName;
          this.$nextTick(() => {
            this.updateInputWidth();
          });
        } else {
          const target = this.sortedUnits.find((u) => u.unitOrder === newOrder);
          if (target) this.currentUnit = target;
          this.textUnitName = this.showEnglishOnly ? target.unitName.split('(')[0].trim() : target.unitName;
          this.$nextTick(() => {
            this.updateInputWidth();
          });
        }
      },

      // 监听输入值变化
      value(newVal) {
        if (!this.isInternalUpdate) {

          // 外部更新时重置原始值
          this.originalValue = (newVal === "NaN" ? 0 : newVal);
          this.originalUnit = this.currentUnit;
          this.inputValue = (newVal === "" ? 0 : newVal);
        }
        this.isInternalUpdate = false;
      }
    },
    methods: {

      selectAllText(event) {
        // 通过 event.target 获取触发事件的 input 元素
        const input = event.target;
        // 调用 select() 方法全选文本
        input.select();
      },
      handleMouseMove(event) {
        if (this.showUnitSelector) {
          // 鼠标右下方偏移量
          const offsetX = 10;
          const offsetY = 10;
          this.unitSelectorLeft = event.clientX + offsetX;
          this.unitSelectorTop = event.clientY + offsetY;
          // 获取弹窗元素
          const unitSelector = this.$refs.unitSelector;
          if (unitSelector) {
            // 检查是否超出屏幕右边界
            if (this.unitSelectorLeft + unitSelector.offsetWidth > window.innerWidth) {
              this.unitSelectorLeft = window.innerWidth - unitSelector.offsetWidth;
            }
            // 检查是否超出屏幕下边界
            if (this.unitSelectorTop + unitSelector.offsetHeight > window.innerHeight) {
              this.unitSelectorTop = window.innerHeight - unitSelector.offsetHeight;
            }
          }
        }
      },

      updateInputWidth() {

        const spanWidth = this.$refs.unitLabel.offsetWidth + 5;
        console.log("widht", this.width, "spanWidth", spanWidth)
        this.inputWidth = this.width - spanWidth;
      },
      // 处理全局点击事件
      handleClickOutside(event) {
        if (this.$refs.unitSelector && !this.$refs.unitSelector.contains(event.target)) {
          this.showUnitSelector = false;
        }
      },
      // 切换单位选择器的显示状态
      toggleUnitSelector() {
        this.showUnitSelector = !this.showUnitSelector;

      },
      // 加载单位数据
      async loadUnits(unitType) {
        try {
          const res = await listSysUnitConvert({
            unitType: unitType,
            status: 'Y'
          });
          // console.log(res);
          this.unitData = res.rows;
          this.baseUnit = this.unitData.find((u) => u.baseUnit === 'Y');
          // console.log(this.baseUnit.unitName);
        } catch (e) {
          console.error('单位数据加载失败:', e);
        }
      },

      // 初始化当前单位
      initCurrentUnit() {
        const target = this.sortedUnits.find((u) => u.unitOrder === this.unitOrder);
        this.currentUnit = target || this.baseUnit || this.sortedUnits[0];
        // 初始化时设置原始单位（关键修复）
        this.originalUnit = this.currentUnit;
        this.textUnitName = this.showEnglishOnly ? target.unitName.split('(')[0].trim() : target.unitName;
        this.$nextTick(() => {
          this.updateInputWidth();
        });
      },

      // 输入变化处理
      handleInputChange() {
        // 记录原始值和单位
        this.originalValue = this.inputValue;
        this.originalUnit = this.currentUnit;
        // console.log(this.originalValue);
        this.$emit('input', this.inputValue);
        // this.convertAndEmit();
      },

      // 循环切换单位
      // 修改单位切换方法
      cycleUnit() {
        const index = this.sortedUnits.findIndex((u) => u === this.currentUnit);
        const newUnit = this.sortedUnits[(index + 1) % this.sortedUnits.length];
        this.currentUnit = newUnit;
        this.textUnitName = this.showEnglishOnly ? newUnit.unitName.split('(')[0].trim() : newUnit.unitName;
        this.$nextTick(() => {
          this.updateInputWidth();
          this.convertAndEmit(); // 触发转换
        });
      },


      // 选择单位
      selectUnit(unit) {
        this.currentUnit = unit;
        this.showUnitSelector = false;
        this.$nextTick(() => {
          this.updateInputWidth();
          this.convertAndEmit(); // 触发转换
        });
      },

      // 执行换算并提交事件
      convertAndEmit() {
        // 移除参数
        if (!this.currentUnit || !this.baseUnit || !this.originalUnit) return;

        let newValue = 0;
        if (this.unitType === 'temperature') {
          newValue = this.handleTemperatureConversion(this.originalUnit, this.currentUnit);
        } else {
          // 通过基准单位进行两次精确转换
          const baseValue = this.originalValue / this.originalUnit.conversionFactor;
          newValue = baseValue * this.currentUnit.conversionFactor;
        }

        const roundedValue = this.roundValue(newValue);
        this.isInternalUpdate = true; // 锁定更新
        this.inputValue = roundedValue;
        this.$emit('input', roundedValue);
        this.$emit('update:unitOrder', this.currentUnit.unitOrder);

        this.$emit('conversion', {
          initialValue: this.originalValue,
          newValue: roundedValue,
          oldUnit: this.originalUnit.unitName,
          newUnit: this.currentUnit.unitName,
          oldOrder: this.originalUnit.unitOrder,
          newOrder: this.currentUnit.unitOrder
        });
      },

      // 温度单位换算
      // 温度转换调整（使用原始值）
      handleTemperatureConversion(oldUnit, newUnit) {
        const oldOrder = oldUnit.unitOrder;
        const newOrder = newUnit.unitOrder;
        // console.log(1111, this.originalValue);
        // 使用原始值计算
        let celsius;
        switch (oldOrder) {
          case 0:
            celsius = this.originalValue;
            break;
          case 1:
            celsius = ((this.originalValue - 32) * 5) / 9;
            break;
          case 2:
            celsius = this.originalValue - 273.15;
            break;
          default:
            throw new Error('无效温度单位');
        }

        switch (newOrder) {
          case 0:
            return celsius;
          case 1:
            return (celsius * 9) / 5 + 32;
          case 2:
            return celsius + 273.15;
          default:
            throw new Error('无效温度单位');
        }
      },

      // 四舍六入五成双
      roundValue(value) {
        const multiplier = Math.pow(10, this.decimalPlaces);
        const val = value * multiplier;
        const intVal = Math.trunc(val);
        const decimalPart = val - intVal;
        if (decimalPart < 0.5) {
          return intVal / multiplier;
        } else if (decimalPart > 0.5) {
          return (intVal + 1) / multiplier;
        } else {
          return intVal % 2 === 0 ? intVal / multiplier : (intVal + 1) / multiplier;
        }
      }
    }
  };
</script>

<style scoped>
  .unit-converter {
    display: flex;
    align-items: center;
    gap: 2px;
    position: relative;
  }

  .input-field {
    border: 1px solid #d6d5d5;
    border-radius: 4px;
    font-size: 14px;
  }

  .unit-label {
    cursor: pointer;
    font-weight: bold;
    border: 1px solid #d6d5d5;
    border-radius: 4px;
    font-size: 12px;
    padding-left: 10px;
    padding-right: 5px;
    white-space: nowrap;
  }

  .unit-label:hover {
    background: #f0f8ff;
  }

  .unit-selector {
    /* 设置容器的最大高度，当内容超出这个高度时会出现滚动条 */
    max-height: 100px;
    /* 超出内容时显示纵向滚动条 */
    overflow-y: auto;
    /* 横向内容不溢出，隐藏多余部分 */
    overflow-x: hidden;
    /* 其他样式保持不变 */
    position: absolute;
    z-index: 9999;
    background-color: white;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    padding: 2px 0;
    min-width: 200px;
    list-style-type: none;
    margin-left: 100px;
  }

  .unit-option {
    padding: 2px 10px;
    cursor: pointer;
    font-size: 14px;
  }

  .unit-option:hover {
    background-color: #f0f0f0;
  }
</style>
