<script setup lang="ts">
import { computed, nextTick, reactive, ref, onUnmounted, inject, onMounted, watch } from 'vue';
import type { Ref } from 'vue';
import { getErrorTranslate, traduction } from '@/utils/language';
import PullDownTriangle from '@/components/PullDownTriangle/PullDownTriangle.vue';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import useStore from '@/stores';
import { IFanInfo, ISpeedAdjustmentMode } from '../model/fan.datatype';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import CustomAdjustSpeed from './CustomAdjustSpeed.vue';
import { AlarmAlert } from '@/components/AlarmAlert';
import { getThermals, intelligentUpdate } from '../../Info/service/system.service';
import { IconCheckBold } from '@computing/opendesign-icons';
import {
  getIntelSpeedAdjustInfo,
  initializingIntelSpeedAdjustInfo,
} from '../utils/fan.utils';
import { IIntelSpeedAdjust, MODE_INDEX } from '../model/fan.datatype';
import { loading, showFailedMessage, showSuccessMessage, getStoreData } from '@/utils/composition';
import { rangeVerification } from '@/validators/validation-functions';
import { getGenericInfo } from '@/services/export-config-service';

const emits = defineEmits(['updateFanInfo']);

const props = defineProps({
  fanInfoList: {
    type: Array as () => IFanInfo[],
    required: true,
    default: () => {
      return [];
    },
  }
});

const store = useStore();
// 用户配置权限
const isConfigureUser = checkPrivil(UserPrivil.userConfig);
// 安全配置权限
const isOemSecurityMgmtUser = checkPrivil(UserPrivil.securityConfig);
// 远程控制权限
const isOemKvmUser = checkPrivil(UserPrivil.remoteControl);

const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const intelSpeedAdjustInfo: any = reactive({ data: {} as IIntelSpeedAdjust });
const rateModeList = computed(() => {
  const result = [
    {
      label: traduction('FAN_SET_GLOBAL'),
      value: '0',
      expectedSpeedRatio: intelSpeedAdjustInfo.data.manualLevel ? intelSpeedAdjustInfo.data.manualLevel : '20',
    },
  ];
  // 只有在手动模式下才能设置单个风扇
  if (intelSpeedAdjustInfo.data.fanMode === 'Manual') {
    result.push(...props.fanInfoList.map(item => ({ label: item.fanName, value: item.id, expectedSpeedRatio: item.expectedSpeedRatio })));
  }
  return result;
});
const fanModeList: { key: string; id: string }[] = [
  {
    key: traduction('FAN_MODE_AUTO'),
    id: 'Auto',
  },
  {
    key: traduction('FAN_MODE_CUSTEM'),
    id: 'Manual',
  },
];

// 表单校验结果
let validateResult = {
  EntireRate: true,
};

const loctFanInfo = computed(() => {return getStoreData('loct', 'fanInfo')}) as any;

const speedMode = ref([
  {
    id: 'EnergySaving',
    label: traduction('FAN_MODEL_TITLE1'),
    content: traduction('FAN_MODEL_CONTENT1'),
    isSelect: false,
    isShow: true,
  },
  {
    id: 'LowNoise',
    label: traduction('FAN_MODEL_TITLE2'),
    content: traduction('FAN_MODEL_CONTENT2'),
    isSelect: false,
    isShow: true,
  },
  {
    id: 'HighPerformance',
    label: traduction('FAN_MODEL_TITLE3'),
    content: traduction('FAN_MODEL_CONTENT3'),
    isSelect: false,
    isShow: true,
  },
  {
    id: 'LiquidCooling',
    label: traduction('FAN_LIQUID_COOLING'),
    content: traduction('FAN_LIQUID_COOLING_CONTENT'),
    isSelect: false,
    isShow: true,
  },
  {
    id: 'Custom',
    label: traduction('FAN_MODEL_TITLE4'),
    content: traduction('FAN_MODEL_CONTENT4'),
    isSelect: false,
    isShow: true,
    tip: traduction('FAN_HEAT_MODE_WARNING'),
  },
] as ISpeedAdjustmentMode[]);

