<template>
  <div class="power-supply-mode">
    <el-form>
      <el-form-item :label="$t('SYSTEM_POWER_SUPPLY_MODE')" :label-width="labelWidth">
        <p id="supplyModeLiteral">{{ $t(currentModeText) }}</p>
      </el-form-item>
      <el-form-item :label="$t('SUPPLY_MODE_SWITCH')" :label-width="labelWidth">
        <div class="radioPanel">
          <div class="radioGroup">
            <el-radio-group v-model="modeSelected">
              <el-radio
                v-for="opt in options" :id="`mode-${opt.id}`"
                :key="opt.id" class="radio-label"
                :value="opt.value"
                :disabled="!(canSetMode && !isSwitching)"
              >
                {{ $t(opt.name) }}
                <el-tooltip :content="$t(opt.name + '_TIP')" placement="top">
                  <el-icon style="margin-left: 4px; vertical-align: middle;">
                    <IconHelpCircle />
                  </el-icon>
                </el-tooltip>
              </el-radio>
            </el-radio-group>
          </div>
        </div>
      </el-form-item>
      <el-form-item :label-width="labelWidth">
        <el-button id="psuModeSaveBtn" type="primary" :disabled="!(canSetMode && !isSwitching)" @click="confirmWarning">
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </el-form-item>
      <el-form-item v-if="switchText" :label="$t('SUPPLY_MODE_LAST_RESULT')" :label-width="labelWidth">
        <p id="switchStatusText">{{ $t(switchText) }}</p>
      </el-form-item>
      <el-form-item v-if="isSwitching" :label="$t('SUPPLY_MODE_SWITCH_PROGRESS')" :label-width="labelWidth">
        <div class="progressbarContainer">
          <el-progress v-if="isSwitching" id="switchProgress" :percentage="progress" />
        </div>
      </el-form-item>
    </el-form>
  </div>
  <Dialog ref="dialogRef" :config="dialogConfig" @close="dialogClose" />
  <SecondPassword ref="secondRef" @close="onSave" />
</template>

<script setup lang="ts">
import { onMounted, ref, reactive, computed } from 'vue';
import { loading, getStoreData, showFailedMessage } from '@/utils/composition';
import { useI18n } from 'vue-i18n';
import {
  getPowerSupplyMode,
  getPowerSwitchProgress,
  SwitchStatus,
  switchStatusMap,
  SwitchStatusText,
  setPowerSupplyMode,
} from '../../services/power.services';
import SecondPassword from '@/components/SecondPassword/SecondPassword.vue';
import { showElMessage } from '@/utils/utils';
import { getErrorTranslate, traduction } from '@/utils/language';
import { IconHelpCircle } from '@computing/opendesign-icons';
import useStore from '@/stores';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { SecondAuthorityFail, UserPrivil } from '@/model/base-enum';

const options = ref([
  {
    name: 'SUPPLY_MODE_MAIN',
    id: 'main',
    value: 0,
  },
  {
    name: 'SUPPLY_MODE_BACKUP',
    id: 'backup',
    value: 1,
  },
  {
    name: 'SUPPLY_MODE_CROSS',
    id: 'cross',
    value: 4,
  },
]);

const nopwd = getStoreData('loct', 'nopwd') || false;
const store = useStore();
const i18n = useI18n();
const langOptions = computed(() => {
  return store.state.glob.langOptions;
});

const curLang = langOptions.value.filter((lang: any) => lang.id === i18n.locale.value)[0].id;
const labelWidth = computed(() => ({
  zh: '120px',
  ja: '120px',
  en: '140px',
  fr: '180px',
  ru: '200px',
} as any)[curLang]);

const systemLockDownEnabled = computed(() => {
  return store.state.glob.systemLocked;
});

const modeSelected = ref(options.value[0].value);
const selectedText = ref('');
const canSetMode = checkPrivil(UserPrivil.powerControl) && !systemLockDownEnabled.value;
const isSwitching = ref(false);
const currentModeText = ref('');
const switchText = ref('');
const progress = ref(0);

