<template>
  <div id="userLayout" class="init-layout relative w-full overflow-hidden bg-white dark:bg-slate-900">
    <!-- 右侧蓝色斜切 banner（仅桌面端显示） -->
    <div class="banner-oblique absolute inset-y-0 right-0 hidden w-[56%] overflow-hidden bg-[#2264f2] md:block">
      <img class="absolute right-0 top-0 h-full w-auto max-w-none" src="@/assets/cover-redesign.svg" alt="banner" />
    </div>

    <!-- 左侧内容区 -->
    <div class="relative z-10 h-full w-full md:w-1/2">
      <div class="flex h-full min-h-0 items-center justify-center p-6 md:p-8">
        <div class="flex h-full max-h-full min-h-0 w-4/5 flex-col overflow-hidden md:w-96">
          <!-- 顶部 logo + 大写字标（无副标题） -->
          <EntryBrand class="mb-6 shrink-0 md:mb-9" />
          <div v-if="!page.showForm" class="anim-fade-up flex min-h-0 flex-1 flex-col overflow-hidden">
            <h2 id="init-notice-title" class="mb-6 shrink-0 text-2xl font-bold dark:text-white">初始化须知</h2>
            <div
              ref="noticeScrollRef"
              class="min-h-0 flex-1 overflow-y-auto pr-2"
              role="region"
              aria-labelledby="init-notice-title"
              tabindex="0"
              @scroll="updateNoticeReadState"
            >
              <div ref="noticeContentRef">
                <div class="space-y-5">
              <div class="notice-group">
                <h4 class="mb-2 flex items-center gap-1.5 text-sm font-semibold text-[#2264f2]">
                  <el-icon><Reading /></el-icon>使用前准备
                </h4>
                <div class="space-y-3 rounded-xl bg-slate-50 p-4 dark:bg-slate-800/50">
                  <p class="flex gap-2.5 text-gray-600 dark:text-gray-300">
                    <span class="mt-[10px] h-1 w-1 shrink-0 rounded-full bg-[#2264f2]" />
                    <span>
                      Kra 是一个前后端分离开发框架，建议您具备一定的
                      <span class="font-bold text-[#2264f2]">
                        Vue、Go、数据库及服务器部署
                      </span>
                      基础后再进行使用。
                    </span>
                  </p>
                  <p class="flex gap-2.5 text-gray-600 dark:text-gray-300">
                    <span class="mt-[10px] h-1 w-1 shrink-0 rounded-full bg-[#2264f2]" />
                    <span>初始化会创建管理后台所需的数据表、管理员账号、菜单和 API 权限数据。</span>
                  </p>
                </div>
              </div>

              <div class="notice-group">
                <h4 class="mb-2 flex items-center gap-1.5 text-sm font-semibold text-[#2264f2]">
                  <el-icon><Coin /></el-icon>数据库要求
                </h4>
                <div class="space-y-3 rounded-xl bg-slate-50 p-4 dark:bg-slate-800/50">
                  <p class="flex gap-2.5 text-gray-600 dark:text-gray-300">
                    <span class="mt-[10px] h-1 w-1 shrink-0 rounded-full bg-[#2264f2]" />
                    <span>
                      如果您使用 MySQL 数据库，请确认数据库存储引擎为
                      <span class="font-bold text-[#2264f2]">
                        InnoDB
                      </span>
                      ，否则可能导致数据库功能异常。
                    </span>
                  </p>
                </div>
              </div>

                </div>

              </div>
            </div>
            <p
              id="init-notice-hint"
              class="mt-2 flex h-5 shrink-0 items-center gap-1 text-xs text-gray-500 dark:text-gray-400"
              aria-live="polite"
            >
              <template v-if="noticeHint">
                <el-icon aria-hidden="true"><Bottom /></el-icon>
                <span>{{ noticeHint }}</span>
              </template>
            </p>
            <div class="mt-2 flex shrink-0 gap-4">
              <el-button
                type="primary"
                plain
                size="large"
                class="btn-hollow flex-1"
                :disabled="!canConfirmNotice"
                :title="canConfirmNotice ? '' : '请先阅读至底部'"
                aria-describedby="init-notice-hint"
                @click="showNext"
              >
                我已确认
              </el-button>
            </div>
          </div>
          <div v-if="page.showForm" class="anim-fade-up min-h-0 flex-1 overflow-y-auto pr-2">
            <el-form ref="formRef" :model="form" label-position="top" size="large" class="init-form">
              <el-form-item label="管理员密码">
                <el-input v-model="form.adminPassword" show-password placeholder="admin账号的默认密码" />
              </el-form-item>
              <el-form-item label="数据库类型">
                <el-select v-model="form.dbType" placeholder="请选择" class="w-full" @change="changeDB">
                  <el-option key="mysql" label="mysql" value="mysql" />
                  <el-option key="pgsql" label="pgsql" value="pgsql" />
                  <el-option key="oracle" label="oracle" value="oracle" />
                  <el-option key="mssql" label="mssql" value="mssql" />
                  <el-option key="sqlite" label="sqlite" value="sqlite" />
                </el-select>
              </el-form-item>
              <div class="flex gap-4">
                <el-form-item v-if="form.dbType !== 'sqlite'" label="host" class="flex-[7]">
                  <el-input v-model="form.host" placeholder="请输入数据库链接" />
                </el-form-item>
                <el-form-item v-if="form.dbType !== 'sqlite'" label="port" class="flex-[3]">
                  <el-input v-model="form.port" placeholder="请输入数据库端口" />
                </el-form-item>
              </div>
              <div class="flex gap-4">
                <el-form-item v-if="form.dbType !== 'sqlite'" label="userName" class="flex-[7]">
                  <el-input v-model="form.userName" placeholder="请输入数据库用户名" />
                </el-form-item>
                <el-form-item label="dbName" class="flex-[3]">
                  <el-input v-model="form.dbName" placeholder="请输入数据库名称" />
                </el-form-item>
              </div>
              <el-form-item v-if="form.dbType !== 'sqlite'" label="password">
                <el-input v-model="form.password" placeholder="请输入数据库密码（没有则为空）" />
              </el-form-item>
              <el-form-item v-if="form.dbType === 'sqlite'" label="dbPath">
                <el-input v-model="form.dbPath" placeholder="请输入sqlite数据库文件存放路径" />
              </el-form-item>
              <el-form-item v-if="form.dbType === 'pgsql'" label="template">
                <el-input v-model="form.template" placeholder="请输入postgresql指定template" />
              </el-form-item>
              <el-form-item style="padding-top: 12px">
                <el-button type="primary" size="large" class="w-full" @click="onSubmit">
                  立即初始化
                </el-button>
              </el-form-item>
            </el-form>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
