<template>
  <Navbar v-if="isEdit" title="编辑认证源" :is-go-back="true" />
  <Navbar v-else title="新建认证源" :is-go-back="true" />
  <a-card
    :bordered="false"
    style="margin-top: 20px; box-shadow: 0 2px 4px 0 rgba(54, 58, 80, 0.32)"
  >
    <a-steps class="steps" :current="current" type="navigation">
      <a-step v-for="item in steps" :key="item.title" :title="item.title" />
    </a-steps>
    <a-divider />
    <div class="steps-content">
      <div v-if="steps[current].contentTemplate === 'First'">
        <div class="box">
          <div style="display: flex">
            <label class="labelStyle">选择认证源 <span style="color: red">*</span></label>
            <ul class="selectUl" :class="{ notAllowed: isEdit }">
              <li
                v-for="(item, index) in selectedItem"
                :key="index"
                :class="{
                  active: activeIndex === index,
                  disabled: isEdit,
                }"
                @click="setActiveItem(index)"
              >
                <img class="picture" :src="item.imgSrc" />
                <div class="info">
                  <h3 style="font-size: 14px; font-weight: 700">
                    {{ item.title }}
                  </h3>
                  <p v-tooltip.bottom="item.tooltip" class="text">
                    {{ item.tooltip }}
                  </p>
                </div>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div v-else-if="steps[current].contentTemplate === 'Second'">
        <a-form
          ref="formRef2"
          :model="identityInfo"
          :label-col="{ style: { width: '120px' } }"
          :wrapper-col="{
            span: 8,
          }"
          :rules="rulesForStep2"
          autocomplete="off"
        >
          <a-form-item has-feedback label="认证源名称" name="name">
            <a-input
              v-model:value="identityInfo.name"
              placeholder="必填，请输入认证源名称"
            />
          </a-form-item>

          <a-form-item has-feedback label="认证源标识" name="no">
            <a-input
              v-model:value="identityInfo.no"
              placeholder="必填，请输入认证源标识"
            />
          </a-form-item>

          <a-form-item label="认证源LOGO" name="logo">
            <div v-tooltip.top="'点击查看大图'">
              <a-image :width="48" :src="logoUrl" />
            </div>
            <a-upload
              v-model:file-list="identityInfo.logo"
              :max-count="1"
              :before-upload="beforeUpload"
              :show-upload-list="false"
              @change="logoFileChange"
            >
              <a style="margin-left: 6px">去上传</a>
            </a-upload>
            <span>
              <a style="margin-left: 6px" @click="deleteLogo">删除</a>
            </span>
          </a-form-item>
          <a-form-item
            label="认证源描述"
            name="description"
            style="margin-top: 6px"
          >
            <a-textarea
              v-model:value="identityInfo.description"
              :rows="4"
              placeholder="非必填，请输入认证源描述"
            />
          </a-form-item>
        </a-form>
      </div>
      <div v-else-if="steps[current].contentTemplate === 'Third'">
        <CasConfiguration
          v-if="activeIndex === 2"
          :form-data="casSetting"
          @get-datas="getDatas"
        />
        <BasicConfiguration
          v-else
          :form-data="identitySetting"
          @get-datas="getDatas"
        />
      </div>
      <div v-else>
        <CasAccountSetting
          v-if="activeIndex === 2"
          :form-data="casSetting"
          :identity-info="identityInfo"
          @get-datas="getDatas"
        />
        <AccountAssociation
          v-else
          :form-data="identitySetting"
          :identity-info="identityInfo"
          @get-datas="getDatas"
        />
      </div>
    </div>
    <div class="steps-action">
      <a-button v-if="current === 0" disabled @click="prev"> 上一步 </a-button>
      <a-button v-if="current === 1" @click="prev"> 上一步 </a-button>
      <a-button
        v-if="current === 0"
        type="primary"
        style="margin-left: 8px"
        @click="next"
      >
        下一步
      </a-button>
      <a-button
        v-if="current === 1"
        type="primary"
        style="margin-left: 8px"
        @click="next"
      >
        下一步
      </a-button>
    </div>
  </a-card>
</template>

<script setup>
import Common from '../common/Common';
import { useRoute } from 'vue-router';
import { message } from 'ant-design-vue';
import { ref, reactive, onMounted } from 'vue';
import { getImageSrc } from '../common/image-src';
import BasicConfiguration from './BasicConfiguration.vue';
import AccountAssociation from './AccountAssociation.vue';
import CasConfiguration from './CasConfiguration.vue';
import CasAccountSetting from './CasAccountSetting.vue';
import {
  getBase64,
  imageToBase64,
  base64toFile,
  queryById,
  isNoExist,
} from './configData.js';

