<template>
  <Navbar 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">
              <li
                v-for="(item, index) in selectedItem"
                :key="index"
                :class="{ active: activeIndex === index }"
                @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
          :model="identityInfo"
          :label-col="labelCol"
          :wrapper-col="wrapperCol"
          autocomplete="off"
        >
          <a-form-item
            has-feedback
            label="认证源名称"
            name="name"
            :rules="[{ required: true, message: '请输入认证源名称!' }]"
          >
            <a-input
              v-model:value="identityInfo.name"
              placeholder="必填，请输入认证源名称"
            />
          </a-form-item>

          <a-form-item
            label="认证源LOGO"
            name="logo"
            :rules="[{ required: true, message: '请选择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'">
        <a-form
          name="basic"
          :label-col="labelCol"
          :wrapper-col="wrapperCol"
          :model="identitySetting"
          autocomplete="off"
        >
          <a-form-item
            has-feedback
            label="身份提供商 id"
            name="entityID"
            :rules="[{ required: true, message: '请输入身份提供商 id!' }]"
          >
            <a-input
              v-model:value="identitySetting.entityID"
              placeholder="必填，请输入身份提供商 id"
            />
          </a-form-item>
          <a-form-item
            has-feedback
            label="SSO 地址"
            name="ssoUrl"
            :rules="[{ required: true, message: '请输入 SSO 地址' }]"
          >
            <a-input
              v-model:value="identitySetting.ssoUrl"
              placeholder="必填，请输入 SSO 地址"
            />
          </a-form-item>
          <a-form-item
            has-feedback
            label="证书"
            name="certificate"
            :rules="[{ required: true, message: '请输入证书' }]"
          >
            <a-textarea
              v-model:value="identitySetting.certificate"
              :rows="4"
              placeholder="必填，请输入证书"
              @blur="certificateBlur"
            />
          </a-form-item>
          <a-form-item
            label="退出 URL"
            name="loginOutUrl"
            style="margin-top: 10px"
          >
            <a-input
              v-model:value="identitySetting.loginOutUrl"
              placeholder="非必填，请输入退出 URL"
            />
          </a-form-item>
        </a-form>
      </div>
      <div v-else>
        <a-form
          name="basic"
          :label-col="{ style: { width: '186px' } }"
          :wrapper-col="wrapperCol"
          :model="identitySetting"
          autocomplete="off"
        >
          <a-form-item label="uid(用户ID)" name="uid">
            <a-input
              v-model:value="identitySetting.uid"
              placeholder="选填，IDP 中用户ID"
            />
          </a-form-item>
          <a-form-item label="clientId(公司ID)" name="clientId">
            <a-input-number
              v-model:value="identitySetting.clientId"
              :controls="false"
              style="width: 100%"
              placeholder="选填，IDP 中公司ID"
            />
          </a-form-item>
          <a-form-item label="userName(用户姓名)" name="userName">
            <a-input
              v-model:value="identitySetting.userName"
              placeholder="选填，IDP 中用户姓名"
            />
          </a-form-item>
          <a-form-item label="userNo(员工编号)" name="userNo">
            <a-input
              v-model:value="identitySetting.userNo"
              placeholder="选填，IDP 中员工编号"
            />
          </a-form-item>
          <a-form-item label="nickName(员工昵称)" name="nickName">
            <a-input
              v-model:value="identitySetting.nickName"
              placeholder="选填，IDP 中员工昵称"
            />
          </a-form-item>
          <a-form-item label="email(员工邮箱)" name="email">
            <a-input
              v-model:value="identitySetting.email"
              placeholder="选填，IDP 中员工邮箱"
            />
          </a-form-item>
          <a-form-item label="phoneNumber(员工电话)" name="phoneNumber">
            <a-input
              v-model:value="identitySetting.phoneNumber"
              placeholder="选填，IDP 中员工电话"
            />
          </a-form-item>
          <a-form-item label="roleTemplateNo(角色模板)" name="roleTemplateNo">
            <a-input
              v-model:value="identitySetting.roleTemplateNo"
              placeholder="选填，如果有多个角色模板编号，使用逗号分隔"
            />
          </a-form-item>
        </a-form>
        <div class="proDog-setting">
          <h3>Prodog 配置</h3>
          <a-form
            name="basic"
            :label-col="{ style: { width: '186px' } }"
            :wrapper-col="wrapperCol"
            :rules="rules"
            :model="identitySetting"
            autocomplete="off"
          >
            <a-form-item has-feedback label="Prodog 实体ID" name="spEntityID">
              <a-input
                v-model:value="identitySetting.spEntityID"
                placeholder="必填， Prodog 实体 ID "
              />
            </a-form-item>
            <a-form-item
              has-feedback
              label="Prodog断言解析地址"
              name="spAssertionConsumeService"
            >
              <a-input
                v-model:value="identitySetting.spAssertionConsumeService"
                placeholder="必填，Prodog 断言解析地址"
              />
            </a-form-item>
            <a-form-item
              has-feedback
              label="Prodog断言解析成功跳转地址"
              name="spAssertionConsumeSuccessRedirectService"
            >
              <a-input
                v-model:value="
                  identitySetting.spAssertionConsumeSuccessRedirectService
                "
                placeholder="必填，Prodog 断言解析成功跳转地址"
              />
            </a-form-item>
          </a-form>
        </div>
      </div>
    </div>
    <div class="steps-action">
      <a-button v-if="current > 0" @click="prev"> 上一步 </a-button>
      <a-button v-if="current === 0" disabled @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"
        :disabled="
          !identityInfo.name ||
            logoUrl === '/static/assets/client-base-v4/image/logo.png'
            ? true
            : false
        "
        @click="next"
      >
        下一步
      </a-button>
      <a-button
        v-if="current === 2"
        type="primary"
        style="margin-left: 8px"
        :disabled="
          !identitySetting.entityID ||
            !identitySetting.ssoUrl ||
            !identitySetting.certificate
            ? true
            : false
        "
        @click="next"
      >
        下一步
      </a-button>
      <a-button
        v-if="current == steps.length - 1"
        type="primary"
        :disabled="
          !identitySetting.spEntityID || service || redirect ? true : false
        "
        style="margin-left: 8px"
        @click="createIdentity"
      >
        完成
      </a-button>
    </div>
  </a-card>
