<script lang="ts" setup>
import { traduction, getErrorTranslate } from '@/utils/language';
import { reactive, ref, computed, watch, nextTick, onMounted } from 'vue';
import useStore from '@/stores';
import {
    inputBlurFn,
    isEqual
} from '@/pages/User/Security/utils/enhance.utils';
import { rangeVerification } from '@/validators/validation-functions';
import { IRule } from '@/model/Service/vnc-interface';
import {
    loading,
    showFailedMessage,
    showSuccessMessage,
    getStoreData
} from '@/utils/composition';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import PullDownTriangle from '@/components/PullDownTriangle/PullDownTriangle.vue';
import { factoryPodData, getPodData, getShowedComps, saveParams, resetValue } from './pod.service';
import { IFormOption, ISelectOption, ISuperPodLabelEnum } from './pod.datatype';

const userRole = getStoreData('loct', 'ur');
const isAdminOrOper = userRole.indexOf('Administrator') > -1 || userRole.indexOf('Operator') > -1;
const hasBaseConfigPrivil = checkPrivil(UserPrivil.baseConfig);

loading(true);
const store = useStore();
const dialogRef = ref();
const resetDialogRef = ref();
const MaxAccountLockoutThreshold = ref(0);
const MaxAccountLockoutDuration = ref(0);
const MaxPreviousPasswordsDisallowedCount = ref(0);
// 获取locked锁定值
let systemLockDownEnabled = computed(() => {
    return store.state.glob.systemLocked;
});

watch(systemLockDownEnabled, () => {
    init();
});
const hasUserConfig = checkPrivil(UserPrivil.userConfig);

let minimumPasswordLength = '';
let inited = false;
const buttonDisable = ref(true);
let authorityData: any = null;
const tlsSupported = ref(false);
const dialogConfig = reactive({
    title: '',
    content: '',
    id: '',
});

const resetDialogConfig = reactive({
    title: traduction('COMMON_CONFIRM'),
    content: traduction('POD_RESET_TIP'),
    id: 'resetDialog',
});

const popoverVisible = reactive({
    nodeNumber: false,
    nodeScale: false,
    nodeFrame: false,
    nodeTopology: false,
    nodeMode: false,
    nodeDPU: false,
    nodeOS: false,
    bootMode: false,
});

// 超节点编号
const nodeNumber = reactive({
    id: 'nodeNumber',
    label: traduction('POD_NUMBER'),
    value: '',
    tip: traduction('VALIDTOR_INTGER_RANGE', [0, 4294967295]),
    initValue: '',
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.SUPERPODID,
    show: true,
} as IFormOption);

// 超节点规模
const nodeScale = reactive({
    id: 'nodeScale',
    label: traduction('POD_SCALE'),
    value: '',
    tip: traduction('POD_SUPERPOD_SIZE_TIP'),
    initValue: '',
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.SUPERPODSIZE,
    show: true,
} as IFormOption);

// 本机机柜号
const nodeFrame = reactive({
    id: 'nodeFrame',
    label: traduction('POD_FRAME'),
    value: '',
    tip: traduction('VALIDTOR_INTGER_RANGE', [0, 65535]),
    initValue: '',
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.CHASSISID,
    show: true,
} as IFormOption);
// 超节点拓扑
const nodeTopology = reactive({
    label: traduction('POD_TOPOLOGY'),
    id: 'nodeTopology',
    tip: '',
    value: null as any,
    initValue: '',
    options: [],
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.TOPOLOGYTYPE,
    show: true,
} as ISelectOption);

const topologyOptions = [
    {
        value: 0,
        label: traduction('8P')
    },
    {
        value: 1,
        label: traduction('1D')
    },
    {
        value: 2,
        label: traduction('2D')
    },
    {
        value: 3,
        label: traduction('16P')
    },
];

// 超节点互联模式
const nodeMode = reactive({
    label: traduction('POD_MODE'),
    id: 'nodeMode',
    tip: '',
    value: null as any,
    initValue: '',
    options: [],
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.INTERCONTYPE,
    show: true,
} as ISelectOption);

