<script lang="ts" setup>
import { sendCmd, syncSendCmd } from 'apis/system'
// import homeChart from 'assets/images/home/home-chart.svg'
import BtButton from 'components/common/BTButton/index.vue'
import CascadingSelectModal from 'components/common/CascadingSelectModal/index.vue'
import Config from 'components/home/config.vue'
import { getDeviceStatus } from 'libs/deviceComm'
import { FtMessageBox } from 'libs/messageBox'
import { compareJSON } from 'libs/utils'
import { cloneDeep } from 'lodash'
import { computed, onMounted, provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'

import { FtMessage } from '@/libs/message'
import { useDeviceStore } from '@/stores/deviceStore'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'

/**
 * 主页操作控制组件
 * @description 负责处理压力控制、消毒设置、图表导航等功能，协调组件间通信
 */

// 依赖注入
const configRef = ref()
provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (methods) => {
  configRef.value = methods
})

// 状态管理
const router = useRouter()
const formulaStore = useFormulaStore()
const deviceStore = useDeviceStore()
const homeStore = useHomeStore()

// 组件状态
const isModalOpen = ref(false) // 级联选择模态框是否打开
const optionsLeft = ref<System.Option[]>([]) // 压力类型选项（左列）
const optionsRight = ref<System.Option[]>([]) // 压力强度选项（右列）
const selectedValue = ref() // 选中的压力配置值
const disinfectionState = ref(homeStore.disinfectionState) // 消毒状态
const disinfectFormulaVisible = ref(false) // 消毒设置对话框是否显示
const selectedByFormulas = ref(cloneDeep(formulaStore.selectedFormulaInfo)) // 当前选中的配方信息
const pressureConfig = ref(homeStore.pressureConfig)
const defaultIntensityValue = ref()

/**
 * @hook 响应式依赖监听
 * @description 监听消毒状态和配方变化，同步更新组件状态
 */
watchEffect(() => {
  disinfectionState.value = homeStore.disinfectionState
  selectedByFormulas.value = formulaStore.selectedFormulaInfo
  pressureConfig.value = homeStore.pressureConfig
})

/**
 * @hook 生命周期钩子 - 组件挂载完成时执行
 * @description 初始化压力配置
 */
onMounted(async () => {
  const deviceInfo: Device.DeviceInfo = deviceStore.deviceInfo
  if (deviceInfo.deviceType !== useDeviceStore().deviceTypeMap.LargeSpaceDM_B) {
    await getPressureConfig() // 获取压力配置
  }
})

/**
 * @function getPressureConfig
 * @desc 获取当前压力配置信息
 */
const getPressureConfig = async () => {
  const pressureParams = {
    className: 'PipelinePressureControl',
    fnName: 'getConfig',
  }
  const res = await syncSendCmd(pressureParams)
  if (res.ackcode === 0) {
    homeStore.updatePressureConfig(res.rely)
  }
}

/**
 * @computed 计算属性 - 设备状态判断
 * @returns {boolean} - 设备是否处于空闲或已完成状态
 * @desc 控制按钮可用状态
 */
const deviceState = computed(() => {
  return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished'
})
const disinfectFormulaTitle = ref<string>('消毒设置')
/**
 * @function 打开消毒设置对话框
 * @desc 根据当前选中配方或默认配方初始化设置
 */
const onDisinfectConfig = (title: string) => {
  formulaStore.updateSelectedFormulaDataByList(selectedByFormulas.value || cloneDeep(formulaStore.defaultFormulaInfo))
  disinfectFormulaVisible.value = true
  disinfectFormulaTitle.value = title
}

/**
 * @function 导航到图表页面
 * @desc 路由跳转至消毒图表页面
 */
const onShowChart = () => {
  router.push('/home/chart')
}

/**
 * @function 保存消毒参数
 * @desc 处理表单数据保存逻辑，区分消毒中与非消毒状态
 */
const onSave = async () => {
  const formData = configRef.value?.getFormData()
  if (!formData) {
    return
  }
  formulaStore.updateSelectedFormulaDataByList(cloneDeep(formData)) // 更新选中配方

  if (!homeStore.isDeviceIdle) {
    // 消毒中时更新实时配置
    const res = await sendCmd({
      className: 'DisinfectionCtrlServiceExt',
      fnName: 'getRealtimeConfig',
      params: {},
    })
    const diff = compareJSON(res, formData)
    const diffKeys = Object.keys(diff)
    if (diffKeys.length) {
      await Promise.all(
        diffKeys.map(async (key) => {
          await setRealtimeConfig(key, diff[key].newVal)
        }),
      )
      FtMessage.success('配方修改成功')
    }
  }
  else {
    // 非消毒时保存配方
    if (formData.formula_id) {
      formulaStore.updateSelectedFormulaDataByList(formData)
    }
  }
  onClose() // 关闭对话框
}
console.log(onSave)

/**
 * @function 设置实时消毒参数
 * @param {string} key - 参数键名
 * @param {string} val - 参数值
 * @desc 向设备发送实时参数修改指令
 */
