import NextAuth, { type NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { prisma } from "./prisma";
import { z } from "zod";

/**
 * Auth.js v5 配置
 *
 * 支持渠道（按优先级）：
 *  1. 手机号 + 短信 OTP（国内主推）
 *  2. 微信扫码（待团队配置 appId/secret 后开启 · 启用时需把 PrismaAdapter 加回来）
 *  3. 邮箱（境外用户备用）
 *
 * 当前阶段：使用 JWT session 策略，Credentials 不需要 Adapter。
 * 数据库不可用时自动降级为内存用户（开发态友好）。
 */

const OtpCredentials = z.object({
  phone: z
    .string()
    .regex(/^1[3-9]\d{9}$/, "请输入有效的中国大陆手机号"),
  code: z.string().regex(/^\d{6}$/, "请输入 6 位验证码"),
});

export const authConfig: NextAuthConfig = {
  // NOTE: Credentials + JWT 策略不需要 adapter。
  // 启用微信 OAuth 时再把 PrismaAdapter 加回来。
  session: { strategy: "jwt" },
  pages: {
    signIn: "/login",
  },
  providers: [
    Credentials({
      id: "phone-otp",
      name: "Phone OTP",
      credentials: {
        phone: { label: "手机号", type: "tel" },
        code: { label: "验证码", type: "text" },
      },
      async authorize(raw) {
        const parsed = OtpCredentials.safeParse(raw);
        if (!parsed.success) return null;
        const { phone, code } = parsed.data;

        const validOtp = await verifyOtp(phone, code);
        if (!validOtp) return null;

        // 尝试持久化到数据库；失败则降级为内存身份（开发态）
        try {
          const user = await prisma.user.upsert({
            where: { phone },
            create: {
              phone,
              nickname: `粉丝_${phone.slice(-4)}`,
              loginType: "PHONE",
            },
            update: { lastLoginAt: new Date() },
          });
          return {
            id: String(user.id),
            name: user.nickname,
            image: user.avatar ?? undefined,
          };
        } catch (err) {
          if (process.env.NODE_ENV === "production") {
            console.error("[auth] DB upsert failed:", err);
            return null;
          }
          // 开发态：用手机号末 9 位做确定性 ID，便于跨重启保持身份
          const fakeId = String(parseInt(phone.slice(-9), 10));
          console.warn(
            `[auth] DB 不可用，开发态降级身份 id=${fakeId} phone=${phone}`,
          );
          return {
            id: fakeId,
            name: `粉丝_${phone.slice(-4)}`,
          };
        }
      },
    }),

    // TODO[团队]: 启用微信扫码登录（需配置 WECHAT_APP_ID/SECRET 并加回 PrismaAdapter）
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.uid = user.id;
      }
      return token;
    },
    async session({ session, token }) {
      if (token.uid) {
        (session.user as { id?: unknown }).id = token.uid;
      }
      return session;
    },
  },
  trustHost: true,
};

export const { handlers, signIn, signOut, auth } = NextAuth(authConfig);

/**
 * 校验 OTP 验证码（开发态：固定接受 "123456"）。
 * 生产态：从 Redis 读取并比对，校验后删除避免重放。
 */
async function verifyOtp(phone: string, code: string): Promise<boolean> {
  if (process.env.NODE_ENV !== "production" && code === "123456") {
    console.log(`[dev-otp] 手机号 ${phone} 使用万能码 123456 通过`);
    return true;
  }

  // TODO[团队]: 接入 Redis
  // const redis = getRedis();
  // if (!redis) return false;
  // const key = `sms:otp:${phone}`;
  // const stored = await redis.get(key);
  // if (!stored || stored !== code) return false;
  // await redis.del(key);
  // return true;

  return false;
}