const showCustom = ref(false);

const selectedMode = ref();

// 保存按钮状态
const saveBtnState = ref(false);

// 自定义模式参数是否正确
let hasError = false;

const mpcShow = ref(false);

const modelPredictiveControlEnabled = ref(false);

const fanHeatForm = reactive({
  fanMode: 'Auto',
  currentMode: '',
  rate: '20',
  rateMode: '0',
});

const fanHeatRule = reactive({
  EntireRate: {
    type: 'number',
    isInteger: true,
    required: true,
    min: 20,
    max: 100,
    message: traduction('VALID_RANGE_VALUE_ERR_MSG', [20, 100]),
    validator: rangeVerification,
    trigger: 'change',
  }
});

const popoverVisible = reactive({
  EntireRate: false,
  SingleRate: false,
});

let newCustomParam = {};

let postParam: any = {};

const initSelectedMode = (mode: string) => {
  speedMode.value.forEach(item => {
    item.isSelect = false;
  });
  switch (mode) {
    case 'EnergySaving':
      // 节能模式
      speedMode.value[MODE_INDEX.ENERGY_SAVING].isSelect = true;
      selectedMode.value = speedMode.value[MODE_INDEX.ENERGY_SAVING].id;
      break;
    case 'LowNoise':
      // 低噪音模式
      speedMode.value[MODE_INDEX.LOW_NOISE].isSelect = true;
      selectedMode.value = speedMode.value[MODE_INDEX.LOW_NOISE].id;
      break;
    case 'HighPerformance':
      // 高性能模式
      speedMode.value[MODE_INDEX.HIGH_PERFORMANCE].isSelect = true;
      selectedMode.value = speedMode.value[MODE_INDEX.HIGH_PERFORMANCE].id;
      break;
    case 'LiquidCooling':
      // 液冷模式
      speedMode.value[MODE_INDEX.LIQUID_COOLING].isSelect = true;
      selectedMode.value = speedMode.value[MODE_INDEX.LIQUID_COOLING].id;
      break;
    case 'Custom':
      // 用户自定义模式
      speedMode.value[MODE_INDEX.CUSTOM].isSelect = true;
      selectedMode.value = speedMode.value[MODE_INDEX.CUSTOM].id;
      break;
    default:
      break;
  }
};

const focus = (key: string) => {
  popoverVisible[key] = true;
};

const blur = (key: string) => {
  popoverVisible[key] = false;
};

const input = (key: string, value: string) => {
  fanHeatForm.rate = value;
  // 判断值是否与以前相同
  setSaveBtnState();
};

const changeCurrentMode = (mode: string) => {
  newCustomParam = {};
  if (mode === 'Custom') {
    showCustom.value = true;
    mointorBtn(mode, newCustomParam);
  } else {
    showCustom.value = false;
    mointorBtn(mode, {});
  }
};

const changeFanMode = (mode: string) => {
  if (mode !== intelSpeedAdjustInfo.data.fanMode) {
    saveBtnState.value = false;
  } else {
    saveBtnState.value = true;
  }
  if (mode === 'Manual') {
    fanHeatForm.rate = intelSpeedAdjustInfo.data.manualLevel;
    fanHeatForm.rateMode = '0';
  } else {
    initSelectedMode(intelSpeedAdjustInfo.data.fanSmartCoolingMode);
  }
};

const changeFanSelect = (val: string) => {
  rateModeList.value.forEach(item => {
    if (item.value === val) {
      fanHeatForm.rate = item.expectedSpeedRatio;
    }
  });
  setSaveBtnState();
};

const setSaveBtnState = () => {
  validateResult.EntireRate = rangeVerification(
    fanHeatRule.EntireRate,
    fanHeatForm.rate,
    () => {}
  );
  if (validateResult.EntireRate) {
    saveBtnState.value = false;
  } else {
    saveBtnState.value = true;
  }
};

