<template>
  <view class="page">
    <view
      class="header"
      :style="{ paddingTop: statusBarHeight + 'px' }"
    >
      <image
        class="header-bg"
        :src="headerBg"
        mode="aspectFill"
      />
      <view class="header-mask" />
      <view class="header-inner">
        <text class="greet">您好，</text>
        <text class="welcome">欢迎</text>
      </view>
    </view>

    <view class="sheet">
      <view v-if="loading" class="loading">
        <text>登录中…</text>
      </view>

      <template v-else>
        <template v-if="apiOn">
          <!-- #ifdef MP-WEIXIN -->
          <text class="login-tip">
            浏览作品无需登录。需要上传、管理内容或同步账号信息时再登录即可。
          </text>
          <button class="btn btn-main" @click="onWeixinLogin">快捷登录</button>
          <text class="guest-link" @tap="goBrowseHome">返回首页，先浏览作品</text>
          <!-- #endif -->

          <!-- #ifndef MP-WEIXIN -->
          <view class="field">
            <text class="label">手机号</text>
            <input
              v-model="phone"
              class="input"
              type="number"
              maxlength="11"
              placeholder="请输入您的手机号"
              placeholder-class="ph"
            />
            <view class="line" />
          </view>
          <view class="field">
            <text class="label">密码</text>
            <input
              v-model="password"
              class="input"
              password
              placeholder="请输入您的密码"
              placeholder-class="ph"
            />
            <view class="line" />
          </view>
          <text class="forgot" @click="onForgot">忘记密码？</text>
          <button class="btn btn-main" @click="onPhoneLogin">登录</button>
          <button class="btn btn-sub" @click="onRegister">注册</button>
          <text class="guest-link" @click="onGuestQuick">游客进入，暂不登录</text>
          <!-- #endif -->
        </template>

        <template v-else>
          <text class="off-tip">当前为离线演示模式</text>
          <button class="btn btn-main" @click="enterDemo">进入首页</button>
        </template>
      </template>

      <text v-if="errMsg" class="err">{{ errMsg }}</text>
    </view>
  </view>
</template>

<script setup lang="ts">
import { onLoad, onShow } from "@dcloudio/uni-app";
import { ref } from "vue";
import {
  apiEnabled,
  appendLoopbackConnectHint,
  isApiBaseLoopback,
} from "@/config/api";
import { getMpToken } from "@/utils/api/http";
import { getMpLoginChannel, loginAsGuest, loginWithPhone, loginWithWeixin } from "@/utils/api/mpSession";
import { staticAsset } from "@/utils/staticAsset";
const statusBarHeight = ref(20);
const headerBg = staticAsset("login-header.png");
const apiOn = ref(apiEnabled());
const loading = ref(false);
const errMsg = ref("");
const phone = ref("");
const password = ref("");
/** 快捷登录成功后要进入的 tab（仅小程序） */
const pendingTab = ref<"home" | "upload" | "user">("home");

function goHome() {
  uni.switchTab({ url: "/pages/home/home" });
}

function goBrowseHome() {
  errMsg.value = "";
  uni.switchTab({ url: "/pages/home/home" });
}

function afterLoginNavigate() {
  // #ifdef MP-WEIXIN
  const t = pendingTab.value;
  if (t === "upload" || t === "user") {
    pendingTab.value = "home";
    setTimeout(() => {
      uni.switchTab({
        url: t === "upload" ? "/pages/upload/upload" : "/pages/user/user",
      });
    }, 320);
    return;
  }
  // #endif
  setTimeout(() => goHome(), 400);
}

onLoad((opts: Record<string, string | undefined>) => {
  const t = String(opts?.tab || "").trim();
  if (t === "upload" || t === "user") {
    pendingTab.value = t;
    errMsg.value =
      t === "upload" ? "发布作品需先完成快捷登录" : "查看「我的」需先完成快捷登录";
  }
});

