<template>
  <div>
    <div class="hero-actions">
      <el-button type="primary" @click="startCaptcha" plain>开始验证</el-button>
      <el-button @click="reloadCaptcha" :disabled="!captchaActive">刷新</el-button>
      <el-button @click="destroyCaptcha" :disabled="!captchaActive" plain>销毁</el-button>
    </div>

    <div class="sandbox-grid">
      <el-card shadow="never">
        <template #header>验证码类型</template>

        <el-radio-group v-model="selectedType" size="large">
          <el-radio-button v-for="item in captchaTypeOptions" :key="item.value" :label="item.value">
            {{ item.label }}
          </el-radio-button>
        </el-radio-group>
      </el-card>

      <el-card class="preview-card" shadow="never">
        <template #header>验证码预览</template>
        <CaptchaPanel
          ref="captchaRef"
          class="captcha-box"
          mode="validate"
          :type="selectedType"
          @close="handleCaptchaClose"
          @state-change="handleCaptchaStateChange"
          @valid-fail="handleValidFail"
          @valid-success="handleValidSuccess"
        />
      </el-card>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue'
import CaptchaPanel from '@/components/CaptchaPanel.vue'

type CaptchaType = 'RANDOM' | 'SLIDER' | 'ROTATE' | 'CONCAT' | 'WORD_IMAGE_CLICK'

type CaptchaPanelRef = {
  destroy: () => void
  init: () => Promise<void>
  reload: () => void
}

const captchaTypeOptions: Array<{ label: string, value: CaptchaType }> = [
  { label: '随机', value: 'RANDOM' },
  { label: '滑块拼图', value: 'SLIDER' },
  { label: '旋转', value: 'ROTATE' },
  { label: '拼接', value: 'CONCAT' },
  { label: '汉字点选', value: 'WORD_IMAGE_CLICK' },
]

const captchaRef = ref<CaptchaPanelRef | null>(null)
const captchaActive = ref(false)
const selectedType = ref<CaptchaType>('RANDOM')

async function startCaptcha() {
  console.info('[captcha sandbox] init captcha', {
    type: selectedType.value,
    mode: 'validate'
  })

  await captchaRef.value?.init()
}

function reloadCaptcha() {
  if (!captchaActive.value) return
  console.info('[captcha sandbox] manual reload')
  captchaRef.value?.reload()
}

function destroyCaptcha(showMessage = true) {
  if (!captchaActive.value) return
  captchaRef.value?.destroy()
  if (showMessage) {
    console.info('[captcha sandbox] destroy captcha instance')
  }
}

function handleCaptchaClose() {
  console.info('[captcha sandbox] close captcha window')
}

function handleCaptchaStateChange(active: boolean) {
  captchaActive.value = active
}

function handleValidSuccess(res: any) {
  console.log('[captcha sandbox] valid success', res)
  captchaRef.value?.destroy()
}

function handleValidFail(res: any) {
  console.warn('[captcha sandbox] valid fail', res)
  captchaRef.value?.reload()
}

onBeforeUnmount(() => captchaRef.value?.destroy())
</script>

<style lang="less" scoped>
.hero-actions {
  margin-bottom: 24px;
}

.sandbox-grid {
  display: flex;
  gap: 20px;

  .el-card {
    flex: 1;

    &.preview-card {
      flex: 0 0 420px;
    }
  }
}

.captcha-box {
  min-height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