const selected = (mode: ISpeedAdjustmentMode) => {
  speedMode.value.forEach(element => {
    element.isSelect = false;
  });
  mode.isSelect = true;
  if (mode.id === 'Custom') {
    mointorBtn(mode.id, newCustomParam);
  } else {
    mointorBtn(mode.id, {});
  }
};

const confirmSave = () => {
  if (postParam === null || postParam === undefined || postParam === '') {
    return;
  }
  if (fanHeatForm.fanMode !== intelSpeedAdjustInfo.data.fanMode) {
    postParam['FanCtrlMode'] = fanHeatForm.fanMode;
  }
  if (fanHeatForm.fanMode === 'Manual') {
    postParam['ManualLevel'] = Number(fanHeatForm.rate);
    if (fanHeatForm.rateMode !== '0') {
      // 设置单个风扇的期望速率比
      let fanId = '';
      rateModeList.value.forEach(item => {
        if (item.value === fanHeatForm.rateMode) {
          fanId = item.value;
        }
      });
      const param = {
        FanId: Number(fanId),
        ExpectedSpeedRatio: Number(fanHeatForm.rate),
      };
      intelligentUpdate(param).then(
        res => {
          if (res.data.error) {
            showFailedMessage(getErrorTranslate(res.data.error[0]?.code));
          } else {
            showSuccessMessage();
          }
        },
        error => {
          showFailedMessage(getErrorTranslate(error?.data?.error[0]?.code));
        },
      ).finally(() => {
        initSetData();
      });
      return;
    }
  } else {
    if (postParam['ManualLevel']) {
      Reflect.deleteProperty(postParam, 'ManualLevel');
    }
  }
  intelligentUpdate(postParam).then(
    res => {
      if (res.data.error) {
        showFailedMessage(getErrorTranslate(res.data.error[0]?.code));
        initSetData();
      } else {
        showSuccessMessage();
        initSetData();
      }
    },
    error => {
      showFailedMessage(getErrorTranslate(error?.data?.error[0]?.code));
      initSetData();
    },
  );
};

const cancelEditor = () => {
  getFanMode(intelSpeedAdjustInfo.data);
};

const selectCustom = (result: boolean, param: any) => {
  hasError = !result;
  if (result) {
    mointorBtn('Custom', param);
  } else {
    saveBtnState.value = true;
  }
};

const selectEnergy = () => {
  if (fanHeatForm.currentMode === 'Custom') {
    return;
  }
  nextTick(() => {
    if (postParam) {
      postParam['ModelPredictiveControlEnabled'] = modelPredictiveControlEnabled.value;
    } else {
      postParam = {
        ModelPredictiveControlEnabled: modelPredictiveControlEnabled.value,
      };
    }
    
    if (!hasError) {
      const isChanged =
        intelSpeedAdjustInfo.data.modelPredictiveControlEnabled !== modelPredictiveControlEnabled.value;
      saveBtnState.value = !isChanged && fanHeatForm.currentMode === intelSpeedAdjustInfo.data.fanSmartCoolingMode;
    } else {
      saveBtnState.value = true;
    }
  });
};

const mointorBtn = (mode: string, param: any) => {
  // 自定义模式设置按钮状态
  if (mode === 'Custom' && param !== newCustomParam) {
    newCustomParam = param;
  }
  const currentCustomparam = getParam(mode, newCustomParam);
  if (currentCustomparam === null || currentCustomparam === undefined) {
    saveBtnState.value = true;
  } else {
    postParam = currentCustomparam;
    if (hasError) {
      saveBtnState.value = true;
    } else {
      saveBtnState.value = false;
    }
  }
};