onShow(() => {
  statusBarHeight.value = uni.getSystemInfoSync().statusBarHeight || 20;
  apiOn.value = apiEnabled();
  const token = getMpToken();
  // #ifdef MP-WEIXIN
  if (apiOn.value && token && getMpLoginChannel() === "weixin") {
    goHome();
  }
  // #endif
  // #ifndef MP-WEIXIN
  if (apiOn.value && token) {
    goHome();
  }
  // #endif
  // #ifdef APP-PLUS
  if (apiOn.value && isApiBaseLoopback() && !errMsg.value) {
    errMsg.value =
      "当前接口为 127.0.0.1，手机无法访问开发电脑。请修改 uniapp/.env.development 中 VITE_API_BASE_URL 为电脑局域网 IP 后重新编译。";
  }
  // #endif
});

function enterDemo() {
  errMsg.value = "";
  goHome();
}

function onForgot() {
  uni.showToast({
    title: "请联系管理员或通过小程序客服找回",
    icon: "none",
  });
}

function pickErr(e: unknown, fallback: string): string {
  if (e && typeof e === "object" && "msg" in e && typeof (e as { msg: string }).msg === "string") {
    return (e as { msg: string }).msg;
  }
  if (e && typeof e === "object" && "errMsg" in e && typeof (e as { errMsg: string }).errMsg === "string") {
    const m = (e as { errMsg: string }).errMsg.trim();
    if (m) return m;
  }
  if (e instanceof Error && e.message.trim()) {
    return e.message;
  }
  return fallback;
}

function normalizeAuditSafeMessage(msg: string): string {
  const m = String(msg || "").trim();
  if (!m) return "请求失败，请稍后重试";
  const low = m.toLowerCase();
  // 微信审核常见：request:fail url not in domain list
  if (low.includes("url not in domain list")) {
    return "网络配置异常，请稍后重试";
  }
  if (low.includes("request:fail") || low.includes("network")) {
    return "网络请求失败，请稍后重试";
  }
  return m;
}

async function onWeixinLogin() {
  errMsg.value = "";
  loading.value = true;
  try {
    // #ifdef MP-WEIXIN
    await loginWithWeixin();
    // #endif
    // #ifndef MP-WEIXIN
    await loginAsGuest();
    // #endif
    uni.showToast({ title: "登录成功", icon: "success" });
    afterLoginNavigate();
  } catch (e: unknown) {
    const raw = appendLoopbackConnectHint(pickErr(e, "登录失败"));
    const msg = normalizeAuditSafeMessage(raw);
    errMsg.value = msg;
    uni.showToast({
      title: msg.length > 22 ? "网络请求失败，请稍后重试" : msg,
      icon: "none",
      duration: 3200,
    });
  } finally {
    loading.value = false;
  }
}

async function onPhoneLogin() {
  errMsg.value = "";
  const p = phone.value.trim();
  const pwd = password.value;
  if (!/^1\d{10}$/.test(p)) {
    errMsg.value = "请输入11位手机号";
    uni.showToast({ title: errMsg.value, icon: "none" });
    return;
  }
  if (!pwd) {
    errMsg.value = "请输入密码";
    uni.showToast({ title: errMsg.value, icon: "none" });
    return;
  }
  loading.value = true;
  try {
    await loginWithPhone(p, pwd);
    uni.showToast({ title: "登录成功", icon: "success" });
    afterLoginNavigate();
  } catch (e: unknown) {
    const raw = appendLoopbackConnectHint(pickErr(e, "登录失败"));
    const msg = normalizeAuditSafeMessage(raw);
    errMsg.value = msg;
    uni.showToast({
      title: msg.length > 22 ? "网络请求失败，请稍后重试" : msg,
      icon: "none",
      duration: 3200,
    });
  } finally {
    loading.value = false;
  }
}

function onRegister() {
  errMsg.value = "";
  uni.navigateTo({ url: "/pages/register/register" });
}

