<template>
  <div
    :class="[
      'login-wrapper',
      ['', 'login-form-right', 'login-form-left'][direction]
    ]"
    :style="{
      backgroundImage: 'url(' + config?.loginBgImg + ')'
    }"
  >
    <div class="logo-login" v-if="config?.siteName">
      <img
        :src="
          config.sysLogo ||
          'https://oss.wsdns.cn/20240822/0252ad4ed46449cdafe12f8d3d96c2ea.svg'
        "
        class="logo"
      />
      <h4>{{ config.siteName }}</h4>
    </div>
    <div class="company-name" v-if="config?.loginTitle"
      >{{ config?.loginTitle }}
    </div>
    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      class="login-form ele-bg-white"
    >
      <div class="login-title flex items-center">
        <template v-if="loginType === 'scan'">
          <h4 class="title-btn">扫码登录</h4>
        </template>
        <template v-else>
          <h4
            ref="accountTabRef"
            class="title-btn font-bold text-lg"
            :class="loginType === 'account' ? 'active' : ''"
            @click="onLoginType('account')"
            >账号登录</h4
          >
          <h4
            ref="smsTabRef"
            class="title-btn font-bold text-lg"
            :class="loginType === 'sms' ? 'active' : ''"
            @click="onLoginType('sms')"
            >手机号登录</h4
          >
          <div class="tab-indicator" :style="indicatorStyle"></div>
        </template>
      </div>
      <div
        class="login-bar absolute top-0 z-50 right-0 cursor-pointer"
        @click="onScan"
      >
        <div class="go-to-register cursor-pointer">
          <img
            src="@/assets/O1CN01yz6fEl1MwaRtkJyvf_!!6000000001499-55-tps-70-70.svg"
            alt=""
          />
        </div>
        <div
          class="absolute top-2 right-2 text-lg text-white font-bold cursor-pointer"
        >
          <QrcodeOutlined v-if="loginType === 'scan'" />
          <MobileOutlined v-else />
        </div>
        <!--        <span class="absolute top-3 right-1.5 text-sm text-white font-bold cursor-pointer">{{ '登录' }}</span>-->
      </div>
      <template v-if="loginType === 'account'">
        <a-form-item name="account">
          <a-input
            allow-clear
            size="large"
            v-model:value="form.account"
            placeholder="请输入邮箱"
          >
            <template #prefix>
              <UserOutlined />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item name="password">
          <a-input-password
            size="large"
            v-model:value="form.password"
            placeholder="登录密码"
            @pressEnter="submit"
          >
            <template #prefix>
              <lock-outlined />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item>
          <div class="flex justify-between">
            <a-checkbox v-model:checked="form.remember">
              {{ t('login.remember') }}
            </a-checkbox>
            <a class="login-forget" @click="goForget">{{
              t('login.forget')
            }}</a>
          </div>
        </a-form-item>
        <a-form-item>
          <a-button
            block
            size="large"
            type="primary"
            :loading="loading"
            @click="submit"
          >
            {{ loading ? t('login.loading') : t('login.login') }}
          </a-button>
          <div class="text-center pt-5 text-gray-500"
            >还没有账号？联系管理员开通</div
          >
        </a-form-item>
      </template>
      <template v-if="loginType === 'sms'">
        <a-form-item name="phone">
          <a-input
            allow-clear
            size="large"
            :maxlength="11"
            v-model:value="form.phone"
            :placeholder="`请输入手机号码`"
          >
            <template #addonBefore> +86</template>
          </a-input>
        </a-form-item>
        <a-form-item name="smsCode">
          <div class="login-input-group">
            <a-input
              placeholder="请输入验证码"
              v-model:value="form.smsCode"
              size="large"
              :maxlength="6"
              allow-clear
              @pressEnter="onLoginBySms"
            />
            <a-button
              class="login-captcha"
              :disabled="!!countdownTime"
              @click="handleSendCode"
            >
              <span v-if="!countdownTime">发送验证码</span>
              <span v-else>已发送 {{ countdownTime }} s</span>
            </a-button>
          </div>
        </a-form-item>
        <a-form-item>
          <a-button
            block
            size="large"
            type="primary"
            :loading="loading"
            @click="onLoginBySms"
          >
            {{ loading ? t('login.loading') : t('login.login') }}
          </a-button>
          <div class="text-center pt-5 text-gray-500"
            >还没有账号？联系管理员开通</div
          >
        </a-form-item>
      </template>
      <template v-if="loginType == 'scan'">
        <QrLogin
          @loginSuccess="onQrLoginSuccess"
          @loginError="onQrLoginError"
        />
      </template>
    </a-form>
    <div class="login-copyright">
      <a-space>
        <span>© {{ new Date().getFullYear() }}</span>
        <span>{{ config?.copyright || 'websopy Inc.' }}</span>
      </a-space>
    </div>
    <!-- 编辑弹窗 -->
    <a-modal
      :width="340"
      :footer="null"
      title="发送验证码"
      v-model:visible="visible"
    >
      <div class="login-input-group" style="margin-bottom: 16px">
        <a-input
          v-model:value="imgCode"
          :maxlength="5"
          size="large"
          placeholder="请输入图形验证码"
          allow-clear
          @pressEnter="() => sendCode(imgCode.value)"
        />
        <a-button class="login-captcha">
          <img alt="" :src="captcha" @click="changeCaptcha" />
        </a-button>
      </div>
      <a-button
        block
        size="large"
        type="primary"
        :loading="codeLoading"
        @click="() => sendCode(imgCode.value)"
      >
        立即发送
      </a-button>
    </a-modal>

    <!-- 多租户选择登录 -->
    <a-modal
      :width="420"
      :footer="null"
      :mask-closable="false"
      title="请选择要登录的租户"
      v-model:visible="showSelectTenantModal"
    >
      <div class="flex flex-col justify-start">
        <a-list item-layout="horizontal" :data-source="pendingTenants">
          <template #renderItem="{ item }">
            <a-list-item
              class="cursor-pointer hover:border-gray-100"
              @click="onSelectTenant(item)"
            >
              <a-list-item-meta :description="`租户ID: ${item.tenantId}`">
                <template #title>
                  {{ item.tenantName }}
                </template>
              </a-list-item-meta>
              <template #actions>
                <RightOutlined />
              </template>
            </a-list-item>
          </template>
        </a-list>
      </div>
    </a-modal>

    <!-- 多账户选择登录 -->
    <a-modal
      :width="500"
      :footer="null"
      title="选择账号登录"
      v-model:visible="showSelectLoginUser"
    >
      <div class="flex flex-col justify-start">
        <a-list item-layout="horizontal" :data-source="admins">
          <template #renderItem="{ item }">
            <a-list-item
              class="cursor-pointer hover:border-gray-100"
              @click="onSelectUser(item)"
            >
              <a-list-item-meta :description="`租户ID: ${item.tenantId}`">
                <template #title>
                  {{ item.tenantName }}
                </template>
                <template #avatar>
                  <a-avatar :src="item.avatar" />
                </template>
              </a-list-item-meta>
              <template #actions>
                <RightOutlined />
              </template>
            </a-list-item>
          </template>
        </a-list>
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, unref, watch, nextTick, onMounted } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { useRouter } from 'vue-router';
  import { Form, message } from 'ant-design-vue';
  import {
    LockOutlined,
    UserOutlined,
    QrcodeOutlined,
    MobileOutlined,
    RightOutlined
  } from '@ant-design/icons-vue';
  import { goHomeRoute, cleanPageTabs } from '@/utils/page-tab-util';
  import {
    loginByUserId,
    loginByEmail,
    loginBySuperAdminSms,
    loginBySelectTenant,
    getCaptcha,
    sendSmsCaptcha
  } from '@/api/passport/login';
  import type { TenantOption } from '@/api/passport/login/model';
  import QrLogin from '@/components/QrLogin/index.vue';

  import { User } from '@/api/system/user/model';
  type LoginForm = User & { account?: string };
  import { TEMPLATE_ID, THEME_STORE_NAME } from '@/config/setting';
  import useFormData from '@/utils/use-form-data';
  import { FormInstance } from 'ant-design-vue/es/form';
  import { configWebsiteField } from '@/api/cms/cmsWebsiteField';
  import { Config } from '@/api/cms/cmsWebsiteField/model';
  import { phoneReg } from 'ele-admin-pro';
  import router from '@/router';
  import { listAdminsByEmailAll } from '@/api/system/user';
  import { QrCodeStatusResponse } from '@/api/passport/qrLogin';

  const useForm = Form.useForm;
  const { currentRoute } = useRouter();
  const { t } = useI18n();
  const { locale } = useI18n();

  // 登录框方向, 0 居中, 1 居右, 2 居左
  const direction = ref(0);
  // 加载状态
  const loading = ref(false);
  // 是否显示tenantId填写输入框，默认进入账号登录/手机号登录切换模式
  const loginType = ref('account');
  // 标签下划线指示器
  const accountTabRef = ref<HTMLElement>();
  const smsTabRef = ref<HTMLElement>();
  const indicatorStyle = ref({ left: '0px', width: '0px', transition: 'none' });
  // 收缩/展开两阶段动画时长(ms)，模拟阿里云"先收一下再展开"的弹性效果
  const SHRINK_MS = 150;
  const EXPAND_MS = 220;
  let indicatorTimer: number | null = null;
  const updateIndicator = (animate = true) => {
    if (indicatorTimer != null) {
      clearTimeout(indicatorTimer);
      indicatorTimer = null;
    }
    nextTick(() => {
      const activeEl =
        loginType.value === 'account' ? accountTabRef.value : smsTabRef.value;
      if (!activeEl) {
        return;
      }
      const targetLeft = activeEl.offsetLeft;
      const targetWidth = activeEl.offsetWidth;
      // 非动画：直接定位（首次渲染 / 窗口缩放）
      if (!animate) {
        indicatorStyle.value = {
          left: `${targetLeft}px`,
          width: `${targetWidth}px`,
          transition: 'none'
        };
        return;
      }
      // 阶段一：收缩成一条短线，并滑向目标中心
      const targetCenter = targetLeft + targetWidth / 2;
      const smallWidth = 8;
      indicatorStyle.value = {
        left: `${targetCenter - smallWidth / 2}px`,
        width: `${smallWidth}px`,
        transition: `left ${SHRINK_MS}ms ease-in, width ${SHRINK_MS}ms ease-in`
      };
      // 阶段二：展开到目标标签的宽度
      indicatorTimer = window.setTimeout(() => {
        indicatorStyle.value = {
          left: `${targetLeft}px`,
          width: `${targetWidth}px`,
          transition: `left ${EXPAND_MS}ms ease-out, width ${EXPAND_MS}ms ease-out`
        };
        indicatorTimer = null;
      }, SHRINK_MS);
    });
  };
  watch(loginType, () => updateIndicator(true), { immediate: true });
  onMounted(() => {
    updateIndicator(false);
    window.addEventListener('resize', () => updateIndicator(false));
  });
  const config = ref<Config>();
  // 配置信息
  const { form } = useFormData<LoginForm>({
    account: '',
    userId: undefined,
    phone: '',
    email: '',
    password: '',
    code: '',
    smsCode: '',
    tenantId: undefined,
    templateId: TEMPLATE_ID,
    isSuperAdmin: true,
    remember: true
  });

  // 验证码 base64 数据
  const captcha = ref('');
  // 验证码内容, 实际项目去掉
  const text = ref('');
  // 是否显示图形验证码弹窗
  const visible = ref(false);
  // 图形验证码
  const imgCode = ref('');
  // 发送验证码按钮loading
  const codeLoading = ref(false);
  // 验证码倒计时时间
  const countdownTime = ref(0);
  // 验证码倒计时定时器
  let countdownTimer: number | null = null;
  // 多用户选择账号登录
  const showSelectLoginUser = ref<boolean>(false);
  const admins = ref<User[]>([]);
  // 多租户选择登录（手机号登录时同一手机号对应多个租户）
  const showSelectTenantModal = ref<boolean>(false);
  const pendingTenants = ref<TenantOption[]>([]);
  const selectingTenant = ref<boolean>(false);
  // const tenantId = getTenantId();

  // 表格选中数据
  const formRef = ref<FormInstance | null>(null);

  // 表单验证规则
  const rules = reactive({
    account: [
      {
        required: true,
        message: '请输入邮箱',
        type: 'string',
        trigger: 'blur'
      },
      {
        validator: (_rule: unknown, value: string) => {
          if (!value) {
            return Promise.resolve();
          }
          const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
          const isNumber = /^\d+$/.test(value);
          if (isEmail || isNumber) {
            return Promise.resolve();
          }
          return Promise.reject(new Error('请输入正确邮箱'));
        },
        trigger: 'blur'
      }
    ],
    phone: [
      {
        pattern: phoneReg,
        required: true,
        type: 'string',
        message: '手机号格式不正确',
        trigger: 'blur'
      }
    ],
    password: [
      {
        required: true,
        message: t('login.password'),
        type: 'string'
      }
    ],
    code: [
      {
        required: true,
        message: t('login.code'),
        type: 'string'
      }
    ],
    smsCode: [
      {
        required: true,
        message: t('login.code'),
        type: 'string'
      }
    ]
  });

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

  // 根据手机号生成发送次数缓存 key
  const getSendCountKey = () => `login_sms_send_count_${form.phone}`;

  // 读取当前手机号已发送次数
  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 handleSendCode = () => {
    if (!form.phone) {
      message.error('请输入手机号码');
      return;
    }
    if (getSendCount() >= FREE_SEND_TIMES) {
      imgCode.value = '';
      changeCaptcha();
      visible.value = true;
    } else {
      sendCode();
    }
  };

  /* 发送短信验证码 */
  const sendCode = (captchaCode?: string) => {
    if (captchaCode !== undefined) {
      if (!captchaCode) {
        message.error('请输入图形验证码');
        return;
      }
      if (text.value !== captchaCode.toLowerCase()) {
        message.error('图形验证码不正确');
        return;
      }
    }
    codeLoading.value = true;
    sendSmsCaptcha({ phone: form.phone })
      .then(() => {
        message.success('短信验证码发送成功, 请注意查收!');
        visible.value = false;
        increaseSendCount();
        countdownTime.value = 30;
        // 开始对按钮进行倒计时
        countdownTimer = window.setInterval(() => {
          if (countdownTime.value <= 1) {
            countdownTimer && clearInterval(countdownTimer);
            countdownTimer = null;
          }
          countdownTime.value--;
        }, 1000);
      })
      .catch((e: Error) => {
        message.error(e.message);
        changeCaptcha();
      })
      .finally(() => {
        codeLoading.value = false;
      });
  };

  /* 跳转到忘记密码页 */
  const goForget = () => {
    router.push('/forget');
  };

  // const { clearValidate, validate, validateInfos } = useForm(form, rules);

  const { resetFields } = useForm(form, rules);

  const goHome = () => {
    const { query } = unref(currentRoute);
    goHomeRoute(query.from as string);
    localStorage.removeItem(THEME_STORE_NAME);
  };

  const onLoginBySms = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        form.code = form.smsCode?.toLowerCase();
        loginBySuperAdminSms(form)
          .then((outcome) => {
            if (outcome.status === 'selectTenant') {
              pendingTenants.value = outcome.tenants;
              showSelectTenantModal.value = true;
              loading.value = false;
              return;
            }
            message.success(outcome.message);
            loading.value = false;
            resetFields();
            cleanPageTabs();
            goHome();
          })
          .catch((e: Error) => {
            message.error(e.message);
            loading.value = false;
          });
      })
      .catch(() => {});
  };

  /* 选择租户后二次登录 */
  const onSelectTenant = (item: TenantOption) => {
    if (selectingTenant.value || item.tenantId == null) return;
    selectingTenant.value = true;
    loginBySelectTenant({
      phone: form.phone,
      code: form.smsCode || '',
      tenantId: item.tenantId,
      remember: form.remember
    })
      .then((outcome) => {
        showSelectTenantModal.value = false;
        message.success(outcome.message);
        resetFields();
        cleanPageTabs();
        goHome();
      })
      .catch((e: Error) => message.error(e.message))
      .finally(() => {
        selectingTenant.value = false;
      });
  };

  /* 邮箱登录（跨租户） */
  const onSelectUser = (item: User) => {
    form.tenantId = item.tenantId;
    submit();
  };

  /* 账号登录（用户ID / 邮箱登录合并） */
  const submit = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        const account = (form.account || '').trim();
        // 判断输入的是邮箱还是用户ID（纯数字）
        const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(account);
        const payload = {
          password: form.password,
          remember: form.remember
        };
        const req = isEmail
          ? loginByEmail({
              ...payload,
              email: account,
              tenantId: form.tenantId
            })
          : loginByUserId({ ...payload, userId: account });
        req
          .then((msg) => {
            if (msg == '请选择登录用户') {
              showSelectLoginUser.value = true;
              listAdminsByEmailAll({
                email: account,
                templateId: TEMPLATE_ID
              }).then((data) => {
                admins.value = data;
              });
              return false;
            }
            // 登录成功
            message.success(msg);
            loading.value = false;
            resetFields();
            cleanPageTabs();
            goHome();
          })
          .catch((e: Error) => {
            message.error(e.message);
            loading.value = false;
          });
      })
      .catch(() => {});
  };

  // const doRegister = () => {
  //   registerUser(form)
  //     .then(() => {
  //       loading.value = false;
  //       message.success('注册成功');
  //     })
  //     .catch((e) => {
  //       loading.value = false;
  //       message.error(e.message);
  //     });
  // };

  const onLoginType = (text) => {
    loginType.value = text;
  };

  const onScan = () => {
    if (loginType.value == 'scan') {
      loginType.value = 'sms';
    } else {
      loginType.value = 'scan';
    }
  };

  /* 二维码登录成功处理 */
  const onQrLoginSuccess = async (item: QrCodeStatusResponse) => {
    // 设置token到localStorage或其他存储
    localStorage.setItem('access_token', item.accessToken || '');
    message.success('扫码登录成功');
    if (item) {
      localStorage.setItem('access_token', `${item.accessToken}`);
      localStorage.setItem('TenantId', `${item.tenantId}`);
      cleanPageTabs();
      goHome();
    }
  };

  /* 二维码登录错误处理 */
  const onQrLoginError = (error: string) => {
    message.error(error || '扫码登录失败');
  };

  // const goBack = () => {
  //   openUrl(getDomain());
  //   return;
  // };

  const loginConnect = () => {
    // getWxWorkQrConnect().then((result) => {
    //   console.log(result);
    //   qrConnect.value = result;
    // });
  };

  /* 获取图形验证码 */
  const changeCaptcha = () => {
    configWebsiteField({ lang: locale.value }).then((data) => {
      config.value = data;
    });
    // 这里演示的验证码是后端返回base64格式的形式, 如果后端地址直接是图片请参考忘记密码页面
    getCaptcha()
      .then((data) => {
        captcha.value = data.base64;
        // 实际项目后端一般会返回验证码的key而不是直接返回验证码的内容, 登录用key去验证, 你可以根据自己后端接口修改
        text.value = data.text;
        // 自动回填验证码, 实际项目去掉这个
        // form.code = data.text;
        // resetFields();
      })
      .catch((e) => {
        message.error(e.message);
      });
  };

  // 首次加载
  changeCaptcha();
  loginConnect();

  watch(
    router.currentRoute,
    (data) => {
      if (data.query?.loginPhone) {
        form.phone = `${data.query?.loginPhone}`;
      } else {
        localStorage.clear();
      }
    },
    { immediate: true }
  );