const modeOptions = [
    {
        value: 3,
        label: traduction('UBoE(CPU)')
    },
    {
        value: 0,
        label: traduction('UBoE(SWITCH)')
    },
    {
        value: 2,
        label: traduction('UBoE(NPU)')
    },
    {
        value: 1,
        label: traduction('RoCE(NPU)')
    },
];

// 本机柜DPU数量
const nodeDPU = reactive({
    label: traduction('POD_DPU_NUMBER'),
    id: 'nodeDPU',
    tip: '',
    value: null as any,
    initValue: '',
    options: [],
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.PRESENTDPUCOUNT,
    show: true,
} as ISelectOption);

const dpuOptions = [
    {
        value: 16,
        label: traduction('16')
    },
    {
        value: 32,
        label: traduction('32')
    },
];

// 本机OS编号
const nodeOS = reactive({
    id: 'nodeOS',
    label: traduction('POD_OS_NUMBER'),
    value: '',
    tip: traduction('VALIDTOR_INTGER_RANGE', [0, 65535]),
    initValue: '',
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.SERVERINDEX,
    show: true,
} as IFormOption);

// NPU启动模式
const bootMode = reactive({
    label: traduction('POD_BOOT_MODE'),
    id: 'bootMode',
    tip: '',
    value: null as any,
    initValue: '',
    options: [],
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.NPUBOOTOPTION,
    show: true,
} as ISelectOption);

const bootModeOptions = [
    {
        value: 0,
        label: traduction('POD_BOOT_MODE0')
    },
    {
        value: 1,
        label: traduction('POD_BOOT_MODE1')
    },
    {
        value: 2,
        label: traduction('POD_BOOT_MODE2')
    },
    {
        value: 255,
        label: traduction('DEFAULT_CONFIGURATION')
    },
];

// UB管理模式
const manageMode = reactive({
    label: traduction('POD_UB_MODE'),
    id: 'manageMode',
    tip: '',
    value: null as any,
    initValue: '',
    options: [],
    disabled: !hasBaseConfigPrivil,
    associated: ISuperPodLabelEnum.UBMANAGEDBY,
    show: true,
} as ISelectOption);

const manageModeOptions = [
    {
        value: 1,
        label: traduction('POD_OUTER_MANAGE')
    },
    {
        value: 0,
        label: traduction('POD_INNER_MANAGE')
    },
];

const formRules = reactive({
    nodeNumber: {
        type: 'number',
        required: true,
        isInteger: true,
        min: 0,
        max: 4294967295,
        message: traduction('VALID_VALUE_RANGE_TIP', [0, 4294967295]),
        validator: rangeVerification,
        trigger: 'blur',
    },
    nodeScale: {
        type: 'number',
        required: true,
        isInteger: true,
        min: 16,
        max: 65535,
        message: traduction('POD_SUPERPOD_SIZE_TIP'),
        validator: (rule: IRule, valueParams: any, callback: any) => {
            let value = valueParams;
            if (value === '') {
                callback(new Error(traduction('POD_SUPERPOD_SIZE_TIP')));
                return false;
            }
            // 输入的要是数字字符串 或者 数字
            const reg = /(^[\-0-9][0-9]*(.[0-9]+)?)$/;
            if (!reg.test(value)) {
                callback(new Error(traduction('VALID_NUMBER_INFO')));
                return false;
            }
            if (typeof value === 'string') {
                value = Number(value);
            }
            let isValidValue = (value >= 16 && value <= 8192) || (value == 65535);
            if (rule.min && rule.max && isValidValue) {
                callback();
                return true;
            } else {
                callback(new Error(traduction('POD_SUPERPOD_SIZE_TIP')));
                return false;
            }
        },
        trigger: 'blur',
    },
    nodeFrame: {
        type: 'number',
        required: true,
        isInteger: true,
        min: 0,
        max: 65535,
        message: traduction('VALID_VALUE_RANGE_TIP', [0, 65535]),
        validator: rangeVerification,
        trigger: 'blur',
    },
    nodeOS: {
        type: 'number',
        required: true,
        isInteger: true,
        min: 0,
        max: 65535,
        message: traduction('VALID_VALUE_RANGE_TIP', [0, 65535]),
        validator: rangeVerification,
        trigger: 'blur',
    }
});

