import { CustomPrismaAdapter } from "@/lib/customPrismaAdapter";
import GoogleProvider from "next-auth/providers/google";
import CredentialsProvider from "next-auth/providers/credentials";
import { prisma } from "@/lib/prisma";
import bcrypt from "bcryptjs";
import { Session, User } from "next-auth";
import { JWT } from "next-auth/jwt";
import { AdapterUser } from "next-auth/adapters";

// JWT token refresh configuration
const JWT_REFRESH_INTERVAL = 15 * 60 * 1000; // 15 minutes - adjust as needed

export const authOptions = {
  adapter: CustomPrismaAdapter(),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "your@email.com" },
        password: { label: "Password", type: "password" },
        captcha: { label: "Captcha", type: "text" },
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) {
          throw new Error("Please enter both email and password.");
        }

        const user = await prisma.user.findUnique({
          where: { email: credentials.email.toLowerCase() },
          select: {
            id: true,
            email: true,
            name: true,
            image: true,
            password: true,
            pinCode: true,
            timezoneOffset: true,
            createdAt: true,
          },
        });

        if (!user || !user.password) {
          throw new Error("Invalid email or password.");
        }

        const justCreated =
          user.createdAt &&
          Date.now() - new Date(user.createdAt).getTime() < 100000;
        if (!justCreated) {
          if (!credentials?.captcha) {
            throw new Error("Missing credentials or CAPTCHA.");
          }
          const verifyUrl = `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${credentials.captcha}`;
          const captchaResponse = await fetch(verifyUrl, { method: "POST" });
          const captchaData = await captchaResponse.json();

          if (!captchaData.success) {
            throw new Error("CAPTCHA verification failed.");
          }
        }
        const isValidPassword = await bcrypt.compare(
          credentials.password,
          user.password
        );

        if (!isValidPassword) {
          throw new Error("Invalid email or password.");
        }

        return {
          id: user.id,
          email: user.email!,
          name: user.name ?? null,
          image: user.image ?? null,
          pinCode: user.pinCode ?? null,
          timezoneOffset: user.timezoneOffset ?? null,
        };
      },
    }),
  ],
  session: {
    strategy: "jwt" as const,
  },
  secret: process.env.NEXTAUTH_SECRET,
  pages: {
    signIn: "/",
    error: "/",
  },
  callbacks: {
    async jwt({ token, user }: { token: JWT; user?: User | AdapterUser }) {
      if (user) {
        // Fresh login - store all data + timestamp
        token.id = user.id;
        token.email = user.email!;
        token.name = user.name ?? null;
        token.picture = user.image ?? null;
        token.lastRefresh = Date.now(); // Set fresh timestamp
        // ✨ Safe access to custom properties - check if they exist on user object
        token.pinCode = ("pinCode" in user ? user.pinCode : null) ?? null;
        token.timezoneOffset =
          ("timezoneOffset" in user ? user.timezoneOffset : null) ?? null;
      } else if (token.id) {
        const now = Date.now();
        const lastRefresh = token.lastRefresh || 0;

        // Only query DB if data is stale
        if (now - lastRefresh > JWT_REFRESH_INTERVAL) {
          const dbUser = await prisma.user.findUnique({
            where: { id: token.id as string },
            select: {
              id: true,
              email: true,
              name: true,
              image: true,
              pinCode: true,
              timezoneOffset: true,
            },
          });

          if (!dbUser) {
            // User deleted - invalidate token
            console.log(
              `User ${token.id} no longer exists, invalidating token`
            );
            return null;
          }

          // Update token with fresh data
          token.id = dbUser.id;
          token.email = dbUser.email!;
          token.name = dbUser.name ?? null;
          token.picture = dbUser.image ?? null;
          token.pinCode = dbUser.pinCode ?? null;
          token.timezoneOffset = dbUser.timezoneOffset ?? null;
          token.lastRefresh = now; // Update refresh timestamp
        }
        // If data is fresh, keep existing token data
      }

      if (!token.picture && token.email) {
        token.picture = `https://api.dicebear.com/9.x/fun-emoji/svg?seed=${encodeURIComponent(
          token.email
        )}`;
      }

      return token;
    },

    async session({ session, token }: { session: Session; token: JWT }) {
      session.user = {
        id: token.id as string,
        email: token.email as string,
        name: token.name ?? null,
        image: token.picture ?? null,
        // ✨ Custom properties from JWT token:
        pinCode: token.pinCode ?? null,
        timezoneOffset: token.timezoneOffset ?? null,
      };

      return session;
    },
  },
};
