<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 justify-center items-center px-12">
        <h4 class="title-btn">邀请注册</h4>
      </div>
      <template v-if="loginType === 'account'">
        <!-- 邀请信息显示 -->
        <div
          v-if="inviterId"
          style="
            margin-bottom: 16px;
            padding: 12px;
            background: #f6ffed;
            border: 1px solid #b7eb8f;
            border-radius: 4px;
          "
        >
          <div style="color: #52c41a; font-size: 14px">
            <check-circle-outlined style="margin-right: 4px" />
            您正在通过邀请链接注册，注册成功后将自动建立推荐关系
          </div>
        </div>

        <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="code">
          <div class="login-input-group">
            <a-input
              placeholder="请输入验证码"
              v-model:value="form.code"
              size="large"
              :maxlength="6"
              allow-clear
              @pressEnter="submit"
            />
            <a-button
              class="login-captcha"
              :disabled="!!countdownTime"
              @click="openImgCodeModal"
            >
              <span v-if="!countdownTime">发送验证码</span>
              <span v-else>已发送 {{ countdownTime }} s</span>
            </a-button>
          </div>
        </a-form-item>
        <a-form-item>
          <a-checkbox v-model:checked="form.remember">
            同意
            <a href="https://website.websoft.top/xieyi/01.html" target="_blank"
              >《服务协议及隐私政策》</a
            >
          </a-checkbox>
        </a-form-item>
        <a-form-item>
          <a-button
            block
            size="large"
            type="primary"
            :disabled="!form.remember"
            :loading="loading"
            @click="submit"
          >
            注册
          </a-button>
        </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="code">
          <div class="login-input-group">
            <a-input
              placeholder="请输入验证码"
              v-model:value="form.code"
              size="large"
              :maxlength="6"
              allow-clear
              @pressEnter="submit"
            />
            <a-button
              class="login-captcha"
              :disabled="!!countdownTime"
              @click="openImgCodeModal"
            >
              <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="submit"
          >
            {{ loading ? t('login.loading') : t('login.login') }}
          </a-button>
        </a-form-item>
      </template>
    </a-form>
    <div class="login-copyright">
      <a-space>
        <span>© {{ new Date().getFullYear() }}</span>
        <span>{{ config?.copyright || 'websoft.top 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"
        />
        <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"
      >
        立即发送
      </a-button>
    </a-modal>
  </div>
  <!-- 地图位置选择弹窗 -->
  <ele-map-picker
    :need-city="true"
    :dark-mode="darkMode"
    v-model:visible="showMap"
    :center="[108.374959, 22.767024]"
    :search-type="1"
    :zoom="12"
    @done="onDone"
  />
</template>

<script lang="ts" setup>
  import { ref, reactive, unref, watch, onMounted, onBeforeUnmount } from 'vue';
  import { useI18n } from 'vue-i18n';
  import { useRouter } from 'vue-router';
  import { getTenantId } from '@/utils/domain';
  import { Form, message } from 'ant-design-vue';
  import { CheckCircleOutlined } from '@ant-design/icons-vue';
  import { storeToRefs } from 'pinia';
  import { goHomeRoute, cleanPageTabs } from '@/utils/page-tab-util';
  import {
    getCaptcha,
    loginBySms,
    registerUser,
    sendSmsCaptcha
  } from '@/api/passport/login';
  import { 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 { useThemeStore } from '@/store/modules/theme';
  import { User } from '@/api/system/user/model';
  import { addShopDealerReferee } from '@/api/shop/shopDealerReferee';
  import { getToken } from '@/utils/token-util';
  import { useUserStore } from '@/store/modules/user';

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

  // 登录框方向, 0 居中, 1 居右, 2 居左
  const direction = ref(0);
  // 加载状态
  const loading = ref(false);
  // 是否显示tenantId填写输入框
  const showTenantId = ref(true);
  const loginType = ref('account');
  const config = ref<Config>();
  // 是否开启响应式布局
  const themeStore = useThemeStore();
  const { darkMode } = storeToRefs(themeStore);
  const userStore = useUserStore();

  // 配置信息
  const { form } = useFormData<User>({
    phone: '',
    code: '',
    remember: false, // 这里作为“同意协议”的勾选状态使用
    isAdmin: true,
    dealerId: undefined
  });

  // 验证码 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 showMap = ref(false);
  // 邀请人ID
  const inviterId = ref<number>();

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

  // 表单验证规则（只保留本页面实际填写的字段）
  const rules = reactive({
    phone: [
      {
        pattern: phoneReg,
        required: true,
        type: 'string',
        message: '手机号格式不正确',
        trigger: 'blur'
      }
    ],
    code: [
      {
        required: true,
        message: t('login.code'),
        type: 'string'
      }
    ]
  });

  /* 显示发送短信验证码弹窗 */
  const openImgCodeModal = () => {
    if (!form.phone) {
      message.error('请输入手机号码');
      return;
    }
    imgCode.value = '';
    changeCaptcha();
    visible.value = true;
  };

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

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

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

  // 建立邀请推荐关系（需要登录态；失败不影响主流程）
  let bindInviterDone = false;
  let bindInviterInFlight: Promise<unknown> | null = null;
  const tryBindInviteRelation = async () => {
    if (bindInviterDone) {
      return;
    }
    if (bindInviterInFlight) {
      return bindInviterInFlight;
    }
    if (!inviterId.value) {
      return;
    }
    if (!getToken()) {
      return;
    }
    const tenantId =
      Number(localStorage.getItem('TenantId')) ||
      Number(userStore.info?.tenantId) ||
      Number(form.tenantId) ||
      undefined;
    const userId =
      Number(localStorage.getItem('UserId')) ||
      Number(userStore.info?.userId) ||
      0;
    if (!userId) {
      return;
    }
    bindInviterInFlight = addShopDealerReferee({
      dealerId: inviterId.value,
      userId,
      level: 1,
      tenantId
    }).then(
      (res) => {
        bindInviterDone = true;
        return res;
      },
      (e) => {
        // Allow retry if the add failed (e.g. user info not ready yet).
        bindInviterDone = false;
        throw e;
      }
    );
    try {
      await bindInviterInFlight;
    } finally {
      bindInviterInFlight = null;
    }
  };

  /* 保存编辑 */
  const submit = async () => {
    if (!formRef.value) {
      return;
    }

    try {
      await formRef.value.validate();
    } catch {
      return;
    }

    loading.value = true;
    try {
      // 通过短信验证码完成注册；inviter 作为推荐人ID传给后端
      const msg = await registerUser({
        tenantId: form.tenantId,
        phone: form.phone,
        username: form.phone,
        code: form.code?.trim(),
        // 后端若用 Java boolean 命名为 `isAdmin`，序列化/反序列化可能会被映射成 `admin`；
        // 这里双写以兼容不同字段名，避免后端拿到 null 导致 NPE。
        isAdmin: true,
        ...({ admin: true } as any),
        dealerId: inviterId.value
      });

      // 注册成功后自动登录，再建立绑定关系（避免未登录时后端取 role 为空）
      await loginBySms({
        tenantId: form.tenantId,
        phone: form.phone,
        code: form.code?.trim(),
        remember: !!form.remember
      });

      // 确保拿到 userId/tenantId（部分后端登录接口可能不返回 user 字段）
      await userStore.fetchUserInfo().catch(() => void 0);

      // 建立绑定关系（失败不影响主流程）
      try {
        await tryBindInviteRelation();
      } catch (e: any) {
        message.warning(
          `注册成功，但建立推荐关系失败：${e?.message || '未知错误'}`
        );
      }

      message.success(msg);
      resetFields();
      cleanPageTabs();
      goHome();
    } catch (e: any) {
      message.error(e?.message || '注册失败');
    } finally {
      loading.value = false;
    }
  };

  /* 获取图形验证码 */
  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();

  // 检查URL参数中的邀请人ID
  onMounted(() => {
    // 优先从链接参数中拿 tenantId（新用户未登录时，用于后端识别租户/初始化角色）
    const tenantIdParam = (unref(currentRoute).query.tenantId ??
      new URLSearchParams(window.location.search).get('tenantId')) as
      | string
      | undefined;
    if (tenantIdParam != null && tenantIdParam !== '') {
      const tid = Number.parseInt(String(tenantIdParam).trim(), 10);
      if (!Number.isNaN(tid) && tid > 0) {
        form.tenantId = tid;
        // 让 request 拦截器也能带上 TenantId
        localStorage.setItem('TenantId', String(tid));
        showTenantId.value = false;
      }
    }

    const inviterParam = (unref(currentRoute).query.inviter ??
      new URLSearchParams(window.location.search).get('inviter')) as
      | string
      | undefined;
    if (inviterParam != null && inviterParam !== '') {
      // 容错：有些场景会把链接后面带上逗号/空格等（例如复制文本），这里提取首段数字
      const raw = String(inviterParam).trim();
      const id = Number.parseInt(raw.match(/\d+/)?.[0] || '', 10);
      if (!Number.isNaN(id) && id > 0) {
        inviterId.value = id;
        form.dealerId = id;
      }
    }

    // 已登录用户通过邀请链接访问时，补绑一次推荐关系
    tryBindInviteRelation();
  });

  onBeforeUnmount(() => {
    if (countdownTimer) {
      clearInterval(countdownTimer);
      countdownTimer = null;
    }
  });

  // 地图选择回调（本页面不使用地图能力，避免模板引用报错）
  const onDone = () => {
    showMap.value = false;
  };

  watch(
    currentRoute,
    () => {
      // 解析二级域名获取租户ID
      const tenantId = getTenantId();
      if (tenantId) {
        form.tenantId = Number(tenantId);
        showTenantId.value = false;
      }
      const tid = localStorage.getItem('TenantId');
      if (tid) {
        form.tenantId = Number(tid);
        showTenantId.value = false;
      }
    },
    { 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: 450px;
    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;
    }

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

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

  .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>
