<template>
  <div class="app-container">
    <el-steps
      :active="activeStep"
      :process-status="
        currentStepStatus === 0
          ? 'error'
          : currentStepStatus === 1
          ? 'process'
          : 'success'
      "
      align-center
      class="init-steps"
      finish-status="success"
    >
      <el-step title="开始" />
      <el-step title="检查" />
      <el-step title="步骤2" />
      <el-step title="步骤3" />
    </el-steps>

    <!--  错误提示  -->
    <el-alert
      v-if="currentStepStatus === 0"
      :closable="false"
      :type="
        currentStepStatus === 0
          ? 'error'
          : currentStepStatus === 1
          ? 'info'
          : 'success'
      "
      show-icon
      >{{
        activeStep === 1
          ? "错误码: " +
            tenantInitCheckResult.result +
            ", 错误信息: " +
            tenantInitCheckResult.msg
          : activeStep === 2
          ? "错误码: " +
            createTablesResult.result +
            ", 错误信息: " +
            createTablesResult.msg
          : activeStep === 3
          ? "错误码: " +
            initDataResult.result +
            ", 错误信息: " +
            initDataResult.msg
          : ""
      }}
    </el-alert>

    <!--  数据库配置信息  -->
    <el-row
      v-if="Object.keys(tenantInitCheckResult).length"
      style="margin: 36px 36px 0"
    >
      <el-col :span="12">
        <div class="data-card init-check-base-data">
          <div class="card-title">
            <span>基础数据</span>
          </div>
          <div class="card-content">
            <div class="card-content-item">
              <span class="card-content-item-title">租户名称:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.tenantName
              }}</span>
            </div>
            <!--模式-->
            <div class="card-content-item">
              <span class="card-content-item-title">模式:</span>
              <span class="card-content-item-value">{{
                tenantModeDict.find(
                  (item) => item.value === tenantInitCheckResult.mode
                )?.label
              }}</span>
            </div>
          </div>
        </div>
      </el-col>
      <el-col :span="12">
        <div
          v-if="tenantInitCheckResult.datasource"
          class="data-card init-check-base-data"
          style="margin-left: 24px"
        >
          <div class="card-title">
            <span>数据源数据</span>
          </div>
          <div class="card-content">
            <div class="card-content-item">
              <span class="card-content-item-title">数据库IP:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.ip
              }}</span>
            </div>
            <!--                端口-->
            <div class="card-content-item">
              <span class="card-content-item-title">端口:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.port
              }}</span>
            </div>
            <!--模式-->
            <div class="card-content-item">
              <span class="card-content-item-title">类型:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.type
              }}</span>
            </div>
            <!--                数据库名称-->
            <div class="card-content-item">
              <span class="card-content-item-title">数据库名称:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.dbName
              }}</span>
            </div>
            <!--                用户名-->
            <div class="card-content-item">
              <span class="card-content-item-title">用户名:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.username
              }}</span>
            </div>
            <!--                密码-->
            <div class="card-content-item">
              <span class="card-content-item-title">密码:</span>
              <span class="card-content-item-value">{{
                tenantInitCheckResult.datasource.password
              }}</span>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!--  spinner  -->
    <el-row v-if="loading" justify="center">
      <el-col :span="1.5">
        <div class="btn-loading">
          <el-icon size="80">
            <refresh />
          </el-icon>
        </div>
      </el-col>
    </el-row>

    <div v-else class="steps-content">
      <div v-if="activeStep === 0" class="start-step">
        <el-row justify="center">
          <el-col :span="1.5">
            <div class="circle-button" @click="initTenant">开始</div>
          </el-col>
        </el-row>
      </div>
      <div v-else-if="activeStep === 1">
        <el-row justify="center">
          <el-col :span="1.5">
            <div
              v-if="currentStepStatus === 0"
              class="circle-button error"
              @click="router.push({ path: '/tenant/tenant' })"
            >
              关闭
            </div>
            <div
              v-else-if="currentStepStatus === 2"
              class="circle-button"
              @click="initTenant"
            >
              创建库
            </div>
          </el-col>
        </el-row>
      </div>
      <template v-else-if="activeStep === 2">
        <el-row justify="center">
          <el-col :span="1.5">
            <div
              v-if="currentStepStatus === 0"
              class="circle-button error"
              @click="router.push({ path: '/tenant/tenant' })"
            >
              关闭
            </div>
            <div
              v-else-if="currentStepStatus === 2"
              class="circle-button"
              @click="initTenant"
            >
              <span>导入数据</span>
            </div>
          </el-col>
        </el-row>
      </template>
      <template v-else-if="activeStep === 3">
        <el-row justify="center">
          <el-col :span="1.5">
            <div
              v-if="currentStepStatus === 0"
              class="circle-button error"
              @click="router.push({ path: '/tenant/tenant' })"
            >
              关闭
            </div>
            <div
              v-else-if="currentStepStatus === 2"
              class="circle-button finish"
              @click="router.push({ path: '/tenant/tenant' })"
            >
              完成
            </div>
          </el-col>
        </el-row>
      </template>
    </div>
  </div>