const formRef2 = ref();
const route = useRoute();
const current = ref(0); // 当前步骤
const logoName = ref(''); // logo 名称
const isEdit = ref(true); // 是否为编辑
const activeIndex = ref(0); // 所选认证源
const logoClassName = ref(''); // logo 类名
const isImage = ref(false); // logo 类型限制
const isLt300k = ref(false); // logo 大小限制
const logoUrl = ref('/static/assets/client-base-v4/image/logo.png'); // logo地址
// 步骤一步骤二数据
const identityInfo = reactive({
  id: '',
  name: '',
  logo: [],
  file: '',
  active: true,
  description: '',
  authType: 'OAUTH',
});
// 步骤三步骤四数据
const identitySetting = ref({
  entityID: '',
  ssoUrl: '',
  certificate: '',
  loginOutUrl: '',
  uid: 'id',
  userName: 'firstName',
  userNo: 'id',
  nickName: 'firstName',
  email: 'email',
  phoneNumber: 'phoneNumber',
  roleTemplateNo: '003',
  clientId: '',
  spEntityID: 'com.leanwo.prodog.sp',
  spAssertionConsumeService: 'http://xxxx:xx/api/saml/sso/${no}',
  spAssertionConsumeSuccessRedirectService:
    'http://xxxx:xx/index.html#/samlLogin',
});
const casSetting = ref({
  userNo: '',
  casUrl: 'https://cas.example.com/cas/login',
  casTicketUrl: 'https://cas.example.com/cas/serviceValidate',
  casLogoutUrl: 'https://cas.example.com/cas/logout',
});

const getDatas = datas => {
  current.value = datas.current;
  if (activeIndex.value === 2) {
    casSetting.value = datas.formData;
  } else {
    identitySetting.value = datas.formData;
  }
};

// 获取更新Id
onMounted(() => {
  const { identityId } = route.query;
  if (identityId) {
    isEdit.value = true;
    identityInfo.id = Number(identityId);
    queryAuthById(identityId);
  } else {
    isEdit.value = false;
  }
});

// 根据id查询详情（更新时数据回显）
const queryAuthById = id => {
  const params = new FormData();
  params.append('id', id);
  queryById(params).then(
    success => {
      if (success.errorCode === 0) {
        const {
          active,
          authType,
          attribute,
          className,
          description,
          logo,
          name,
          no,
        } = success.data;
        logoUrl.value = getImageSrc(className, logo);
        imgToBase64();
        logoName.value = logo;
        identityInfo.name = name;
        identityInfo.no = no;
        identityInfo.active = active;
        logoClassName.value = className;
        identityInfo.description = description;
        const datas = JSON.parse(attribute);
        if (authType === 'OAuth2.0') {
          activeIndex.value = 0;
          identityInfo.authType = 'OAUTH';
          identitySetting.value = datas;
        } else if (authType === 'SAML') {
          activeIndex.value = 1;
          identityInfo.authType = 'SAML';
          identitySetting.value = datas;
        } else {
          activeIndex.value = 2;
          identityInfo.authType = 'CAS';
          casSetting.value = datas;
        }
      } else {
        message.error(success.errorMessage);
      }
    },
    error => {
      Common.processException(error);
    },
  );
};

// check is no exist
const validateIsNoExist = (no, excludeId) => {
  const params = new FormData();
  params.append('no', no);
  params.append('excludeId', excludeId);
  return new Promise((resolve, reject) => {
    isNoExist(params).then(
      success => {
        if (success.errorCode === 0) {
          if (success.data === false) {
            resolve();
          } else {
            reject('认证源标识已经存在');
          }
        } else {
          reject(success.errorMessage);
        }
      },
      error => {
        reject(error);
      },
    );
  });
};

// 图片转file
const imgToBase64 = () => {
  var image = new Image();
  image.crossOrigin = '';
  image.src = logoUrl.value;
  image.onload = function () {
    let base64 = imageToBase64(image); //图片转base64
    identityInfo.file = base64toFile(base64, logoName.value); //base64转File
    identityInfo.logo.push(identityInfo.file);
  };
};

// 获取logo文件
const logoFileChange = async e => {
  if (!isImage.value) {
    message.warning('请上传图片类型的logo！');
    return;
  }
  if (!isLt300k.value) {
    message.warning('logo大小不得超过300KB,请重新选择logo!');
    return;
  }
  identityInfo.file = e.file;
  logoUrl.value = await getBase64(e.fileList[0].originFileObj);
};

