<template>
  <div class="qr-login-container">
    <div class="qr-code-wrapper">
      <!-- 二维码显示区域 -->
      <div v-if="qrCodeStatus === 'loading'" class="qr-loading">
        <a-spin size="large" />
        <p class="loading-text">正在生成二维码...</p>
      </div>

      <div
        v-else-if="qrCodeStatus === 'active'"
        class="qr-active cursor-pointer"
      >
        <ele-qr-code-svg
          :value="qrCodeData"
          :size="200"
          @click="refreshQrCode"
        />
        <p class="qr-tip">请使用手机APP或小程序扫码登录</p>
        <p class="qr-expire-tip">二维码有效期：{{ formatTime(expireTime) }}</p>
      </div>

      <div v-else-if="qrCodeStatus === 'scanned'" class="qr-scanned">
        <div class="scanned-icon">
          <CheckCircleOutlined style="font-size: 48px; color: #52c41a" />
        </div>
        <p class="scanned-text">扫码成功，请在手机上确认登录</p>
      </div>

      <div v-else-if="qrCodeStatus === 'expired'" class="qr-expired">
        <div class="expired-icon">
          <ClockCircleOutlined style="font-size: 48px; color: #ff4d4f" />
        </div>
        <p class="expired-text">二维码已过期</p>
        <a-button type="primary" @click="refreshQrCode">刷新二维码</a-button>
      </div>

      <div v-else-if="qrCodeStatus === 'error'" class="qr-error">
        <div class="error-icon">
          <ExclamationCircleOutlined style="font-size: 48px; color: #ff4d4f" />
        </div>
        <p class="error-text">{{ errorMessage || '生成二维码失败' }}</p>
        <a-button type="primary" @click="refreshQrCode">重新生成</a-button>
      </div>
    </div>

    <!-- 刷新按钮 -->
    <div class="qr-actions" v-if="qrCodeStatus === 'active'">
      <a-button type="link" @click="refreshQrCode" :loading="refreshing">
        <ReloadOutlined /> 刷新二维码
      </a-button>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, onUnmounted, computed } from 'vue';
  import { message } from 'ant-design-vue';
  import {
    CheckCircleOutlined,
    ClockCircleOutlined,
    ExclamationCircleOutlined,
    ReloadOutlined
  } from '@ant-design/icons-vue';
  import {
    generateQrCode,
    checkQrCodeStatus,
    type QrCodeResponse,
    QrCodeStatusResponse
  } from '@/api/passport/qrLogin';

  // 定义组件事件
  const emit = defineEmits<{
    (e: 'loginSuccess', data: QrCodeStatusResponse): void;
    (e: 'loginError', error: string): void;
  }>();

  // 响应式数据
  const qrCodeData = ref<string>('');
  const qrCodeToken = ref<string>('');
  const qrCodeStatus = ref<
    'loading' | 'active' | 'scanned' | 'expired' | 'error'
  >('loading');
  const expireTime = ref<number>(0);
  const errorMessage = ref<string>('');
  const refreshing = ref<boolean>(false);

  // 定时器
  let statusCheckTimer: number | null = null;
  let expireTimer: number | null = null;

  // 计算属性：格式化剩余时间
  const formatTime = computed(() => {
    return (seconds: number) => {
      const minutes = Math.floor(seconds / 60);
      const remainingSeconds = seconds % 60;
      return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
    };
  });

  /**
   * 生成二维码
   */
  const generateQrCodeData = async () => {
    try {
      qrCodeStatus.value = 'loading';
      const response: QrCodeResponse = await generateQrCode();

      // 后端返回的qrCode是二维码内容，我们需要构造完整的URL
      const baseUrl = window.location.origin;
      const qrCodeUrl = `${baseUrl}/qr-confirm?qrCodeKey=${response.token}`;

      qrCodeData.value = qrCodeUrl;
      qrCodeToken.value = response.token;
      qrCodeStatus.value = 'active';
      expireTime.value = response.expiresIn || 300; // 默认5分钟过期

      // 开始检查二维码状态
      startStatusCheck();
      // 开始倒计时
      startExpireCountdown();
    } catch (error: any) {
      qrCodeStatus.value = 'error';
      errorMessage.value = error.message || '生成二维码失败';
      message.error(errorMessage.value);
    }
  };

  /**
   * 开始检查二维码状态
   */
  const startStatusCheck = () => {
    if (statusCheckTimer) {
      clearInterval(statusCheckTimer);
    }

    statusCheckTimer = window.setInterval(async () => {
      try {
        const status = await checkQrCodeStatus(qrCodeToken.value);

        switch (status.status) {
          case 'scanned':
            qrCodeStatus.value = 'scanned';
            break;
          case 'confirmed':
            // 登录成功
            if (status.tenantId) {
              localStorage.setItem('TenantId', `${status.tenantId}`);
            }
            qrCodeStatus.value = 'active';
            stopAllTimers();
            emit('loginSuccess', status);
            break;
          case 'expired':
            qrCodeStatus.value = 'expired';
            stopAllTimers();
            break;
          case 'pending':
            // 继续等待
            break;
        }

        // 更新剩余时间
        if (status.expiresIn !== undefined) {
          expireTime.value = status.expiresIn;
        }
      } catch (error: any) {
        console.error('检查二维码状态失败:', error);
        // 继续检查，不中断流程
      }
    }, 2000); // 每2秒检查一次
  };

  /**
   * 开始过期倒计时
   */
  const startExpireCountdown = () => {
    if (expireTimer) {
      clearInterval(expireTimer);
    }

    expireTimer = window.setInterval(() => {
      if (expireTime.value <= 0) {
        qrCodeStatus.value = 'expired';
        stopAllTimers();
        return;
      }
      expireTime.value--;
    }, 1000);
  };

  /**
   * 停止所有定时器
   */
  const stopAllTimers = () => {
    if (statusCheckTimer) {
      clearInterval(statusCheckTimer);
      statusCheckTimer = null;
    }
    if (expireTimer) {
      clearInterval(expireTimer);
      expireTimer = null;
    }
  };

  /**
   * 刷新二维码
   */
  const refreshQrCode = async () => {
    refreshing.value = true;
    stopAllTimers();

    try {
      await generateQrCodeData();
    } finally {
      refreshing.value = false;
    }
  };

  // 组件挂载时生成二维码
  onMounted(() => {
    generateQrCodeData();
  });

  // 组件卸载时清理定时器
  onUnmounted(() => {
    stopAllTimers();
  });
</script>

<style lang="less" scoped>
  .qr-login-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    min-height: 300px;
  }

  .qr-code-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 250px;
    width: 100%;
  }

  .qr-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;

    .loading-text {
      color: #666;
      margin: 0;
    }
  }

  .qr-active {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;

    .qr-tip {
      color: #333;
      font-size: 14px;
      margin: 0;
      text-align: center;
    }

    .qr-expire-tip {
      color: #999;
      font-size: 12px;
      margin: 0;
    }
  }

  .qr-scanned {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;

    .scanned-text {
      color: #52c41a;
      font-size: 14px;
      margin: 0;
      text-align: center;
    }
  }

  .qr-expired {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;

    .expired-text {
      color: #ff4d4f;
      font-size: 14px;
      margin: 0;
    }
  }

  .qr-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;

    .error-text {
      color: #ff4d4f;
      font-size: 14px;
      margin: 0;
      text-align: center;
    }
  }

  .qr-actions {
    margin-top: 16px;
  }
</style>