const setRealtimeConfig = async (key: string, val: string) => {
  await syncSendCmd({
    className: 'DisinfectionCtrlServiceExt',
    fnName: 'setRealtimeConfig',
    params: { key, val },
  })
}

/**
 * @function 打开压力控制模态框
 * @desc 初始化压力类型和强度选项
 */
const onSetPressure = () => {
  // 校验设备状态
  const statusName = getDeviceStatus()
  if (statusName) {
    FtMessageBox.error(statusName)
    return
  }
  const pressureVal = pressureConfig.value
  const { typeDisplayNames, types, intensitys } = pressureVal || {}

  // 构建压力类型选项（左列）
  const leftOptions: System.Option[]
    = typeDisplayNames?.map((name: string, index: number) => ({
      label: name,
      value: types[index],
    })) || []

  // 构建压力强度选项（右列）
  const rightOptions: System.Option[] = []
  if (types?.includes('positivePressure')) {
    intensitys?.positivePressure?.forEach((intensity: string) => {
      rightOptions.push({ label: `${intensity}%`, value: intensity })
    })
  }

  optionsLeft.value = leftOptions
  optionsRight.value = rightOptions

  // 获取已经设置的压力值
  syncSendCmd({
    className: 'PipelinePressureControl',
    fnName: 'getState',
  }).then((res) => {
    if (res.ackcode === 0) {
      defaultIntensityValue.value = res.rely.intensity
      homeStore.updateDefaultIntensityValue(res.rely.intensity)
      homeStore.updateDefaultIntensityTypeValue(res.rely.type)
      isModalOpen.value = true
    }
  })
}

/**
 * @function 确认压力选择
 * @param {string|number[]} value - 选中的压力配置值（[类型, 强度]）
 * @desc 关闭模态框并更新压力配置
 */
const handleConfirm = (value: string | number[]) => {
  isModalOpen.value = false
  homeStore.updatePressure(value)
}

/**
 * @function 取消压力选择
 * @desc 关闭模态框
 */
const handleCancel = () => {
  isModalOpen.value = false
}

/**
 * @function 关闭消毒设置对话框
 * @desc 重置对话框状态
 */
const onClose = () => {
  disinfectFormulaVisible.value = false
}

const settingWidth = computed(() => {
  if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.LargeSpaceDM_B) {
    return '12rem'
  }
  return '7.5rem'
})
</script>

<template>
  <div class="home-start-opt">
    <div class="home-opt-flex">
      <div v-if="__DEVICE_TYPE__ === deviceStore.deviceTypeMap.PipeDM">
        <BtButton
          button-text="压力控制"
          text-size="1.3rem"
          border-radius="5px"
          width="7.5rem"
          text-color="#1989fa"
          height="3rem"
          @click="onSetPressure"
        />
      </div>
      <div class="home-opt-ml">
        <BtButton
          button-text="查看图表"
          text-size="1.3rem"
          border-radius="5px"
          :width="settingWidth"
          height="3rem"
          text-color="#1989fa"
          :disabled="deviceState"
          @click="onShowChart"
        />
      </div>
      <div class="home-opt-ml">
        <BtButton
          v-if="deviceState"
          button-text="消毒设置"
          text-size="1.3rem"
          border-radius="5px"
          :width="settingWidth"
          text-color="#1989fa"
          height="3rem"
          @click="onDisinfectConfig('消毒设置')"
        />
        <BtButton
          v-else
          button-text="运行参数"
          text-size="1.3rem"
          border-radius="5px"
          :width="settingWidth"
          text-color="#1989fa"
          height="3rem"
          @click="onDisinfectConfig('运行参数')"
        />
      </div>
    </div>
  </div>
  <ft-dialog v-model="disinfectFormulaVisible" :title="disinfectFormulaTitle" width="80vw">
    <div style="height: 80vh; overflow: auto">
      <Config ref="configRef" />
    </div>
    <template #footer>
      <div class="config-btn">
        <BtButton
          button-text="关闭"
          border-radius="5px"
          width="7rem"
          text-size="1.5rem"
          text-color="#1989fa"
          height="3rem"
          @click="onClose"
        />
        <!--        <BtButton -->
        <!--          bg-color="#1989fa" -->
        <!--          button-text="确认" -->
        <!--          border-radius="5px" -->
        <!--          width="7rem" -->
        <!--          text-size="1.5rem" -->
        <!--          text-color="#ffffff" -->
        <!--          height="3rem" -->
        <!--          @click="onSave" -->
        <!--        /> -->
      </div>
    </template>
  </ft-dialog>
  <CascadingSelectModal
    v-if="isModalOpen"
    :options-left="optionsLeft"
    :options="optionsRight"
    :selected-value="selectedValue"
    :default-value="defaultIntensityValue"
    placeholder="请选择"
    @confirm="handleConfirm"
    @cancel="handleCancel"
  />
</template>

<style lang="scss" scoped>
.home-start-opt {
  margin: 0.5rem;
  gap: 5px;
  width: 100%;
  .home-opt-flex {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    .home-opt-ml {
      margin-left: 5px;
    }
  }
}

.config {
  border: 1px solid red;
}
.config-btn {
  //margin-top: -3rem
}
</style>