// 获取设置的数据
const getParam = (selectId: string, customParam: any) => {
  let param: any = {
    SmartCooling: {},
  };
  if (intelSpeedAdjustInfo.data.modelPredictiveControlEnabled !== modelPredictiveControlEnabled.value) {
    param['ModelPredictiveControlEnabled'] = modelPredictiveControlEnabled.value;
  }
  if (fanHeatForm.fanMode !== intelSpeedAdjustInfo.data.fanMode) {
    param['FanCtrlMode'] = fanHeatForm.fanMode;
  }
  if (selectId === intelSpeedAdjustInfo.data.fanSmartCoolingMode) {
    if (selectId === 'Custom') {
      if (JSON.stringify(customParam) !== '{}') {
        param.SmartCooling['CustomConfig'] = customParam;
      }
    }
  } else {
    param.SmartCooling['Mode'] = selectId;
    if (selectId === 'Custom') {
      if (JSON.stringify(customParam) !== '{}') {
        param.SmartCooling['CustomConfig'] = customParam;
      }
    }
  }
  if (JSON.stringify(param.SmartCooling) === '{}' && fanHeatForm.fanMode === intelSpeedAdjustInfo.data.fanMode) {
    param = null;
  }
  param = param;
  return param;
};

const getFanMode = (data: any) => {
  modelPredictiveControlEnabled.value = data.modelPredictiveControlEnabled;
  if (data.coolingMedium === 'AirCooled') {
    // 风冷模式
    speedMode.value[MODE_INDEX.LIQUID_COOLING].isShow = false;
  }else if (data.coolingMedium === 'LiquidCooled') {
    // 液冷模式
    speedMode.value[MODE_INDEX.ENERGY_SAVING].isShow = false;
    speedMode.value[MODE_INDEX.LOW_NOISE].isShow = false;
    speedMode.value[MODE_INDEX.HIGH_PERFORMANCE].isShow = false;
  }
  saveBtnState.value = true;
  fanHeatForm.currentMode = data.fanSmartCoolingMode;
  fanHeatForm.fanMode = data.fanMode;
  initSelectedMode(data.fanSmartCoolingMode);
};

const initSetData = () => {
  loading(true);
  getThermals().then((res: any) => {
    emits('updateFanInfo', res);
    resloveInfo(res);
    loading(false);
  });
};

const resloveInfo = (res: any) => {
  intelSpeedAdjustInfo.data = getIntelSpeedAdjustInfo(res.data);
  initializingIntelSpeedAdjustInfo(intelSpeedAdjustInfo.data);
  intelSpeedAdjustInfo.data['fanMode'] = res.data.FanCtrlMode ? res.data.FanCtrlMode : 'Auto';
  intelSpeedAdjustInfo.data.manualLevel = res.data.ManualLevel ? res.data.ManualLevel : '20';
  if (fanHeatForm.rateMode === '0') {
    fanHeatForm.rate = intelSpeedAdjustInfo.data.manualLevel;
  }
  if (res.data.LevelPercentRange) {
    fanHeatRule.EntireRate.message = traduction('VALID_RANGE_VALUE_ERR_MSG', res.data.LevelPercentRange);
    fanHeatRule.EntireRate.min = res.data.LevelPercentRange[0];
    fanHeatRule.EntireRate.max = res.data.LevelPercentRange[1];
  }
  getFanMode(intelSpeedAdjustInfo.data);
};

watch(
  loctFanInfo,
  () => {
    const res = loctFanInfo.value;
    resloveInfo(res);
  },
  { deep: true }
);

onMounted(() => {
  showCustom.value = true;
  resloveInfo(loctFanInfo.value);
  getGenericInfo().then(res => {
    mpcShow.value = res.PowerPredictSupported;
  });
});

onUnmounted(() => {
  showCustom.value = false;
});

</script>

