import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
import { JWT } from "next-auth/jwt";

const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000/api/v1";

// Django REST API - Token Refresh
async function refreshAccessToken(token: JWT) {
  try {
    const response = await fetch(
      `${API_BASE_URL}/auth/jwt/refresh/`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          refresh: token.refreshToken,
        }),
      }
    );

    const data = await response.json();

    if (!response.ok) {
      throw data;
    }

    return {
      ...token,
      accessToken: data.access,
      refreshToken: data.refresh ?? token.refreshToken,
      // Django JWT access token: 60 dakika (3600000 ms)
      accessTokenExpiry: Date.now() + 3600000,
    };
  } catch (error) {
    console.error("Error refreshing access token:", error);
    return {
      ...token,
      error: "RefreshAccessTokenError",
    };
  }
}

// Django REST API - Social Auth Handler
async function handleSocialAuth(provider: string, accessToken: string) {
  const response = await fetch(
    `${API_BASE_URL}/auth/social/${provider}/`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        access_token: accessToken,
      }),
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error || "Social authentication failed");
  }

  return await response.json();
}

export const authOptions: NextAuthOptions = {
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID || "",
      clientSecret: process.env.GITHUB_SECRET || "",
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_ID || "",
      clientSecret: process.env.GOOGLE_SECRET || "",
    }),
    CredentialsProvider({
      name: "Django REST API",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) {
          return null;
        }

        try {
          // Django REST API - Login
          const response = await fetch(
            `${API_BASE_URL}/auth/jwt/create/`,
            {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                email: credentials.email,
                password: credentials.password,
              }),
            }
          );

          if (!response.ok) {
            return null;
          }

          const data = await response.json();

          if (data?.access && data?.refresh) {
            // Get user profile
            const userResponse = await fetch(
              `${API_BASE_URL}/auth/users/me/`,
              {
                headers: {
                  Authorization: `Bearer ${data.access}`,
                },
              }
            );

            const userData = await userResponse.json();

            return {
              id: userData.id?.toString() || credentials.email,
              email: userData.email,
              name: `${userData.first_name || ""} ${userData.last_name || ""}`.trim(),
              accessToken: data.access,
              refreshToken: data.refresh,
              accessTokenExpiry: Date.now() + 3600000, // 60 dakika
            };
          }

          return null;
        } catch (error) {
          console.error("Authentication error:", error);
          return null;
        }
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user, account }) {
      // İlk login - Email/Password (Credentials Provider)
      if (user && account?.provider === "credentials") {
        token.accessToken = user.accessToken;
        token.refreshToken = user.refreshToken;
        token.accessTokenExpiry = user.accessTokenExpiry;
        return token;
      }

      // İlk login - Social Auth (Google/GitHub)
      if (account && (account.provider === "google" || account.provider === "github")) {
        try {
          const providerMap: Record<string, string> = {
            google: "google-oauth2",
            github: "github",
          };

          const djangoProvider = providerMap[account.provider];
          const socialData = await handleSocialAuth(
            djangoProvider,
            account.access_token!
          );

          token.accessToken = socialData.access;
          token.refreshToken = socialData.refresh;
          token.accessTokenExpiry = Date.now() + 3600000;
          token.email = socialData.user.email;
          token.name = `${socialData.user.first_name || ""} ${socialData.user.last_name || ""}`.trim();
          
          return token;
        } catch (error) {
          console.error("Social auth error:", error);
          token.error = "SocialAuthError";
          return token;
        }
      }

      // Token hala geçerliyse mevcut tokeni döndür
      if (token.accessTokenExpiry && Date.now() < (token.accessTokenExpiry as number)) {
        return token;
      }

      // Token süresi dolmuşsa refresh et
      return refreshAccessToken(token);
    },
    async session({ session, token }) {
      session.accessToken = token.accessToken as string;
      session.refreshToken = token.refreshToken as string;
      session.error = token.error as string | undefined;
      
      if (token.email) {
        session.user = {
          ...session.user,
          email: token.email as string,
          name: token.name as string,
        };
      }
      
      return session;
    },
  },
  pages: {
    signIn: "/auth/login",
    error: "/auth/error",
  },
  session: {
    strategy: "jwt",
    maxAge: 7 * 24 * 60 * 60, // 7 gün (refresh token süresi)
  },
  secret: process.env.NEXTAUTH_SECRET,
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