// @ts-ignore
import { initDB } from '@/api/initdb'
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { ElLoading, ElMessage } from 'element-plus'
import { Bottom, Coin, Reading } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import EntryBrand from '@/components/entryBrand/index.vue'
import { getScrollGateHint, isScrollAtBottom } from './scroll-gate'

defineOptions({
  name: 'Init'
})

const router = useRouter()

const page = reactive({
  showReadme: false,
  showForm: false
})

const noticeScrollRef = ref(null)
const noticeContentRef = ref(null)
const canConfirmNotice = ref(false)
const noticeHint = computed(() => getScrollGateHint(canConfirmNotice.value))
let noticeResizeObserver

const updateNoticeReadState = () => {
  const scroll = noticeScrollRef.value
  const content = noticeContentRef.value
  if (!scroll || !content || scroll.clientHeight <= 0) {
    canConfirmNotice.value = false
    return
  }
  const contentFits = content.scrollHeight <= scroll.clientHeight + 1
  canConfirmNotice.value = contentFits || isScrollAtBottom(scroll)
}

const disconnectNoticeObserver = () => {
  noticeResizeObserver?.disconnect()
  noticeResizeObserver = undefined
}

onMounted(async () => {
  await nextTick()
  updateNoticeReadState()

  noticeResizeObserver = new ResizeObserver(updateNoticeReadState)
  noticeResizeObserver.observe(noticeScrollRef.value)
  noticeResizeObserver.observe(noticeContentRef.value)
})

onBeforeUnmount(disconnectNoticeObserver)

const showNext = () => {
  if (!canConfirmNotice.value) return

  disconnectNoticeObserver()
  page.showReadme = false
  setTimeout(() => {
    page.showForm = true
  }, 20)
}

const out = ref(false)

const form = reactive({
  adminPassword: '123456',
  dbType: 'mysql',
  host: '127.0.0.1',
  port: '3306',
  userName: 'root',
  password: '',
  dbName: 'kra',
  dbPath: ''
})