const formComponents = [
    nodeNumber,
    nodeScale,
    nodeFrame,
    nodeTopology,
    nodeMode,
    nodeDPU,
    nodeOS,
    bootMode,
    manageMode,
];

const formComponentsObj = reactive({
    nodeNumber,
    nodeScale,
    nodeFrame,
    nodeTopology,
    nodeMode,
    nodeDPU,
    nodeOS,
    bootMode,
    manageMode,
});

// 表单校验结果
let validateResult = {};
const ruleFormRef = ref();

// 输入框 发生input 事件
function input(inputItem: IFormOption, value: number, valid: string) {
    inputItem.value = value;
    validateResult[inputItem.id + '.value'] = formRules[valid].validator(
        formRules[valid],
        value,
        () => { }
    );

    nextTick(() => {
        detectChange();
    });
}

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

function blur(key: string) {
    popoverVisible[key] = false;
    inputBlurFn(formComponentsObj[key]);
}

function clear(key: string) {
    // 如果没有focus, 那么这个地方需要手动调用一次校验
    if (!popoverVisible[key]) {
        ruleFormRef.value.validateField(key + '.value');
    }
}

// 表单校验发生时 - 控制保存按钮状态 state:校验结果
function validate(key: string, state: boolean) {
    validateResult[key] = state;
    nextTick(() => {
        detectChange();
    });
}

const detectChange = (data?: string): any => {
    if (!inited) {
        return;
    }

    for (let key in validateResult) {
        // 任意一个校验失败
        if (!validateResult[key]) {
            buttonDisable.value = true;
            return;
        }
    }
    const showedFormComps = getShowedComps(formComponents);
    let isChange = false;
    showedFormComps.forEach(form => {
        if (form.value === null && form.initValue === null) {
            return;
        }
        if (!isEqual(form.value, form.initValue)) {
            isChange = true;
            return;
        }
    });
    buttonDisable.value = !isChange;
};

function showMessage() {
    dialogConfig.id = 'oneKeyModel';
    dialogConfig.title = traduction('COMMON_CONFIRM');
    dialogConfig.content = traduction('COMMON_ASK_OK');
    dialogRef.value.show();
}

function dialogClose(reason: boolean) {
    dialogRef.value.hide();
    if (reason) {
        save();
    }
}

function showResetDialog() {
    resetDialogRef.value.show();
}

function resetDialogClose(reason: boolean) {
    resetDialogRef.value.hide();
    if (reason) {
        setValue();
    }
}

function save() {
    loading(true);
    let changedForm = getShowedComps(formComponents).filter(form => {
        if (!isEqual(form.value, form.initValue)) {
            return true;
        }
        return false;
    });
    saveParams(changedForm).then(
        (res: any) => {
            store.state.event.setEventState({
                type: 'alertMessage',
                value: { type: 'success', message: traduction('COMMON_SUCCESS') }
            });
            initValue(factoryPodData(res));
            loading(false);
        },
        (error: any) => {
            store.state.event.setEventState({
                type: 'alertMessage',
                value: { type: 'error', message: traduction('COMMON_FAILED') }
            });
            init();
            loading(false);
        }
    );
    buttonDisable.value = true;
}

function init() {
    getPodData().then(res => {
        authorityData = factoryPodData(res);
        initValue(authorityData);
    });
}
onMounted(() => {
    init();
});
function initValue(authData: any) {
    nodeNumber.value = authData.nodeNumber;
    nodeScale.value = authData.nodeScale;
    nodeFrame.value = authData.nodeFrame;
    nodeTopology.value = authData.nodeTopology;
    nodeMode.value = authData.nodeMode;
    nodeDPU.value = authData.nodeDPU;
    nodeOS.value = authData.nodeOS;
    bootMode.value = authData.bootMode;
    manageMode.value = authData.manageMode;

    setShow(authData);
    setOptions(authData);

    setInitValue();
    inited = true;
    loading(false);
}