<template>
    <div class="fan-heat-dissipation">
        <el-form
          id="fanHeatForm"
          :model="fanHeatForm"
          :rules="fanHeatRule"
          label-width="auto"
          label-position="left"
          :hide-required-asterisk="false"
          :validate-on-rule-change="false"
        >
            <el-form-item :label="$t('FAN_MODE')" size="default">
                <el-radio-group
                    v-model="fanHeatForm.fanMode"
                    @change="changeFanMode"
                >
                    <el-radio
                        v-for="radio in fanModeList"
                        :key="radio.id"
                        v-addId.radio="radio.id"
                        :label="radio.id"
                    >
                        {{ radio.key }}
                    </el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item size="default" v-if="fanHeatForm.fanMode === 'Auto'">
              <div class="auto-content">
                <div v-if="mpcShow" class="item flex" style="margin-bottom: 16px">
                  <div class="mpc-title">{{ $t('POWER_MPC') }}</div>
                  <div class="mpc-content">
                    <el-switch
                      id="mpcEnable"
                      v-model="modelPredictiveControlEnabled"
                      @change="selectEnergy()"
                    ></el-switch>
                  </div>
                </div>
                <div class="item">
                  <div class="mpc-title">{{ $t('POWER_SELECT_MODE') }}</div>
                </div>
                <div id="intelSpeedAdjustId">
                  <div id="customTip">
                    <AlarmAlert
                      v-if="speedMode[MODE_INDEX.CUSTOM].isSelect"
                      :content="speedMode[MODE_INDEX.CUSTOM].tip"
                      :show-close="true"
                    />
                  </div>
                  <div>
                    <div id="intelSpeedAdjust" class="tab">
                      <div
                        v-for="(mode, index) in speedMode"
                        v-show="mode.isShow"
                        :id="mode.id"
                        :key="index"
                        class="custom-mode"
                        :class="{
                          isSelectedLabel: mode.isSelect,
                          unselectedLabel: !mode.isSelect,
                          tdBottomNone: index === 4
                        }"
                        @click="selected(mode)"
                      >
                        <div class="tdContent">
                          <div class="label">{{ mode.label }}</div>
                          <span v-if="index !== 4" class="content">{{ mode.content }}</span>
                          <div class="imgState" :class="{ selectedImg: mode.isSelect }">
                            <el-icon :size="8">
                              <IconCheckBold v-if="mode.isSelect" />
                            </el-icon>
                          </div>
                        </div>
                      </div>
                    </div>
                    <div
                      class="custom-mode"
                      :class="{
                        customSelected: speedMode[MODE_INDEX.CUSTOM].isSelect,
                        customUnselected: !speedMode[MODE_INDEX.CUSTOM].isSelect
                      }"
                      @click="selected(speedMode[MODE_INDEX.CUSTOM])"
                    >
                      <CustomAdjustSpeed v-if="showCustom" :data="intelSpeedAdjustInfo.data" @select="selectCustom" />
                    </div>
                  </div>
                </div>
              </div>
            </el-form-item>
            <div class="set-rate-item" v-else>
              <el-form-item
                :label="$t('POWER_FAN_SELECT_MODE')"
              >
                <el-select
                  v-model="fanHeatForm.rateMode"
                  v-addId.select="'rateMode'"
                  :teleported="false"
                  :suffix-icon="PullDownTriangle"
                  @change="changeFanSelect"
                >
                    <el-option
                      v-for="item in rateModeList"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                      :name="item.value"
                    />
                </el-select>
              </el-form-item>
              <el-form-item
                :rules="fanHeatRule.EntireRate"
                :label="$t('FAN_HEAT_RATE_TAUX')"
                prop="rate"
              >
                  <el-popover
                    v-model:visible="popoverVisible.EntireRate"
                    popper-class="no-wrap-popover"
                    placement="right"
                    trigger="focus"
                    trigger-keys
                  >
                      <span id="entireRateTip">{{ $t('VALID_VALUE_RANGE_TIP', [fanHeatRule.EntireRate.min, fanHeatRule.EntireRate.max]) }}</span>
                      <template #reference>
                        <el-input
                          v-model="fanHeatForm.rate"
                          v-addId.input="'expectRate'"
                          v-clearable
                          clearable
                          type="text"
                          @focus="focus('EntireRate')"
                          @blur="blur('EntireRate')"
                          @input="input('EntireRate', $event)"
                        >
                          <template #suffix>
                            <ErrorIcon />
                            <ClearableIcon />
                          </template>
                        </el-input>
                      </template>
                  </el-popover>
              </el-form-item>
            </div>
            <el-form-item>
                <el-button id="fanSetSaveBtn" :disabled="saveBtnState" type="primary" @click="confirmSave">
                {{ $t('COMMON_SAVE') }}
                </el-button>
                <el-button id="fanSetCancelBtn" :disabled="saveBtnState" @click="cancelEditor">
                {{ $t('COMMON_CANCEL') }}
                </el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<style lang="scss" scoped>
