<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch, nextTick } from 'vue';
import { traduction } from '@/utils/language';
import { IconCaretDown } from '@computing/opendesign-icons';
import { rangeVerification, strVerification } from '@/validators/validation-functions';
import { compareObjectEqual } from '@/utils/utils';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
const SPECIALS_STR = '******';
const PARTITION_STRING = /^[^#$ ]*$/;
const props = defineProps({
  templateData: {
    type: Object,
    default: () => ({}),
  },
  taskStatus: {
    type: Boolean,
    default: () => false,
  },
  isLastParams: {
    type: Boolean,
    default: () => false,
  },
});

const disabled = computed(() => {
  return props.taskStatus;
});
const basicFormRef = ref();
const formState = ref({
  RootPwd: true,
  Language: true,
  TimeZone: true,
  Keyboard: true,
  Location: true,
  DeviceName: true,
  InstallMode: true,
  Port: true,
});
const deviceState = ref({
  Name: true,
  MAC: true,
});

let baseBasicParams = {
  InstallMode: '',
  OSType: '',
  Language: '',
  TimeZone: '',
  RootPwd: '',
  Keyboard: '',
  AutoPosition: true,
  Autopart: false,
  CheckFirmware: false,
  Software: [],
  Device: {
    Name: '',
    MAC: '',
    Silkprint: {
      Location: '',
      DeviceName: '',
      Port: '',
    },
  },
};
let getPlaceholder = ref('');
function setPlaceHolder(key: string, p: any) {
  if (key === 'RootPwd') {
    getPlaceholder.value = p[key] === SPECIALS_STR ? SPECIALS_STR : '';
    p[key] = '';
  }
}
watch(
  () => props.templateData,
  newVal => {
    let params = newVal;
    if (JSON.stringify(newVal) === '{}') {
      params = baseBasicParams;
    }
    for (let key in params) {
      if (basicParams.hasOwnProperty(key)) {
        basicParams[key] = params[key];
        if (key === 'OSType') {
          onChangeOSType('OSType', params[key], false);
        } else {
          if (key === 'Device') {
            resetControlValue('Device.MAC', params[key].MAC);
            resetControlValue('Device.Name', params[key].Name);
            resetControlValue('Device.Silkprint.Port', params[key]?.Silkprint?.Port);
            resetControlValue('Device.Silkprint.Location', params[key]?.Silkprint?.Location);
            resetControlValue('Device.Silkprint.DeviceName', params[key]?.Silkprint?.DeviceName);
          } else {
            setPlaceHolder(key, params);
            resetControlValue(key, params[key]);
          }
        }
      }
    }
    if (props.isLastParams) {
      oldData = JSON.parse(JSON.stringify(basicParams));
    }
  },
);
let basicParams = reactive(JSON.parse(JSON.stringify(baseBasicParams)));
let oldData = JSON.parse(JSON.stringify(baseBasicParams));
const basicPoperState = reactive({
  OSType: false,
  Language: false,
  TimeZone: false,
  RootPwd: false,
  Keyboard: false,
  deviceName: false,
  deviceMAC: false,
  deviceSilkprintLocation: false,
  deviceSilkprintDeviceName: false,
  deviceSilkprintPort: false,
});

function togglePopper(target: string, value: boolean) {
  basicPoperState[target] = value;
}

// 自定义输入框组件输入时，同时修改当前组件的绑定值
function resetControlValue(key: string, value: any) {
  if (key.indexOf('Device') > -1) {
    let deviceKey;
    if (key.indexOf('Silkprint') > -1) {
      deviceKey = key.split('.')[2];
      basicParams.Device.Silkprint[deviceKey] = value;
      formState.value[deviceKey] = formRules[deviceKey]?.validator(
        formRules[deviceKey],
        basicParams.Device.Silkprint[deviceKey],
        () => {},
      );
    } else {
      deviceKey = key.split('.')[1];
      basicParams.Device[deviceKey] = value;
      deviceState.value[deviceKey] = formRules[deviceKey]?.validator(
        formRules[deviceKey],
        basicParams.Device[deviceKey],
        () => {},
      );
    }
  } else {
    basicParams[key] = value;
    if (formRules[key]) {
      if (key === 'RootPwd') {
        nextTick(() => {
          basicFormRef.value.validateField('RootPwd', (res: boolean) => {
            formState.value.RootPwd = res;
          });
        })
      } else {
        formState.value[key] = formRules[key]?.validator(formRules[key], basicParams[key], () => {});
      }
    }
  }
}

function setEmitData(data: any) {
  let tmpData = JSON.parse(JSON.stringify(data));
  tmpData.Software = [{FileName: tmpData.Software[0] || ''}];
  delete tmpData.DeviceMAC;
  delete tmpData.DeviceName;
  delete tmpData.DeviceSilkprintDeviceName;
  delete tmpData.DeviceSilkprintLocation;
  delete tmpData.DeviceSilkprintPort;
  return tmpData;
}

const emits = defineEmits(['btn-status', 'data-change']);
const btnStatus = computed(() => {
  let status = compareObjectEqual(basicParams, oldData);
  let deviceValidStatus = Object.values(deviceState.value).every(f => f); 
  let formValidateStatus = Object.values(formState.value).every(f => f);
  let validateStatus = deviceValidStatus && formValidateStatus;  // true 代表校验ok
  emits('btn-status', {
    status,
    validRes: validateStatus,
  });
  let changeData = setEmitData(basicParams);
  emits('data-change', changeData);
  return !(!status && validateStatus);
});

const formRules = reactive({
  OSType: {
    id: 'OSType',
    type: 'string',
    required: false,
    containsEmptyString: true,
    validator: strVerification,
    trigger: 'change',
  },
  RootPwd: {
    id: 'RootPwd',
    type: 'string',
    required: false,
    message: traduction('VALIDTOR_FORMAT_ERROR'),
    minLength: 6,
    matchRule: /.*/,
    validator: strVerification,
    containsEmptyString: true,
    trigger: 'change',
  },
  TimeZone: {
    id: 'TimeZone',
    type: 'string',
    required: false,
    message: traduction('VALIDTOR_FORMAT_ERROR'),
    matchRule: PARTITION_STRING,
    validator: strVerification,
    containsEmptyString: false,
    trigger: 'change',
  },
  Name: {
    id: 'Name',
    type: 'string',
    required: false,
    message: traduction('VALIDTOR_FORMAT_ERROR'),
    matchRule: PARTITION_STRING,
    validator: strVerification,
    containsEmptyString: false,
    trigger: 'change',
  },
  MAC: {
    id: 'MAC',
    type: 'string',
    required: false,
    message: traduction('VALIDATOR_MAC_ERROR'),
    matchRule: /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/,
    validator: strVerification,
    containsEmptyString: false,
    trigger: 'change',
  },
  Location: {
    id: 'Location',
    type: 'string',
    required: false,
    message: traduction('VALIDTOR_FORMAT_ERROR'),
    matchRule: /.*/,
    validator: strVerification,
    containsEmptyString: false,
    trigger: 'change',
  },
  DeviceName: {
    id: 'DeviceName',
    type: 'string',
    required: false,
    message: traduction('VALIDTOR_FORMAT_ERROR'),
    matchRule: /.*/,
    validator: strVerification,
    containsEmptyString: false,
    trigger: 'change',
  },
  Port: {
    id: 'Port',
    type: 'number',
    isInteger: true,
    required: false,
    min: 0,
    max: 65535,
    containsEmptyNumber: true,
    message: traduction('IBMC_AUTOMATIC_PORT_RANGES'),
    validator: rangeVerification,
    trigger: 'change',
  },
});

const OS_TYPES = [
  'BC-Linux-for-Euler.x',
  'BC-Linux7.x',
  'CentOS7.x',
  'CentOS7U6',
  'CentOS8.x',
  'Debian 10.x',
  'EulerOS.x',
  'EulerOSV2SP8',
  'Kylin10.x',
  'NeoKylin7.x',
  'openEuler.x',
  'openEuler1.0',
  'openEuler20.03',
  'openEuler20.03SP1',
  'openEuler20.03SP3',
  'openEuler22.03',
  'SLES12.x',
  'SLES15.x',
  'Ubuntu20.04.x',
  'Ubuntu22.04.x',
  'Linx6.x',
  'UOS20e.x',
  'CTyunOS2.x',
  'KylinSec3.x',
];
const OSTypeList = ref(<any>[]);

const basicTips = reactive({
  RootPwd: traduction('SP_INPUT_COMMON', { key: traduction('ADMISNISTRATOR_INITIAL_PASSWORD')}),
  TimeZone: traduction('SP_INPUT_COMMON', { key: traduction('NTP_TIME')}),
  deviceName: traduction('SP_INPUT_COMMON', { key: traduction('DEVICE_NAME')}),
  deviceMAC: traduction('NET_MAC_ADDRESS'),
  deviceSilkprintLocation: traduction('SP_INPUT_COMMON', { key: traduction('LOCATION_PARAMETER')}),
  deviceSilkprintDeviceName: traduction('SP_INPUT_COMMON', { key: traduction('DEVICE_NAME')}),
  deviceSilkprintPort: traduction('IBMC_AUTOMATIC_PORT_RANGES'),
});
let languageOptions = ref(<any>[]);
let keyboardOptions = ref(<any>[]);
const LANGUAGE_KEYBOARD_OPTIONS = {
  LinxUOS: {
    language: ['zh_CN.UTF-8', 'en_US.UTF-8'],
    keyboard: ['us'],
  },
  SLES: {
    language: ['zh_CN', 'en_US', 'ja_JP'],
    keyboard: ['english-us', 'japanese'],
  },
  others: {
    language: ['zh_CN.UTF-8', 'en_US.UTF-8', 'ja_JP'],
    keyboard: ['us', 'jp106'],
  },
};
function onChangeOSType(key: string, value: any, flag: boolean = true) {
  let rootPwdTips = {
    suse: traduction('SP_ROOTPWD_RULE'),
    ce: traduction('SP_ROOTPWD_RULE_CE'),
    ub: traduction('SP_ROOTPWD_RULE_UB'),
  };
  if (basicParams.OSType.indexOf('CentOS') > -1 || basicParams.OSType.indexOf('EulerOS') > -1) {
    basicTips.RootPwd = rootPwdTips.ce;
    formRules.RootPwd.minLength = 6;
    formRules.RootPwd.matchRule = PARTITION_STRING;
  } else if (basicParams.OSType.indexOf('Ubuntu') > -1) {
    basicTips.RootPwd = rootPwdTips.ub;
    formRules.RootPwd.minLength = 8;
    formRules.RootPwd.matchRule = PARTITION_STRING;
  } else {
    basicTips.RootPwd = rootPwdTips.suse;
    formRules.RootPwd.minLength = 6;
    formRules.RootPwd.matchRule = /.*/;
  }

  if (flag) {
    basicParams.Language = '';
    basicParams.Keyboard = '';
  }
  if (basicParams.OSType.indexOf('Linx') > -1 || basicParams.OSType.indexOf('UOS') > -1) {
    languageOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.LinxUOS.language];
    keyboardOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.LinxUOS.keyboard];
  } else if (basicParams.OSType.indexOf('SLES') > -1) {
    languageOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.SLES.language];
    keyboardOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.SLES.keyboard];
  } else {
    languageOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.others.language];
    keyboardOptions.value = [...LANGUAGE_KEYBOARD_OPTIONS.others.keyboard];
  }
  resetControlValue(key, value);
}