const progressErrorCount = ref(0);
const isInit = ref(true);
const timeoutHandler = ref<ReturnType<typeof setTimeout> | null>(null);

const dialogConfig = reactive({
  title: traduction('SUPPLY_SWITCH_WARNING_HEAD'),
  content: traduction('SUPPLY_SWITCH_WARNING_CONTENT'),
  id: 'psuModeSwitch',
});

const dialogRef = ref();
const secondRef = ref();

function confirmWarning() {
  dialogRef.value.show();
}

function dialogClose(reason: boolean) {
  dialogRef.value.hide();
  if (reason) {
    if (!nopwd) {
      secondRef.value.show();
    } else {
      loading(true);
      setPowerSupplyMode(modeSelected.value)
        .catch((error) => {
          const errorCode = error?.data?.error?.[0]?.code || '';
          showFailedMessage(getErrorTranslate(errorCode));
        })
        .finally(() => {
          refreshMode();
          loading(false);
        });
    }
  }
}

onMounted(() => {
  refreshMode();
});

async function refreshMode(): Promise<void> {
  loading(true);
  const res = await getPowerSupplyMode();
  if (res === null) {
    loading(false);
    return;
  }
  const { operateState, currentPowerSupplyMode, expectedPowerSupplyMode } = res;
  currentModeText.value = options.value.filter(opt => opt.value === currentPowerSupplyMode)[0]?.name;
  selectedText.value = options.value.filter(opt => opt.value === expectedPowerSupplyMode)[0]?.name;
  modeSelected.value = options.value.filter(opt => opt.value === expectedPowerSupplyMode)[0]?.value;

  if (operateState === SwitchStatus.RUNNING) {
    isSwitching.value = true;
    switchText.value = '';
    pullProgress();
  } else {
    switchText.value = switchStatusMap.get(operateState) as SwitchStatusText;
    isSwitching.value = false;
  }

  if (operateState === SwitchStatus.FINISHED && !isInit.value) {
    showElMessage('success', traduction('COMMON_SUCCESS'));
  }
  loading(false);
}

function onSave(param: { reason: boolean; password: string }) {
  isInit.value = false;
  loading(true);
  const { reason, password } = param;
  if (reason) {
    setPowerSupplyMode(modeSelected.value, window.btoa(password)).then(
      () => {
        secondRef.value.hide();
        refreshMode();
        loading(false);
      },
      error => {
        const errorCode = error?.data?.error?.[0]?.code || '';
        if (
          errorCode === SecondAuthorityFail.REAUTHFAILED ||
          errorCode === SecondAuthorityFail.AUTHORIZATIONFAILED
        ) {
          secondRef.value.setErrorId();
          secondRef.value.clearPassword();
        } else {
          secondRef.value.hide();
          showFailedMessage(getErrorTranslate(errorCode));
          refreshMode();
        }
      },
    );
  } else {
    loading(false);
    secondRef.value.hide();
  }
}

async function pullProgress(): Promise<void> {
  try {
    const progressVal = await getPowerSwitchProgress();
    progress.value = progressVal;
    if (progress.value < 100) {
      timeoutHandler.value = setTimeout(pullProgress, 1000);
    } else {
      if (timeoutHandler.value) {
        clearTimeout(timeoutHandler.value);
        timeoutHandler.value = null;
      }
      progress.value = 0;
      refreshMode();
    }
  } catch {
    progressErrorCount.value++;
    let nextRequestTimeout = 2000;
    if (progressErrorCount.value > 5) {
      nextRequestTimeout = 10000;
    }
    timeoutHandler.value = setTimeout(pullProgress, nextRequestTimeout);
  }
}
</script>

<style scoped>
.power-supply-mode {
  padding: 16px;
  background: #fff;
  border-radius: 8px;
}
:deep(.radio-label .el-radio__label) {
  display: flex;
  align-items: center;
}
.progressbarContainer {
  width: 400px;
}
</style>