</template>
<script setup>
import { onMounted, reactive, ref, toRefs, watchEffect } from "vue";
import { check, createTables, initData } from "@/api/tenant/init";
import { useRoute, useRouter } from "vue-router";
import { tenantModeDict } from "@/constant/dict";
import { Refresh } from "@element-plus/icons-vue";

const route = useRoute();
const router = useRouter();
const activeStep = ref(0);
const currentStepStatus = ref(1); // 0: error 1: process 2: finish
const tenantId = ref(undefined);
const loading = ref(false);
if (route.query.id) {
  tenantId.value = route.query.id;
} else {
  router.push({ path: "/tenant/tenant" });
}

const data = reactive({
  tenantInitCheckResult: {},
  createTablesResult: {},
  initDataResult: {},
});

const { tenantInitCheckResult, createTablesResult, initDataResult } =
  toRefs(data);

const initTenant = async () => {
  loading.value = true;
  const promiseList = [tenantInitCheck, createDatabase, importData];
  for (const promise of promiseList.slice(activeStep.value)) {
    try {
      await promise();
    } catch (e) {
      loading.value = false;
      break;
    }
  }
  loading.value = false;
};

const tenantInitCheck = () => {
  activeStep.value = 1;
  currentStepStatus.value = 1;
  return check(tenantId.value)
    .catch(() => {
      currentStepStatus.value = 2;
      activeStep.value = 0;
      throw new Error("租户初始化检查失败");
    })
    .then((resp) => {
      tenantInitCheckResult.value = resp;
      if (resp.result === 200) {
        currentStepStatus.value = 2;
      } else {
        currentStepStatus.value = 0;
        throw new Error("租户初始化检查失败");
      }
    });
};

//  第二步: 创建数据库
const createDatabase = () => {
  // loading.value = true;
  activeStep.value = 2;
  currentStepStatus.value = 1;
  return createTables(tenantId.value)
    .catch(() => {
      currentStepStatus.value = 2;
      activeStep.value = 1;
      throw new Error("创建数据库失败");
    })
    .then((resp) => {
      createTablesResult.value = resp;
      if (resp.result === 200) {
        currentStepStatus.value = 2;
      } else {
        currentStepStatus.value = 0;
        throw new Error("创建数据库失败");
      }
    });
};

// 第三步,导入数据
const importData = () => {
  // loading.value = true;
  activeStep.value = 3;
  currentStepStatus.value = 1;
  return initData(tenantId.value)
    .catch(() => {
      currentStepStatus.value = 2;
      activeStep.value = 2;
      throw new Error("导入数据失败");
    })
    .then((resp) => {
      initDataResult.value = resp;
      if (resp.result === 200) {
        currentStepStatus.value = 2;
      } else {
        currentStepStatus.value = 0;
        throw new Error("导入数据失败");
      }
    });
};

