// file: ~/server/api/auth/[...].ts
import { NuxtAuthHandler } from '#auth'
import CredentialsProvider from 'next-auth/providers/credentials';
import GithubProvider from 'next-auth/providers/github'
import GoogleProvider from 'next-auth/providers/google';
import type { JWT } from 'next-auth/jwt';

const config = useRuntimeConfig();
const API_BASE_URL = config.public.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:8080';

// Helper to refresh the access token
async function refreshAccessToken(token: JWT): Promise<JWT> {
    try {
        if (!token.refreshToken) {
            throw new Error("No refresh token available");
        }

        const response = await fetch(`${API_BASE_URL}/api/v1/auth/refresh`, {
            headers: { 'Content-Type': 'application/json' },
            method: 'POST',
            body: JSON.stringify({ refresh_token: token.refreshToken }),
        });

        const refreshedProperies = await response.json();

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

        return {
            ...token,
            accessToken: refreshedProperies.access_token,
            refreshToken: refreshedProperies.refresh_token ?? token.refreshToken, // Fallback to old refresh token
            accessTokenExpires: Date.now() + 15 * 60 * 1000, // Varsayılan 15 dk, backend yanıtına göre ayarlanabilir
        };
    } catch (error) {
        console.error('RefreshAccessTokenError', error);
        return {
            ...token,
            error: 'RefreshAccessTokenError',
        };
    }
}

export default NuxtAuthHandler({
    secret: config.authSecret,
    providers: [
        // @ts-expect-error
        GithubProvider.default({
            clientId: config.githubClientId,
            clientSecret: config.githubClientSecret
        }),
        // @ts-expect-error
        GoogleProvider.default({
            clientId: config.googleClientId,
            clientSecret: config.googleClientSecret
        }),
        // @ts-expect-error
        CredentialsProvider.default({
            name: 'Credentials',
            credentials: {
                email: { label: 'Email', type: 'email' },
                password: { label: 'Password', type: 'password' }
            },
            async authorize(credentials) {
                if (!credentials?.email || !credentials?.password) return null;

                try {
                    const res = await fetch(`${API_BASE_URL}/api/v1/auth/login`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            email: credentials.email,
                            password: credentials.password
                        })
                    });

                    const user = await res.json();

                    // Backend dönüş formatı: { access_token, refresh_token, user: { ... } }
                    if (res.ok && user.access_token && user.user) {
                        return {
                            ...user.user, // id, email, username, is_admin vb.
                            access_token: user.access_token,
                            refresh_token: user.refresh_token,
                        };
                    }
                    return null;
                } catch (error) {
                    console.error('Login error:', error);
                    return null;
                }
            }
        })
    ],
    callbacks: {
        async jwt({ token, user, account }) {
            // Initial sign in
            if (account && user) {
                // Social login case handled here if needed, consistent with Credentials
                // Eğer social login backend değişimi yapılacaksa burası da güncellenmeli.
                // Şimdilik Credentials akışına odaklanıyoruz.

                return {
                    ...token,
                    accessToken: user.access_token,
                    refreshToken: user.refresh_token,
                    accessTokenExpires: Date.now() + 15 * 60 * 1000, // 15 dakika
                    id: user.id as number,
                    email: user.email as string,
                    username: user.username as string,
                    first_name: user.first_name as string,
                    last_name: user.last_name as string,
                    is_admin: user.is_admin as boolean,
                    // Diğer alanlar
                };
            }

            // Return previous token if the access token has not expired yet
            if (Date.now() < (token.accessTokenExpires as number)) {
                return token;
            }

            // Access token has expired, try to update it
            return refreshAccessToken(token);
        },
        async session({ session, token }) {
            if (token) {
                session.user.id = token.id;
                session.user.email = token.email;
                session.user.username = token.username;
                session.user.first_name = token.first_name;
                session.user.last_name = token.last_name;
                session.user.is_admin = token.is_admin;

                session.accessToken = token.accessToken;
                session.refreshToken = token.refreshToken;
                session.error = token.error;
            }
            return session;
        }
    },
    pages: {
        signIn: '/auth/login',
        newUser: '/auth/register' // Opsiyonel
    },
    session: {
        strategy: 'jwt'
    },
    // Debug only in development
    debug: process.env.NODE_ENV === 'development',
})