const changeDB = (val) => {
  switch (val) {
    case 'mysql':
      Object.assign(form, {
        adminPassword: '123456',
        reAdminPassword: '',
        dbType: 'mysql',
        host: '127.0.0.1',
        port: '3306',
        userName: 'root',
        password: '',
        dbName: 'kra',
        dbPath: ''
      })
      break
    case 'pgsql':
      Object.assign(form, {
        adminPassword: '123456',
        dbType: 'pgsql',
        host: '127.0.0.1',
        port: '5432',
        userName: 'postgres',
        password: '',
        dbName: 'kra',
        dbPath: '',
        template: 'template0'
      })
      break
    case 'oracle':
      Object.assign(form, {
        adminPassword: '123456',
        dbType: 'oracle',
        host: '127.0.0.1',
        port: '1521',
        userName: 'oracle',
        password: '',
        dbName: 'kra',
        dbPath: ''
      })
      break
    case 'mssql':
      Object.assign(form, {
        adminPassword: '123456',
        dbType: 'mssql',
        host: '127.0.0.1',
        port: '1433',
        userName: 'mssql',
        password: '',
        dbName: 'kra',
        dbPath: ''
      })
      break
    case 'sqlite':
      Object.assign(form, {
        adminPassword: '123456',
        dbType: 'sqlite',
        host: '',
        port: '',
        userName: '',
        password: '',
        dbName: 'kra',
        dbPath: ''
      })
      break
    default:
      Object.assign(form, {
        adminPassword: '123456',
        dbType: 'mysql',
        host: '127.0.0.1',
        port: '3306',
        userName: 'root',
        password: '',
        dbName: 'kra',
        dbPath: ''
      })
  }
}
const onSubmit = async () => {
  if (form.adminPassword.length < 6) {
    ElMessage({
      type: 'error',
      message: '密码长度不能小于6位'
    })
    return
  }

  const loading = ElLoading.service({
    lock: true,
    text: '正在初始化数据库，请稍候',
    spinner: 'loading',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  try {
    const res = await initDB(form)
    if (res.code === 0) {
      out.value = true
      ElMessage({
        type: 'success',
        message: res.msg
      })

      router.push({ name: 'Login' })
    }
    loading.close()
  } catch (_) {
    loading.close()
  }
}
</script>

<style lang="scss" scoped>
.init-layout {
  height: 100vh;
  height: 100dvh;
}

/* 右侧蓝色面板的左边缘斜切：顶部靠右、底部靠左，蓝色区上窄下宽 */
.banner-oblique {
  clip-path: polygon(22% 0, 100% 0, 100% 100%, 4% 100%);
}

/* 镂空按钮：常态透明底；hover 用浅色底 + 主色文字表现（不再变白字实心） */
.btn-hollow {
  --el-button-bg-color: transparent;
  --el-button-hover-bg-color: var(--el-color-primary-light-9);
  --el-button-hover-text-color: var(--el-color-primary);
  --el-button-hover-border-color: var(--el-color-primary);
  --el-button-active-bg-color: var(--el-color-primary-light-8);
  --el-button-active-text-color: var(--el-color-primary);
  --el-button-active-border-color: var(--el-color-primary);
}

/* 全页主题色统一为 #2264f2：覆盖 Element Plus 主色及其派生深浅色，
     让实心/镂空按钮、输入框聚焦、下拉选中等所有主色区域保持一致 */
#userLayout {
  --el-color-primary: #2264f2;
  --el-color-primary-light-3: #6493f6;
  --el-color-primary-light-5: #91b2f9;
  --el-color-primary-light-7: #bdd1fb;
  --el-color-primary-light-8: #d3e0fc;
  --el-color-primary-light-9: #e9f0fe;
  --el-color-primary-dark-2: #1b50c2;
}

/* 初始化表单：非 2K 屏（<2560px）每行 margin-bottom 收窄到 10px；
     2K 及以上保持 Element Plus 默认间距 */
@media (max-width: 2559.98px) {
  .init-form :deep(.el-form-item) {
    margin-bottom: 10px;
  }
}

/* 淡入上浮：替换原来的飞入动画 */
.anim-fade-up {
  animation: anim-fade-up 0.45s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

/* 须知分组：沿用同一动画，按组递增延迟逐组浮现 */
.notice-group {
  animation: anim-fade-up 0.45s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@for $i from 1 through 3 {
  .notice-group:nth-child(#{$i}) {
    animation-delay: #{($i - 1) * 60}ms;
  }
}

@keyframes anim-fade-up {
  0% {
    opacity: 0;
    transform: translateY(18px);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (max-width: 750px) {
  .form {
    width: 94vw !important;
    padding: 0;
  }
}
</style>