onMounted(() => {
  watchEffect(() => {
    let progressLineWidth =
      (activeStep.value - 1) * 100 +
      Math.abs(currentStepStatus.value - 1) * 30 +
      70;
    progressLineWidth = progressLineWidth < 100 ? 0 : progressLineWidth;
    let progressLineColor;
    if (currentStepStatus.value === 0) {
      const percent = ((activeStep.value - 1) / activeStep.value) * 100;
      progressLineColor = `linear-gradient(to right, #67c23a ${percent}%, #f56c6c ${percent}%)`;
      // 进度条颜色
    } else {
      progressLineColor = `linear-gradient(to right, #67c23a ${100}%, #f56c6c ${100}%)`;
    }
    document
      .querySelector(".app-container")
      .style.setProperty("--progress-line-color", progressLineColor);
    document
      .querySelector(".app-container")
      .style.setProperty("--progress-line-width", progressLineWidth + "%");
  });
});
</script>

<style lang="scss" scoped>
:deep(.init-steps) {
  margin-top: 120px;

  .el-step__icon {
    z-index: 9999;
  }

  .el-step:first-child {
    .el-step__head.is-success {
      .el-step__line::before {
        content: "";
        display: block;
        position: absolute;
        left: 12px;
        top: 0;
        height: 2px;
        width: var(--progress-line-width);
        z-index: 99;
        background: var(--progress-line-color);
        transition: all 1s linear;
      }

      .el-step__line::after {
        content: "";
        display: block;
        position: absolute;
        left: calc(var(--progress-line-width) - 7px);
        top: -6px;
        width: 14px;
        height: 14px;
        transition: all 1s linear;
        border-radius: 50%;
        z-index: 99;
        background: var(--progress-line-color);
      }
    }
  }
}

.steps-content {
  margin-top: 80px;
  padding: 0 60px;

  .start-step {
  }

  .check-step {
    display: flex;
  }
}

.btn-loading {
  margin-top: 80px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #409eff;
  display: flex;
  justify-content: center;
  align-items: center;

  .el-icon {
    animation: spin 1s linear infinite;
    color: white;
  }
}

.circle-button {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #409eff;
  color: #fff;
  text-align: center;
  line-height: 100px;
  cursor: pointer;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);
  user-select: none;

  &:hover {
    background-color: #66b1ff;
  }

  //  按钮按下时
  &:active {
    background-color: #3a8ee6;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2) inset;
  }

  &.error {
    background-color: #f56c6c;

    &:hover {
      background-color: #f78989;
    }

    &:active {
      background-color: #f56c6c;
      box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2) inset;
    }
  }

  &.finish {
    background-color: #67c23a;

    &:hover {
      background-color: #85ce61;
    }

    &:active {
      background-color: #67c23a;
      box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2) inset;
    }
  }
}

.data-card {
  width: 100%;
  height: 100%;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  min-height: 120px;
  position: relative;
  padding: 16px;

  .card-title {
    position: absolute;
    top: -10px;
    left: 10px;
    background-color: #fff;
    //禁止选中
    user-select: none;
    // 水平方向padding 10px
    padding: 0 5px;
    font-size: 12px;
    // 浅灰色字体
    color: #606266;
    border-radius: 12px;
  }

  .card-content {
    display: flex;
    flex-direction: column;
    justify-content: start;
    height: 100%;

    .card-content-item {
      display: flex;
      justify-content: space-between;

      &:not(:last-child) {
        margin-bottom: 10px;
      }
    }

    .card-content-item-title {
      font-size: 14px;
      font-weight: 500;
      color: #606266;
    }

    .card-content-item-value {
      font-size: 14px;
      color: #909399;
    }
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

:deep(.el-step__head.is-success) {
  transition: all 1s linear;
}

:deep(.el-step__title) {
  font-size: 20px;
}
</style>