// 删除logo文件
const deleteLogo = () => {
  identityInfo.file = '';
  identityInfo.logo.splice(0, 1);
  logoUrl.value = '/static/assets/client-base-v4/image/logo.png';
  message.warning('请上传logo！');
};

// 禁用antd自动上传
const beforeUpload = file => {
  isImage.value = file.type.includes('image');
  isLt300k.value = file.size / 1024 < 300;
  return false;
};

// 步骤条配置
const steps = ref([
  {
    title: '选择认证源协议类型',
    contentTemplate: 'First',
  },
  {
    title: '定义认证源名称及logo',
    contentTemplate: 'Second',
  },
  {
    title: '认证源基础配置',
    contentTemplate: 'Third',
  },
  {
    title: '账号关联',
    contentTemplate: 'Last',
  },
]);

const noValidator = async (_rule, value) => {
  if (value === '') {
    return Promise.reject('请输入认证源标识!');
  } else {
    return validateIsNoExist(value, identityInfo.id);
  }
};

const rulesForStep2 = {
  name: [
    {
      required: true,
      message: '请输入认证源名称!',
      trigger: 'change',
    },
  ],
  no: [
    {
      required: true,
      message: '请输入认证源标识!',
      trigger: 'change',
    },
    {
      validator: noValidator,
      trigger: 'change',
    },
  ],
  logo: [
    {
      required: true,
      message: '请选择LOGO!',
      trigger: 'change',
    },
  ],
};

// 选择认证源数据
const selectedItem = ref([
  {
    title: 'OAuth 2.0',
    imgSrc: '/static/assets/client-base-v4/image/oAuth.png',
    tooltip: 'OAuth 2.0是行业标准的授权协议。',
  },
  {
    title: 'SAML',
    imgSrc: '/static/assets/client-base-v4/image/saml.png',
    tooltip: 'SAML是安全断言标记语言，是一个基于XML的开源标准数据格式。',
  },
  {
    title: 'CAS',
    imgSrc: '/static/assets/client-base-v4/image/cas.png',
    tooltip: 'SAML是一种用于web单点登录，主要依赖于统一的认证方式和票据验证。',
  },
]);

// 下一步
const next = () => {
  if (current.value === 1) {
    // TODO
    formRef2.value.validate().then(success => {
      current.value++;
    });
  } else {
    current.value++;
  }
};

const validateNo = () => {};

// 上一步
const prev = () => {
  current.value--;
};
// 设置当前点击的认证源为活动项
const setActiveItem = index => {
  activeIndex.value = index;
  if (index === 0) {
    identityInfo.authType = 'OAUTH';
  } else if (index === 1) {
    identityInfo.authType = 'SAML';
  } else {
    identityInfo.authType = 'CAS';
  }
};
</script>

<style scoped>
.steps {
  padding: 0;
}
.steps-content {
  margin-top: 16px;
  border-radius: 6px;
  min-height: 100px;
}
.steps-action {
  margin-top: 24px;
}
.labelStyle {
  color: rgba(0, 0, 0, 0.4);
  padding-bottom: 6px;
  padding-right: 20px;
  padding-top: 6px;
  vertical-align: baseline;
  width: 100px;
}
.selectUl {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  font-size: 12px;
  width: 100%;
  list-style: none;
  padding: 0;
}
.selectUl li {
  align-items: center;
  border: 1px solid #dcdcdc;
  box-sizing: border-box;
  cursor: pointer;
  display: flex;
  flex-direction: row;
  height: 80px;
  margin-bottom: 20px;
  margin-right: 16px;
  overflow: hidden;
  padding: 20px;
  width: 295px;
}
.selectUl li:hover {
  border-color: #006eff;
}
.selectUl li.active {
  border: 1px solid #006eff;
}
.box {
  display: table;
  font-size: 12px;
  line-height: 1.5;
}
.picture {
  height: 32px;
  margin-right: 16px;
  width: 32px;
}
.info {
  flex: 1;
  overflow: hidden;
  text-align: left;
}
.text {
  margin-top: 5px;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
  white-space: nowrap;
  color: rgba(0, 0, 0, 0.4) !important;
}
.ant-card-body {
  padding: 20px !important;
}
:deep(.ant-form-item-control-input-content) {
  display: flex;
  align-items: center;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
:deep(.ant-form-item-label > label) {
  font-size: 12px !important;
  color: rgba(0, 0, 0, 0.4);
}
.ant-form-item {
  margin-bottom: 4px;
}
.ant-divider-horizontal {
  margin: 0 0 5px 0 !important;
}
.notAllowed {
  cursor: not-allowed;
}
.disabled {
  color: gray;
  background: #e6eaeb;
  /* cursor: not-allowed; */
  pointer-events: none;
}
</style>