#fanHeatForm #rateMode,
#fanHeatForm #expectRateBox{
  width: 200px;
}
:deep(.el-form-item__label::before) {
  display: none;
}

#customModeBox {
  margin-bottom: 16px;
  .label {
    font-size: 14px;
    line-height: 20px;
    white-space: nowrap;
    font-weight: 600;
    color: var(--o-text-color-primary);
  }
}
.auto-content {
  .custom-mode {
    background: var(--o-bg-color-light);
    border-radius: 2px;
    margin-bottom: 12px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .isSelectedLabel {
    border: 2px solid var(--o-color-primary);
    border-radius: 2px;
    cursor: pointer;
  }
  .unselectedLabel {
    border-radius: 2px;
    cursor: pointer;
  }

  .isSelectedImg {
    border-right: 2px solid var(--o-color-primary);
    border-top: 2px solid var(--o-color-primary);
    border-bottom: 2px solid var(--o-color-primary);
    border-radius: 2px;
    cursor: pointer;
  }
  .unselectedImg {
    border-radius: 2px;
    cursor: pointer;
  }
  .tab {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0 16px;
    tr {
      height: 40px;
    }
  }
  .tdContent {
    padding-left: 16px;
    padding-top: 8px;
    padding-bottom: 8px;
  }
  .label {
    font-size: 14px;
    line-height: 20px;
    white-space: nowrap;
    font-weight: 600;
    color: var(--o-text-color-primary);
  }
  .content {
    width: 100%;
    font-size: 12px;
    color: var(--o-text-color-tertiary);
    letter-spacing: 0;
    line-height: 16px;
    margin-top: 4px;
  }
  .imgState {
    float: right;
    margin-top: -24px;
    margin-right: 4px;
    height: 12px;
    width: 12px;
  }
  .selectedImg {
    background: var(--o-color-primary);
    text-align: center;
  }
  .tdBottomNone {
    border-bottom: none !important;
  }
  .customSelected {
    width: 100%;
    border: solid var(--o-color-primary) 2px;
    margin-top: -17px;
    border-top: solid 0;
    padding: 8px 16px;
  }
  .customUnselected {
    width: 100%;
    margin-top: -17px;
    padding: 8px 16px;
  }
  .selectedImg {
    .el-icon {
      color: #ffffff;
      top: -3px;
    }
  }

  .alarm-alert .el-icon {
    top: auto !important;
  }

  #customTip {
    margin-bottom: 8px;
  }
}
.flex {
  display: flex;
}
</style>
<style lang="scss">
.auto-content {
  .el-button {
    padding: 0 12px 0 12px;
    min-width: 64px;
    height: 24px;
    font-size: 12px;
  }

  .integration-controller {
    margin: 16px 0 24px;
  }
  .conten-title {
    font-size: 14px;
    color: var(--o-text-color-secondary);
    letter-spacing: 0;
    line-height: 20px;
  }

  .confirmBtn {
    height: 24px;
    font-size: 12px;
  }
  a,
  a:link,
  a:hover,
  a:visited,
  a:active {
    text-decoration: none;
    color: var(--o-color-primary);
  }
}
</style>