const softwareList = ref([{ FileName: 'iBMA' }]);
onMounted(() => {
  OS_TYPES.forEach(o => {
    OSTypeList.value.push({ label: o, key: o });
  });
});
</script>

<template>
  <div class="root-container">
    <div class="basic-container">
      <el-form
        ref="basicFormRef"
        :model="basicParams"
        :rules="formRules"
        :validate-on-rule-change="false"
        label-position="left"
        label-width="176px"
      >
        <el-form-item :label="$t('INSTALLATION_MODE')" class="special-el-form-item">
          <el-radio-group
            v-model="basicParams.InstallMode"
            :disabled="disabled"
            @change="resetControlValue('InstallMode', $event)"
          >
            <el-radio v-addId.radio="'installModelRecommand'" label="Recommended">
              {{ $t('SP_TASK_RECOMMENDED') }}
            </el-radio>
            <el-radio v-addId.radio="'installModelCustom'" label="Customized">
              {{ $t('SP_TASK_CUSTOM') }}
            </el-radio>
          </el-radio-group>
        </el-form-item>

        <div class="form-row">
          <div class="form-row-item">
            <el-form-item :label="$t('SP_TASK_OS')" prop="OSType">
              <el-select
                v-model="basicParams.OSType"
                v-addId.select="'installOSType'"
                :teleported="false"
                :disabled="disabled"
                :suffix-icon="IconCaretDown"
                class="input-class"
                @change="onChangeOSType('OSType', $event)"
              >
                <el-option
                  v-for="item in OSTypeList"
                  :key="item.key"
                  :label="item.label"
                  :value="item.key"
                ></el-option>
              </el-select>
            </el-form-item>
          </div>

          <div class="form-row-item">
            <el-form-item :label="$t('ADMISNISTRATOR_INITIAL_PASSWORD')" prop="RootPwd" :rules="formRules.RootPwd">
              <el-popover
                :content="basicTips.RootPwd"
                :visible="basicPoperState.RootPwd"
                :teleported="false"
                popper-class="wrap-popper"
                placement="right"
                trigger="focus"
              >
                <template #reference>
                  <el-input
                    id="rootPassword"
                    v-model="basicParams.RootPwd"
                    v-clearable
                    clearable
                    type="password"
                    autocomplete="new-password"
                    :maxlength="20"
                    :disabled="disabled"
                    class="input-class"
                    :placeholder="getPlaceholder || $t('COMMON_INPUT_TEXT')"
                    @input="resetControlValue('RootPwd', $event)"
                    @focus="togglePopper('RootPwd', true)"
                    @blur="togglePopper('RootPwd', false)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </div>
        </div>

        <div class="form-row">
          <div class="form-row-item">
            <el-form-item :label="$t('SYSTEM_LANGUAGE')" prop="Language">
              <el-select
                v-model="basicParams.Language"
                v-addId.select="'Language'"
                :teleported="false"
                :disabled="disabled"
                class="input-class"
                :suffix-icon="IconCaretDown"
                @change="resetControlValue('Language', $event)"
              >
                <el-option
                  v-for="item in languageOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                ></el-option>
              </el-select>
            </el-form-item>
          </div>

          <div class="form-row-item">
            <el-form-item :label="$t('NTP_TIME')" prop="TimeZone">
              <el-popover
                :content="basicTips.TimeZone"
                :visible="basicPoperState.TimeZone"
                :teleported="false"
                popper-class="wrap-popper"
                placement="right"
                trigger="focus"
              >
                <template #reference>
                  <el-input
                    id="basicTimeZone"
                    v-model="basicParams.TimeZone"
                    v-clearable
                    clearable
                    type="text"
                    :disabled="disabled"
                    class="input-class"
                    :placeholder="$t('COMMON_INPUT_TEXT')"
                    @input="resetControlValue('TimeZone', $event)"
                    @focus="togglePopper('TimeZone', true)"
                    @blur="togglePopper('TimeZone', false)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </div>
        </div>

        <el-form-item :label="$t('SYSTEM_KEYBOARD')" prop="Keyboard">
          <el-select
            v-model="basicParams.Keyboard"
            v-addId.select="'Keyboard'"
            :teleported="false"
            :disabled="disabled"
            :suffix-icon="IconCaretDown"
            class="input-class"
            @change="resetControlValue('Keyboard', $event)"
          >
            <el-option
              v-for="item in keyboardOptions"
              :key="item"
              :label="item"
              :value="item"
            ></el-option>
          </el-select>
        </el-form-item>

        <div class="form-row">
          <div class="form-row-item">
            <el-form-item
              :label="$t('AUTO_POSITION')"
              class="special-el-form-item"
              prop="AutoPosition"
            >
              <el-switch
                :id="'AutoPosition'"
                class="input-class"
                v-model="basicParams.AutoPosition"
                :disabled="true"
                @change="resetControlValue('AutoPosition', basicParams.AutoPosition)"
              ></el-switch>
            </el-form-item>
          </div>

          <div class="form-row-item">
            <el-form-item :label="$t('AUTO_PART')" class="special-el-form-item" prop="Autopart">
              <el-switch
                :id="'Autopart'"
                class="input-class"
                v-model="basicParams.Autopart"
                :disabled="disabled"
              ></el-switch>
            </el-form-item>
          </div>
        </div>

        <el-form-item :label="$t('FIRMWARE_VERIFICATION')" class="special-el-form-item" prop="CheckFirmware">
          <el-switch
            :id="'CheckFirmware'"
            v-model="basicParams.CheckFirmware"
            :disabled="disabled"
          ></el-switch>
        </el-form-item>

        <el-form-item :label="$t('SOFTWARE_LIST')" class="item have-warn-item" prop="Software">
          <el-checkbox-group v-model="basicParams.Software">
            <el-checkbox
              v-for="(item, index) in softwareList"
              :id="item.FileName"
              :key="index"
              :disabled="disabled"
              :label="item.FileName"
            ></el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <div class="form-block">
          <h4>{{ $t('DEVICE_NETWORK') }}</h4>
          <div class="form-block-content">
            <div class="form-row">
              <div class="form-row-item">
                <el-form-item :label="$t('DEVICE_NAME')" prop="Device.Name" :rules="formRules.Name">
                  <el-popover
                    :content="basicTips.deviceName"
                    :visible="basicPoperState.deviceName"
                    :teleported="false"
                    popper-class="wrap-popper"
                    placement="right"
                    trigger="focus"
                  >
                    <template #reference>
                      <el-input
                        id="deviceName"
                        v-model="basicParams.Device.Name"
                        v-clearable
                        clearable
                        type="text"
                        :disabled="disabled"
                        class="input-class"
                        :placeholder="$t('COMMON_INPUT_TEXT')"
                        @input="resetControlValue('Device.Name', $event)"
                        @focus="togglePopper('deviceName', true)"
                        @blur="togglePopper('deviceName', false)"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                </el-form-item>
              </div>
              <div class="form-row-item">
                <el-form-item :label="$t('NET_MAC_ADDRESS')" prop="Device.MAC" :rules="formRules.MAC">
                  <el-popover
                    :content="basicTips.deviceMAC"
                    :visible="basicPoperState.deviceMAC"
                    :teleported="false"
                    popper-class="wrap-popper"
                    placement="right"
                    trigger="focus"
                  >
                    <template #reference>
                      <el-input
                        id="deviceMAC"
                        v-model="basicParams.Device.MAC"
                        v-clearable
                        clearable
                        type="text"
                        :disabled="disabled"
                        class="input-class"
                        :placeholder="$t('COMMON_INPUT_TEXT')"
                        @input="resetControlValue('Device.MAC', $event)"
                        @focus="togglePopper('deviceMAC', true)"
                        @blur="togglePopper('deviceMAC', false)"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                </el-form-item>
              </div>
            </div>

            <h4>{{ $t('NICSILK_SCREEN') }}</h4>
            <div class="form-row">
              <div class="form-row-item">
                <el-form-item
                  :label="$t('LOCATION_PARAMETER')"
                  prop="Device.Silkprint.Location"
                  :rules="formRules.Location"
                >
                  <el-popover
                    :content="basicTips.deviceSilkprintLocation"
                    :visible="basicPoperState.deviceSilkprintLocation"
                    :teleported="false"
                    popper-class="wrap-popper"
                    placement="right"
                    trigger="focus"
                  >
                    <template #reference>
                      <el-input
                        id="deviceSilkprintLocation"
                        v-model="basicParams.Device.Silkprint.Location"
                        v-clearable
                        clearable
                        type="text"
                        :disabled="disabled"
                        class="input-class"
                        :placeholder="$t('COMMON_INPUT_TEXT')"
                        @input="resetControlValue('Device.Silkprint.Location', $event)"
                        @focus="togglePopper('deviceSilkprintLocation', true)"
                        @blur="togglePopper('deviceSilkprintLocation', false)"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                </el-form-item>
              </div>
              <div class="form-row-item">
                <el-form-item
                  :label="$t('DEVICE_NAME')"
                  prop="Device.Silkprint.DeviceName"
                  :rules="formRules.DeviceName"
                >
                  <el-popover
                    :content="basicTips.deviceSilkprintDeviceName"
                    :visible="basicPoperState.deviceSilkprintDeviceName"
                    :teleported="false"
                    popper-class="wrap-popper"
                    placement="right"
                    trigger="focus"
                  >
                    <template #reference>
                      <el-input
                        id="deviceSilkprintDeviceName"
                        v-model="basicParams.Device.Silkprint.DeviceName"
                        v-clearable
                        clearable
                        type="text"
                        :disabled="disabled"
                        class="input-class"
                        :placeholder="$t('COMMON_INPUT_TEXT')"
                        @input="resetControlValue('Device.Silkprint.DeviceName', $event)"
                        @focus="togglePopper('deviceSilkprintDeviceName', true)"
                        @blur="togglePopper('deviceSilkprintDeviceName', false)"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                </el-form-item>
              </div>
              <div class="form-row-item">
                <el-form-item
                  :label="$t('SP_TASK_PORT')"
                  prop="Device.Silkprint.Port"
                  :rules="formRules.Port"
                >
                  <el-popover
                    :content="basicTips.deviceSilkprintPort"
                    :visible="basicPoperState.deviceSilkprintPort"
                    :teleported="false"
                    popper-class="wrap-popper"
                    placement="right"
                    trigger="focus"
                  >
                    <template #reference>
                      <el-input
                        id="deviceSilkprintPort"
                        v-model="basicParams.Device.Silkprint.Port"
                        v-clearable
                        clearable
                        type="text"
                        :disabled="disabled"
                        class="input-class"
                        :placeholder="$t('COMMON_INPUT_TEXT')"
                        @input="resetControlValue('Device.Silkprint.Port', $event)"
                        @focus="togglePopper('deviceSilkprintPort', true)"
                        @blur="togglePopper('deviceSilkprintPort', false)"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                </el-form-item>
              </div>
            </div>
          </div>
        </div>
      </el-form>
    </div>
  </div>
  <span class="hidden">{{ btnStatus }}</span>
</template>

<style lang="scss" scoped>
.basic-container {
  .form-block {
    h4 {
      margin-bottom: 16px;
    }
    .form-block-content {
      padding: 32px 16px 16px;
      border-radius: 4px;
      border: 1px solid #c3cedf;
    }
  }
  .el-form .form-row {
    border-radius: 4px;
    display: flex;
    flex-wrap: wrap;
    & .form-row-item {
      margin-right: 32px;
    }
  }
}
.input-class {
  width: 240px;
}
.hidden {
  opacity: 0;
}
</style>
<style>
.wrap-popper {
  max-width: 376px !important;
  white-space: wrap !important;
  font-size: 12px !important;
  width: max-content !important;
}
</style>
