<template>
  <div
    class="login-wrapper"
    :style="{
      backgroundImage: 'url(https://oss.wsdns.cn/20250105/314d2a3da10048b09ef0f0464fdacbff.jpg)'
    }"
  >
    <div class="logo-login" v-if="config?.siteName">
      <img :src="config.siteLogo" class="logo" />
      <h4>{{ config.siteName }}</h4>
    </div>
    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      class="login-form ele-bg-white"
    >
      <div class="login-title flex justify-center items-center px-12">
        <h4 class="title-btn active">{{ t('login.forgetPage.title') }}</h4>
      </div>
      <p class="forget-subtitle">{{ t('login.forgetPage.subTitle') }}</p>

      <a-tabs
        v-model:activeKey="activeTab"
        class="forget-tabs"
        @change="onTabChange"
      >
        <!-- 邮箱找回 -->
        <a-tab-pane key="email" :tab="t('login.forgetPage.tabEmail')">
          <a-form-item name="email">
            <a-input
              allow-clear
              size="large"
              v-model:value="form.email"
              :placeholder="t('login.forgetPage.emailPlaceholder')"
            >
              <template #prefix>
                <MailOutlined />
              </template>
            </a-input>
          </a-form-item>
          <a-form-item name="emailCode">
            <div class="login-input-group">
              <a-input
                allow-clear
                size="large"
                :maxlength="6"
                v-model:value="form.emailCode"
                :placeholder="t('login.forgetPage.codePlaceholder')"
              >
                <template #prefix>
                  <SafetyOutlined />
                </template>
              </a-input>
              <a-button
                class="login-captcha"
                :disabled="!!countdownTime"
                @click="sendCode"
              >
                <span v-if="!countdownTime">{{ t('login.forgetPage.getCode') }}</span>
                <span v-else>{{ countdownTime }} s</span>
              </a-button>
            </div>
          </a-form-item>
        </a-tab-pane>

        <!-- 手机找回 -->
        <a-tab-pane key="phone" :tab="t('login.forgetPage.tabPhone')">
          <a-form-item name="phone">
            <a-input
              allow-clear
              size="large"
              :maxlength="11"
              v-model:value="form.phone"
              :placeholder="t('login.forgetPage.phonePlaceholder')"
            >
              <template #prefix>
                <MobileOutlined />
              </template>
            </a-input>
          </a-form-item>
          <a-form-item name="code">
            <div class="login-input-group">
              <a-input
                allow-clear
                size="large"
                :maxlength="6"
                v-model:value="form.code"
                :placeholder="t('login.forgetPage.codePlaceholder')"
              >
                <template #prefix>
                  <SafetyOutlined />
                </template>
              </a-input>
              <a-button
                class="login-captcha"
                :disabled="!!countdownTime"
                @click="sendCode"
              >
                <span v-if="!countdownTime">{{ t('login.forgetPage.getCode') }}</span>
                <span v-else>{{ countdownTime }} s</span>
              </a-button>
            </div>
          </a-form-item>
        </a-tab-pane>
      </a-tabs>

      <a-form-item name="newPassword">
        <a-input-password
          size="large"
          v-model:value="form.newPassword"
          :placeholder="t('login.forgetPage.passwordPlaceholder')"
        >
          <template #prefix>
            <LockOutlined />
          </template>
        </a-input-password>
      </a-form-item>
      <a-form-item name="confirmPassword">
        <a-input-password
          size="large"
          v-model:value="form.confirmPassword"
          :placeholder="t('login.forgetPage.confirmPlaceholder')"
        >
          <template #prefix>
            <LockOutlined />
          </template>
        </a-input-password>
      </a-form-item>

      <a-form-item>
        <a-button
          block
          size="large"
          type="primary"
          :loading="loading"
          @click="submit"
        >
          {{ loading ? t('login.loading') : t('login.forgetPage.reset') }}
        </a-button>
      </a-form-item>
      <div class="text-center pt-2">
        <a class="login-forget" @click="goLogin">{{ t('login.forgetPage.backLogin') }}</a>
      </div>
    </a-form>

    <!-- 图形验证码弹窗 -->
    <a-modal
      :width="340"
      :footer="null"
      :title="t('login.forgetPage.captchaTitle')"
      v-model:visible="captchaVisible"
      @cancel="codeLoading = false"
    >
      <div class="login-input-group" style="margin-bottom: 16px">
        <a-input
          v-model:value="imgCode"
          :maxlength="5"
          size="large"
          :placeholder="t('login.forgetPage.captchaPlaceholder')"
          allow-clear
          @pressEnter="() => doSendCode(imgCode)"
        />
        <a-button class="login-captcha">
          <img alt="" :src="captchaImage" @click="refreshCaptcha" />
        </a-button>
      </div>
      <a-button
        block
        size="large"
        type="primary"
        :loading="codeLoading"
        @click="() => doSendCode(imgCode)"
      >
        {{ t('login.forgetPage.sendNow') }}
      </a-button>
    </a-modal>

    <div class="login-copyright">
      <a-space>
        <span>© {{ new Date().getFullYear() }}</span>
        <span>{{ config?.copyright || 'websoft.top Inc.' }}</span>
      </a-space>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, computed, onUnmounted } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { useRouter } from 'vue-router';
  import { message } from 'ant-design-vue';
  import {
    LockOutlined,
    MobileOutlined,
    SafetyOutlined,
    MailOutlined
  } from '@ant-design/icons-vue';
  import { FormInstance } from 'ant-design-vue/es/form';
  import {
    sendSmsCaptchaByAdmin,
    sendEmailCaptcha,
    getCaptcha
  } from '@/api/passport/login';
  import { resetPassword } from '@/api/layout';
  import useFormData from '@/utils/use-form-data';
  import { Config } from '@/api/cms/cmsWebsiteField/model';

  const { t } = useI18n();
  const router = useRouter();

  // 默认站点配置（与登录页保持一致）
  const defaultConfig: Config = {
    siteName: '小程序商城',
    siteLogo: 'https://oss.wsdns.cn/20240822/0252ad4ed46449cdafe12f8d3d96c2ea.svg',
    domain: '',
    icpNo: '',
    copyright: '',
    loginBgImg: '',
    address: '',
    tel: '',
    kefu2: '',
    kefu1: '',
    email: '',
    loginTitle: '',
    sysLogo: ''
  };
  const config = ref<Config>({ ...defaultConfig });

  // 找回方式：email(邮箱) / phone(手机)，默认邮箱
  const activeTab = ref<'email' | 'phone'>('email');

  const { form } = useFormData<{
    email: string;
    emailCode: string;
    phone: string;
    code: string;
    newPassword: string;
    confirmPassword: string;
  }>({
    email: '',
    emailCode: '',
    phone: '',
    code: '',
    newPassword: '',
    confirmPassword: ''
  });

  const formRef = ref<FormInstance | null>(null);
  const loading = ref(false);

  // 验证码倒计时
  const countdownTime = ref(0);
  let countdownTimer: number | null = null;

  // 图形验证码弹窗
  const captchaVisible = ref(false);
  const captchaImage = ref('');
  const captchaText = ref('');
  const imgCode = ref('');
  const codeLoading = ref(false);

  // 同一个账号前 3 次发送不需要图形验证码
  const FREE_SEND_TIMES = 3;

  // 根据当前找回方式和账号生成发送次数缓存 key
  const getSendCountKey = () => {
    const account = activeTab.value === 'email' ? form.email : form.phone;
    return `forget_send_count_${activeTab.value}_${account}`;
  };

  // 读取当前账号已发送次数
  const getSendCount = () => {
    const key = getSendCountKey();
    if (!key) return 0;
    const count = localStorage.getItem(key);
    return count ? Number(count) || 0 : 0;
  };

  // 增加发送次数
  const increaseSendCount = () => {
    const key = getSendCountKey();
    if (!key) return;
    localStorage.setItem(key, String(getSendCount() + 1));
  };

  // 刷新图形验证码
  const refreshCaptcha = () => {
    getCaptcha()
      .then((data) => {
        captchaImage.value = data.base64;
        captchaText.value = data.text;
      })
      .catch((e: Error) => message.error(e.message));
  };

  // 打开图形验证码弹窗
  const openCaptchaModal = () => {
    imgCode.value = '';
    refreshCaptcha();
    captchaVisible.value = true;
  };

  // 密码强度：至少8位，且包含字母和数字
  const passwordRules = [
    {
      required: true,
      message: t('login.forgetPage.newPasswordRule'),
      trigger: 'blur'
    },
    { min: 8, message: t('login.forgetPage.newPasswordRule'), trigger: 'blur' },
    {
      pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/,
      message: t('login.forgetPage.newPasswordRule'),
      trigger: 'blur'
    }
  ];
  const confirmPasswordRules = [
    {
      required: true,
      message: t('login.forgetPage.confirmRule'),
      trigger: 'blur'
    },
    {
      validator: (_rule: unknown, value: string) =>
        value === form.newPassword
          ? Promise.resolve()
          : Promise.reject(new Error(t('login.forgetPage.confirmRule'))),
      trigger: 'blur'
    }
  ];

  // 根据当前找回方式动态生成校验规则
  const rules = computed(() => {
    if (activeTab.value === 'email') {
      return {
        email: [
          { required: true, message: t('login.forgetPage.emailRule'), trigger: 'blur' },
          { type: 'email', message: t('login.forgetPage.emailRule'), trigger: 'blur' }
        ],
        emailCode: [
          { required: true, message: t('login.forgetPage.codeRule'), trigger: 'blur' }
        ],
        newPassword: passwordRules,
        confirmPassword: confirmPasswordRules
      };
    }
    return {
      phone: [
        { required: true, message: t('login.forgetPage.phoneRule'), trigger: 'blur' },
        { pattern: /^1\d{10}$/, message: t('login.forgetPage.phoneRule'), trigger: 'blur' }
      ],
      code: [
        { required: true, message: t('login.forgetPage.codeRule'), trigger: 'blur' }
      ],
      newPassword: passwordRules,
      confirmPassword: confirmPasswordRules
    };
  });

  const onTabChange = () => {
    formRef.value?.clearValidate();
  };

  // 发送验证码（邮箱/手机）
  const sendCode = () => {
    if (activeTab.value === 'email') {
      if (!form.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) {
        message.error(t('login.forgetPage.emailRule'));
        return;
      }
    } else {
      if (!form.phone || !/^1\d{10}$/.test(form.phone)) {
        message.error(t('login.forgetPage.phoneRule'));
        return;
      }
    }
    if (getSendCount() >= FREE_SEND_TIMES) {
      openCaptchaModal();
    } else {
      doSendCode();
    }
  };

  // 真正调用接口发送验证码
  const doSendCode = (captchaCode?: string) => {
    if (captchaCode !== undefined) {
      if (!captchaCode) {
        message.error('请输入图形验证码');
        return;
      }
      if (captchaText.value !== captchaCode.toLowerCase()) {
        message.error('图形验证码不正确');
        return;
      }
    }

    codeLoading.value = true;
    const sendPromise =
      activeTab.value === 'email'
        ? sendEmailCaptcha({ email: form.email }, { skipTenant: true })
        : sendSmsCaptchaByAdmin({ phone: form.phone }, { skipTenant: true });

    sendPromise
      .then(() => {
        message.success(
          activeTab.value === 'email'
            ? t('login.forgetPage.sentEmail')
            : t('login.forgetPage.getCode')
        );
        captchaVisible.value = false;
        increaseSendCount();
        startCountdown();
      })
      .catch((e: Error) => {
        message.error(e.message);
        refreshCaptcha();
      })
      .finally(() => {
        codeLoading.value = false;
      });
  };

  const startCountdown = () => {
    countdownTime.value = 60;
    countdownTimer = window.setInterval(() => {
      if (countdownTime.value <= 1) {
        countdownTimer && clearInterval(countdownTimer);
        countdownTimer = null;
      }
      countdownTime.value--;
    }, 1000);
  };

  const goLogin = () => {
    router.push('/login');
  };

  // 提交重置
  const submit = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        const params: Record<string, unknown> = {
          newPassword: form.newPassword,
          confirmPassword: form.confirmPassword
        };
        if (activeTab.value === 'email') {
          params.email = form.email;
          params.emailCode = form.emailCode;
        } else {
          params.phone = form.phone;
          params.smsCode = form.code;
        }
        resetPassword(params as any)
          .then((msg) => {
            message.success(msg || t('login.forgetPage.success'));
            loading.value = false;
            router.push('/login');
          })
          .catch((e: Error) => {
            message.error(e.message);
            loading.value = false;
          });
      })
      .catch(() => {});
  };

  onUnmounted(() => {
    if (countdownTimer) clearInterval(countdownTimer);
  });