</script>

<style lang="less" scoped>
  /* 背景 */
  .login-wrapper {
    padding: 48px 16px 0 16px;
    position: relative;
    box-sizing: border-box;
    background-image: url('@/assets/bg-2.jpeg');
    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);
    }
  }

  .company-name {
    position: absolute;
    top: 17%;
    left: 50%;
    transform: translateX(-50%);
    font-size: 24px;
    color: #ffffff;
  }

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

    h4 {
      text-align: center;
    }

    .title-btn {
      cursor: pointer;
      white-space: nowrap;
      transition: color 0.3s;
    }

    .login-title {
      position: relative;
      display: flex;
      flex-wrap: nowrap;
      line-height: 1;
      margin-top: 10px;
      margin-bottom: 38px;
      gap: 20px;

      .active {
        color: #007dff;
      }

      .tab-indicator {
        position: absolute;
        bottom: -10px;
        height: 3px;
        border-radius: 2px;
        background-color: #007dff;
      }
    }

    :deep(.ant-form-item) {
      margin-bottom: 18px;
    }
  }

  .login-form-right .login-form {
    margin: 0 15% 0 auto;
  }

  .login-form-left .login-form {
    margin: 0 auto 0 15%;
  }

  /* 验证码 */
  .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;

      & > img {
        width: 100%;
        height: 100%;
      }
    }
  }

  /* 第三方登录图标 */
  .login-oauth-icon {
    color: #fff;
    padding: 5px;
    margin: 0 12px;
    font-size: 18px;
    border-radius: 50%;
    cursor: pointer;
  }

  .work-icon {
    width: 50px;
    height: 50px;
  }

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

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

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

    .login-form-right .login-form,
    .login-form-left .login-form {
      left: auto;
      right: 15%;
      transform: translateX(0);
      margin: -230px auto auto auto;
    }

    .login-form-left .login-form {
      right: auto;
      left: 15%;
    }

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

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

  .wwLogin_qrcode_head {
    padding: 10px 0 40px 0 !important;
  }

  .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;
    }
  }
</style>