/** 不注册、不填账号时的快速体验 */
async function onGuestQuick() {
  errMsg.value = "";
  if (!apiOn.value) {
    goHome();
    return;
  }
  loading.value = true;
  try {
    await loginAsGuest();
    uni.showToast({ title: "已进入", icon: "success" });
    setTimeout(() => goHome(), 400);
  } catch (e: unknown) {
    const raw = appendLoopbackConnectHint(pickErr(e, "请求失败"));
    const msg = normalizeAuditSafeMessage(raw);
    errMsg.value = msg;
    uni.showToast({
      title: msg.length > 22 ? "网络请求失败，请稍后重试" : msg,
      icon: "none",
      duration: 3200,
    });
  } finally {
    loading.value = false;
  }
}
</script>

<style scoped>
.page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  box-sizing: border-box;
  overflow: hidden;
  background: #f1f5f9;
}

.header {
  position: relative;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
  min-height: 430rpx;
  padding-bottom: 56rpx;
  box-sizing: border-box;
}

.header-bg {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

.header-mask {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.12) 0%,
    rgba(0, 0, 0, 0.35) 100%
  );
  pointer-events: none;
}

.header-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  padding: 0 48rpx;
  min-height: 0;
}

.greet {
  display: block;
  margin-bottom: 8rpx;
  font-size: 44rpx;
  font-weight: 600;
  color: #fff;
  letter-spacing: 0.02em;
  text-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.25);
}

.welcome {
  display: block;
  font-size: 44rpx;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.02em;
  text-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.25);
}

.sheet {
  flex: 1;
  min-height: 0;
  margin-top: 0;
  padding: 36rpx 48rpx calc(24rpx + env(safe-area-inset-bottom));
  border-radius: 24rpx 24rpx 0 0;
  background: #fff;
  box-shadow: 0 -8rpx 40rpx rgba(0, 0, 0, 0.06);
}

.field {
  margin-bottom: 8rpx;
}

.label {
  display: block;
  margin-bottom: 16rpx;
  font-size: 30rpx;
  font-weight: 600;
  color: #111827;
}

.input {
  display: block;
  width: 100%;
  height: 72rpx;
  padding: 0 4rpx;
  font-size: 30rpx;
  color: #111827;
  border: none;
  background: transparent;
}

.ph {
  color: #c4c4c4;
  font-size: 28rpx;
}

.line {
  height: 1rpx;
  margin-top: 8rpx;
  background: #eeeeee;
}

.forgot {
  display: block;
  margin-top: 12rpx;
  margin-bottom: 32rpx;
  font-size: 24rpx;
  color: #9ca3af;
}

.loading {
  padding: 80rpx 0;
  font-size: 28rpx;
  color: #9ca3af;
  text-align: center;
}

.btn {
  display: flex;
  width: 100%;
  height: 88rpx;
  align-items: center;
  justify-content: center;
  margin-bottom: 20rpx;
  padding: 0;
  font-size: 32rpx;
  font-weight: 500;
  border: none;
  border-radius: 999rpx;
}

.btn::after {
  display: none;
  border: none;
}

.btn-main {
  color: #fff;
  background: #2185ff;
}

.btn-sub {
  color: #111827;
  background: #f3f4f6;
}

.login-tip {
  display: block;
  margin-bottom: 28rpx;
  font-size: 26rpx;
  line-height: 1.5;
  color: #64748b;
  text-align: center;
}

.guest-link {
  display: block;
  margin-top: 8rpx;
  margin-bottom: 0;
  font-size: 26rpx;
  color: #2185ff;
  text-align: center;
}

.off-tip {
  display: block;
  margin-bottom: 48rpx;
  font-size: 28rpx;
  color: #6b7280;
  text-align: center;
}

.err {
  display: block;
  margin-top: 24rpx;
  font-size: 24rpx;
  line-height: 1.4;
  color: #ef4444;
  text-align: center;
}
</style>