</template>

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

const route = useRoute();
const router = useRouter();
const current = ref(0); // 当前步骤
const activeIndex = ref(0); // 所选认证源
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: '',
  userName: '',
  userNo: '',
  nickName: '',
  email: '',
  phoneNumber: '',
  roleTemplateNo: '',
  spEntityID: 'com.leanwo.prodog.sp',
  spAssertionConsumeService: 'http://xxxx:xx/api/saml/sso/${id}',
  spAssertionConsumeSuccessRedirectService:
    'http://xxxx:xx/index.html#/samlLogin',
});

const service = ref(false);
const redirect = ref(false);
const logoName = ref('');
const logoClassName = ref('');
// 设置form样式
const labelCol = ref({
  style: {
    width: '120px',
  },
});
const wrapperCol = ref({
  span: 8,
});
// 验证断言解析地址结束字符是否正确
let validateService = async (_rule, value) => {
  if (!value) {
    return Promise.reject('请输入 Prodog 断言解析地址');
  }
  if (!value.endsWith('/api/saml/sso/${id}')) {
    service.value = true;
    return Promise.reject('断言解析地址必须以/api/saml/sso/${ id }结束');
  } else {
    service.value = false;
  }
};
// 验证断言解析成功跳转地址结束字符是否正确
let redirectService = async (_rule, value) => {
  if (!value) {
    return Promise.reject('请输入 Prodog 断言解析成功跳转地址');
  }
  if (!value.endsWith('index.html#/samlLogin')) {
    redirect.value = true;
    return Promise.reject(
      '断言解析成功跳转地址必须以index.html#/samlLogin结束',
    );
  } else {
    redirect.value = false;
  }
};

const rules = {
  spEntityID: [
    {
      required: true,
      message: '请输入 Prodog 实体 ID',
    },
  ],
  spAssertionConsumeService: [
    {
      required: true,
      validator: validateService,
      trigger: 'change',
    },
  ],
  spAssertionConsumeSuccessRedirectService: [
    {
      required: true,
      validator: redirectService,
      trigger: 'change',
    },
  ],
};

// 获取更新Id
onMounted(() => {
  const { identityId } = route.query;
  if (identityId) {
    identityInfo.id = identityId;
    queryAuthById(identityId);
  }
});

// 根据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,
        } = success.data;
        logoUrl.value = getImageSrc(className, logo);
        imgToBase64();
        logoName.value = logo;
        identityInfo.name = name;
        identityInfo.active = active;
        logoClassName.value = className;
        identityInfo.description = description;
        const datas = JSON.parse(attribute);
        identitySetting.value = datas;
        if (authType === 'OAuth2.0') {
          activeIndex.value = 0;
          identityInfo.authType = 'OAUTH';
        } else {
          activeIndex.value = 1;
          identityInfo.authType = 'SAML';
        }
      } else {
        message.error(success.errorMessage);
      }
    },
    error => {
      Common.processException(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
  };
};
// 新建或更新认证源
const createIdentity = () => {
  const jsonStr = JSON.stringify(identitySetting.value);
  const formData = new FormData();
  formData.append('attribute', jsonStr);
  formData.append('id', identityInfo.id);
  formData.append('name', identityInfo.name);
  formData.append('logo', identityInfo.file);
  formData.append('active', identityInfo.active);
  formData.append('authType', identityInfo.authType);
  formData.append('description', identityInfo.description);
  saveUpdateAuth(formData).then(
    success => {
      if (success.errorCode === 0) {
        if (!identityInfo.id) {
          message.success('新建认证源成功！');
        } else {
          message.success('更新认证源成功！');
        }
        router.push('/desktop/identityManager');
      } else {
        message.error(success.errorMessage);
      }
    },
    error => {
      Common.processException(error);
    },
  );
};

// 获取logo文件
const logoFileChange = async e => {
  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！');
};

// 证书base64格式失去焦点后清除空格换行、回车
const certificateBlur = e => {
  identitySetting.value.certificate = e.target.value.replace(/[\s\n\r]+/g, '');
};

// 禁用antd自动上传
const beforeUpload = () => {
  return false;
};

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

// 选择认证源数据
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的开源标准数据格式。',
  },
]);

// 下一步
const next = () => {
  current.value++;
};
// 上一步
const prev = () => {
  current.value--;
};
// 设置当前点击的认证源为活动项
const setActiveItem = index => {
  activeIndex.value = index;
  if (index === 0) {
    identityInfo.authType = 'OAUTH';
  } else {
    identityInfo.authType = 'SAML';
  }
};
</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;
}
.proDog-setting > h3 {
  font-size: 14px !important;
  font-weight: 700;
}
</style>