function setShow(data: any): void {
    nodeNumber.show = data.superPodIdSupported;
    nodeScale.show = data.superPodSizeSupported;
    nodeFrame.show = data.chassisIDSupported;
    nodeTopology.show = data.topologyTypeSupported;
    nodeMode.show = data.interconTypeSupported;
    nodeDPU.show = data.presentDPUCountSupported;
    nodeOS.show = data.serverIndexSupported;
    bootMode.show = data.npuBootOptionSupported;
    manageMode.show = data.ubManagedBySupported;
}

function setOptions(data: any) {
    const updateOptions = (supported: boolean, allowedNumbers: any[], options: any[], nodeOptions: ISelectOption) => {
        if (supported && allowedNumbers) {
            nodeOptions.options.splice(0);
            for (const element of allowedNumbers) {
                const targetIndex = options.findIndex(item => item.value === element);
                if (targetIndex > -1) {
                    nodeOptions.options.push(options[targetIndex]);
                }
            }
        }
    };
    updateOptions(data.topologyTypeSupported, data.topologyTypeAllowedNumbers, topologyOptions, nodeTopology);
    updateOptions(data.presentDPUCountSupported, data.presentDPUCountAllowedNumbers, dpuOptions, nodeDPU);
    updateOptions(data.interconTypeSupported, data.interconTypeAllowedNumbers, modeOptions, nodeMode);
    updateOptions(data.npuBootOptionSupported, data.npuBootOptionAllowedNumbers, bootModeOptions, bootMode);
    updateOptions(data.ubManagedBySupported, data.ubManagedByAllowedNumbers, manageModeOptions, manageMode);
}

// 记录后台返回值，以后用来做判断是否进行了更改
function setInitValue(): void {
    for (const form of formComponents) {
        if (form.value !== undefined) {
            form.initvalue = form.value;
        } else if (typeof form.value === 'object') {
            form.initvalue = Object.assign({}, form.value);
        } else {
            form.initvalue = form.value;
        }
    }
}

function setValue(): void {
    resetValue().then(
        (res: any) => {
            init();
            showSuccessMessage();
            buttonDisable.value = true;
        },
        (error: any) => {
            const errorCode = error?.data?.error?.[0]?.code;
            if (errorCode) {
                const errorMsg = getErrorTranslate(errorCode);
                showFailedMessage(errorMsg);
            } else {
                showFailedMessage();
            }
        }
    );
}

function setsystemLockDownEnabled(value: boolean) {
    // 切换系统为锁定状态
    store.state.glob.setGlobState({ type: 'systemLocked', value });
}
</script>

