import { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { encryptSecret } from "./crypto/secrets";
import { prisma } from "./db";
import { fetchYouTubeChannel } from "./youtube/upload";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
          scope: [
            "openid",
            "email",
            "profile",
            // Single YouTube Data API scope (covers upload, channel, and playlist APIs)
            "https://www.googleapis.com/auth/youtube.force-ssl",
          ].join(" "),
        },
      },
    }),
  ],
  callbacks: {
    async signIn({ user, account }) {
      if (!account?.access_token || !user.email) return false;

      const dbUser = await prisma.user.upsert({
        where: { email: user.email },
        create: {
          email: user.email,
          name: user.name,
          image: user.image,
        },
        update: {
          name: user.name,
          image: user.image,
        },
      });

      if (account.refresh_token) {
        const channel = await fetchYouTubeChannel(
          account.access_token,
          account.refresh_token,
        );

        const accessToken = encryptSecret(account.access_token);
        const refreshToken = encryptSecret(account.refresh_token);

        await prisma.youTubeConnection.upsert({
          where: { userId: dbUser.id },
          create: {
            userId: dbUser.id,
            accessToken,
            refreshToken,
            expiresAt: account.expires_at
              ? new Date(account.expires_at * 1000)
              : new Date(Date.now() + 3600 * 1000),
            channelId: channel.channelId,
            channelTitle: channel.channelTitle,
          },
          update: {
            accessToken,
            refreshToken,
            expiresAt: account.expires_at
              ? new Date(account.expires_at * 1000)
              : new Date(Date.now() + 3600 * 1000),
            channelId: channel.channelId,
            channelTitle: channel.channelTitle,
          },
        });
      }

      return true;
    },
    async session({ session }) {
      if (session.user?.email) {
        const dbUser = await prisma.user.findUnique({
          where: { email: session.user.email },
          include: { youtubeConnection: true },
        });
        if (dbUser) {
          session.user.id = dbUser.id;
          session.user.youtubeConnected = !!dbUser.youtubeConnection;
          session.user.channelTitle = dbUser.youtubeConnection?.channelTitle;
        }
      }
      return session;
    },
  },
  pages: {
    signIn: "/",
  },
  session: {
    strategy: "jwt",
  },
  secret: process.env.NEXTAUTH_SECRET,
};