</script>

<style lang="less" scoped>
  .login-wrapper {
    padding: 48px 16px 0 16px;
    position: relative;
    box-sizing: border-box;
    background-color: var(--grey-5);
    background-repeat: no-repeat;
    background-size: cover;
    min-height: 100vh;

    &:before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0, 0, 0, 0.2);
    }
  }

  .forget-subtitle {
    text-align: center;
    color: #8c8c8c;
    margin: -8px 0 16px;
    font-size: 13px;
  }

  .login-form {
    width: 380px;
    margin: 0 auto;
    max-width: 100%;
    padding: 0 28px;
    box-sizing: border-box;
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15);
    border-radius: 2px;
    position: relative;
    z-index: 2;

    h4 {
      padding: 22px 0;
      text-align: center;
    }

    .title-btn {
      cursor: pointer;
      white-space: nowrap;
    }

    .login-title {
      position: relative;
      display: flex;
      justify-content: space-around;
      line-height: 50px;

      .active {
        color: #007dff;
      }
    }
  }

  .forget-tabs {
    :deep(.ant-tabs-nav) {
      margin-bottom: 20px;
    }
  }

  .login-input-group {
    display: flex;
    align-items: center;
    background-repeat: no-repeat;

    :deep(.ant-input-affix-wrapper) {
      flex: 1;
    }

    .login-captcha {
      width: 102px;
      height: 40px;
      margin-left: 10px;
      padding: 0;
    }
  }

  .login-copyright {
    color: #eee;
    text-align: center;
    padding: 48px 0 22px 0;
    position: relative;
    z-index: 1;
  }

  .logo-login {
    position: absolute;
    top: 20px;
    left: 20px;
    display: flex;
    align-items: center;
    cursor: pointer;

    img {
      width: 28px;
      height: 28px;
      border-radius: 4px;
    }

    h4 {
      margin-left: 6px;
      color: #ffffff;
      font-size: 20px;
    }
  }

  @media screen and (min-height: 640px) {
    .login-wrapper {
      padding-top: 0;
    }

    .login-form {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateX(-50%);
      margin-top: -260px;
    }

    .login-copyright {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
    }
  }

  @media screen and (max-width: 768px) {
    .login-form {
      left: 50%;
      right: auto;
      margin-left: 0;
      margin-right: auto;
      transform: translateX(-50%);
    }
  }
</style>