<template>
    <div id="securityEnhance">
        <el-form id="securityEnhanceForm" ref="ruleFormRef" label-width="auto" label-position="left"
            :model="formComponentsObj" :rules="formRules" :validate-on-rule-change="false" @validate="validate">
            <!-- 本机机柜号-->
            <el-form-item v-if="nodeFrame.show" :label="nodeFrame.label" class="item" :rules="formRules.nodeFrame"
                prop="nodeFrame.value">
                <el-popover v-model:visible="popoverVisible[nodeFrame.id]" popper-class="no-wrap-popover"
                    placement="right" :content="nodeFrame.tip" trigger="focus" trigger-keys>
                    <template #reference>
                        <el-input v-model="nodeFrame.value" v-addId.input="nodeFrame.id" v-clearable clearable
                            type="text" :disabled="nodeFrame.disabled || systemLockDownEnabled"
                            @focus="focus(nodeFrame.id)" @blur="blur(nodeFrame.id)"
                            @input="input(nodeFrame, $event, 'nodeFrame')" @clear="clear(nodeFrame.id)">
                            <template #suffix>
                                <ErrorIcon />
                                <ClearableIcon />
                            </template>
                        </el-input>
                    </template>
                </el-popover>
            </el-form-item>
            <!-- 本机OS编号-->
            <el-form-item v-if="nodeOS.show" :label="nodeOS.label" class="item" :rules="formRules.nodeOS"
                prop="nodeOS.value">
                <el-popover v-model:visible="popoverVisible[nodeOS.id]" popper-class="no-wrap-popover" placement="right"
                    :content="nodeOS.tip" trigger="focus" trigger-keys>
                    <template #reference>
                        <el-input v-model="nodeOS.value" v-addId.input="nodeOS.id" v-clearable clearable type="text"
                            :disabled="nodeOS.disabled || systemLockDownEnabled" @focus="focus(nodeOS.id)"
                            @blur="blur(nodeOS.id)" @input="input(nodeOS, $event, 'nodeOS')" @clear="clear(nodeOS.id)">
                            <template #suffix>
                                <ErrorIcon />
                                <ClearableIcon />
                            </template>
                        </el-input>
                    </template>
                </el-popover>
            </el-form-item>
            <!-- 本机柜DPU数量-->
            <el-form-item v-if="nodeDPU.show" :label="nodeDPU.label">
                <el-tooltip :content="nodeDPU.tip" :disabled="nodeDPU.tip === ''" placement="right" trigger-keys>
                    <el-select v-model="nodeDPU.value" v-addId.select="nodeDPU.id" :teleported="false"
                        :disabled="systemLockDownEnabled || nodeDPU.disabled" :suffix-icon="PullDownTriangle"
                        @change="detectChange()">
                        <el-option v-for="item in nodeDPU.options" :key="item.value" :label="item.label"
                            :value="item.value"></el-option>
                    </el-select>
                </el-tooltip>
            </el-form-item>
            <!-- 超节点编号-->
            <el-form-item v-if="nodeNumber.show" :label="nodeNumber.label" class="item" :rules="formRules.nodeNumber"
                prop="nodeNumber.value">
                <el-popover v-model:visible="popoverVisible[nodeNumber.id]" popper-class="no-wrap-popover"
                    placement="right" :content="nodeNumber.tip" trigger="focus" trigger-keys>
                    <template #reference>
                        <el-input v-model="nodeNumber.value" v-addId.input="nodeNumber.id" v-clearable clearable
                            type="text" :disabled="nodeNumber.disabled || systemLockDownEnabled"
                            @focus="focus(nodeNumber.id)" @blur="blur(nodeNumber.id)"
                            @input="input(nodeNumber, $event, 'nodeNumber')" @clear="clear(nodeNumber.id)">
                            <template #suffix>
                                <ErrorIcon />
                                <ClearableIcon />
                            </template>
                        </el-input>
                    </template>
                </el-popover>
            </el-form-item>
            <!-- 超节点规模-->
            <el-form-item v-if="nodeScale.show" :label="nodeScale.label" class="item" :rules="formRules.nodeScale"
                prop="nodeScale.value">
                <el-popover v-model:visible="popoverVisible[nodeScale.id]" popper-class="no-wrap-popover"
                    placement="right" :content="nodeScale.tip" trigger="focus" trigger-keys>
                    <template #reference>
                        <el-input v-model="nodeScale.value" v-addId.input="nodeScale.id" v-clearable clearable
                            type="text" :disabled="nodeScale.disabled || systemLockDownEnabled"
                            @focus="focus(nodeScale.id)" @blur="blur(nodeScale.id)"
                            @input="input(nodeScale, $event, 'nodeScale')" @clear="clear(nodeScale.id)">
                            <template #suffix>
                                <ErrorIcon />
                                <ClearableIcon />
                            </template>
                        </el-input>
                    </template>
                </el-popover>
            </el-form-item>
            <!-- 超节点拓扑-->
            <el-form-item v-if="nodeTopology.show" :label="nodeTopology.label">
                <el-tooltip :content="nodeTopology.tip" :disabled="nodeTopology.tip === ''" placement="right"
                    trigger-keys>
                    <el-select v-model="nodeTopology.value" v-addId.select="nodeTopology.id" :teleported="false"
                        :disabled="systemLockDownEnabled || nodeTopology.disabled" :suffix-icon="PullDownTriangle"
                        @change="detectChange()">
                        <el-option v-for="item in nodeTopology.options" :key="item.value" :label="item.label"
                            :value="item.value"></el-option>
                    </el-select>
                </el-tooltip>
            </el-form-item>
            <!-- 超节点互联模式-->
            <el-form-item v-if="nodeMode.show" :label="nodeMode.label">
                <el-tooltip placement="right" :content="nodeMode.tip" :disabled="nodeMode.tip === ''" trigger-keys>
                    <el-select v-model="nodeMode.value" v-addId.select="nodeMode.id" :teleported="false"
                        :disabled="systemLockDownEnabled || nodeMode.disabled" :suffix-icon="PullDownTriangle"
                        @change="detectChange()">
                        <el-option v-for="item in nodeMode.options" :key="item.value" :label="item.label"
                            :value="item.value"></el-option>
                    </el-select>
                </el-tooltip>
            </el-form-item>
            <!-- NPU启动模式-->
            <el-form-item v-if="bootMode.show" :label="bootMode.label">
                <el-tooltip placement="right" :content="bootMode.tip" :disabled="bootMode.tip === ''" trigger-keys>
                    <el-select v-model="bootMode.value" v-addId.select="bootMode.id" :teleported="false"
                        :disabled="systemLockDownEnabled || bootMode.disabled" :suffix-icon="PullDownTriangle"
                        @change="detectChange()">
                        <el-option v-for="item in bootMode.options" :key="item.value" :label="item.label"
                            :value="item.value"></el-option>
                    </el-select>
                </el-tooltip>
            </el-form-item>
            <!-- UB管理模式-->
            <el-form-item v-if="manageMode.show" :label="manageMode.label">
                <el-radio-group v-model="manageMode.value" :disabled="systemLockDownEnabled || manageMode.disabled"
                    @change="detectChange()">

                    <el-radio v-for="item in manageMode.options" :id="item.label" :key="item.label" :label="item.label"
                        :value="item.value">
                        {{ item.label }}
                    </el-radio>
                </el-radio-group>
            </el-form-item>
            <!-- 保存按钮-->
            <el-form-item v-if="hasBaseConfigPrivil" :label="' '">
                <el-button id="authorityButton" type="primary" :disabled="buttonDisable" @click="showMessage()">
                    {{ $t('COMMON_SAVE') }}
                </el-button>
                <el-button id="resetButton" @click="showResetDialog()">
                    {{ $t('HOME_RESTOREDEFAULT') }}
                </el-button>
            </el-form-item>
        </el-form>
    </div>
    <Dialog ref="dialogRef" :config="dialogConfig" @close="dialogClose"></Dialog>
    <Dialog ref="resetDialogRef" :config="resetDialogConfig" @close="resetDialogClose"></Dialog>
</template>

<style lang="scss" scoped>
#securityEnhance {
    background: var(--o-bg-color-base);
    border-radius: 0 4px 4px;
    padding: 16px 24px 0 24px;

    .el-select {
        width: 264px;
    }

    .input-top-text {
        display: block;
    }

    .margin-text {
        margin-left: 8px;
    }

    .lock-tip {
        color: var(--o-color-major);
        width: 264px;
        word-wrap: break-word;
        line-height: 16px;
    }

    .unlimited-tip {
        margin-left: 32px;
    }

    :deep(.el-form-item__label::before) {
        display: none;
    }

    .password-title {
        font-size: 16px;
        color: var(--o-text-color-primary);
        line-height: 24px;
        font-weight: bold;
        margin-bottom: 16px;
    }

    .el-form .form-row {
        border-radius: 4px;
        display: flex;
        flex-wrap: wrap;

        & .form-row-item {
            margin-right: 32px;
        }
    }

    .loginError {
        :deep(.el-form-item__content) {
            display: block !important;
        }
    }
}
</style>
<style lang="scss">
#securityEnhance {
    .small-item {
        height: 16px;

        .el-form-item__label {
            padding-top: 0;
            padding-bottom: 0;
        }

        .el-form-item__content {
            line-height: 16px;
        }
    }

    .item {
        .el-input {
            width: 264px;
        }
    }
}
</style>