import { createDropboxSyncClient } from '../core/client'
import type { DropboxCredentials, DropboxSyncClient } from '../core/types'
import { cookies } from 'next/headers'
import { NextRequest, NextResponse } from 'next/server'

/**
 * Next.js-specific helper to create a Dropbox sync client
 * Can be used in both client and server components
 */
export function useNextDropboxSync(
    credentials: DropboxCredentials
): DropboxSyncClient {
    return createDropboxSyncClient(credentials)
}

/**
 * Server-side helper to get credentials from Next.js cookies
 */
export async function getCredentialsFromCookies(): Promise<DropboxCredentials> {
    const cookieStore = await cookies()

    return {
        clientId: process.env.DROPBOX_APP_KEY || '',
        clientSecret: process.env.DROPBOX_APP_SECRET,
        accessToken: cookieStore.get('dropbox_access_token')?.value,
        refreshToken: cookieStore.get('dropbox_refresh_token')?.value,
    }
}

/**
 * Server action to handle Dropbox OAuth callback
 */
export async function handleOAuthCallback(
    request: NextRequest
): Promise<NextResponse> {
    const url = new URL(request.url)
    const code = url.searchParams.get('code')

    if (!code) {
        return NextResponse.redirect(new URL('/auth/error', request.url))
    }

    const redirectUri =
        process.env.DROPBOX_REDIRECT_URI ||
        `${
            process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
        }/api/dropbox/auth/callback`

    const dropboxSync = createDropboxSyncClient({
        clientId: process.env.DROPBOX_APP_KEY || '',
        clientSecret: process.env.DROPBOX_APP_SECRET,
    })

    try {
        const tokens = await dropboxSync.auth.exchangeCodeForToken(
            code,
            redirectUri
        )

        // Create response with redirect
        const response = NextResponse.redirect(new URL('/', request.url))

        // Set cookies with the tokens
        response.cookies.set({
            name: 'dropbox_access_token',
            value: tokens.accessToken,
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production',
            maxAge: tokens.expiresAt
                ? (tokens.expiresAt - Date.now()) / 1000
                : 14 * 24 * 60 * 60, // 14 days default
            sameSite: 'lax',
            path: '/',
        })

        if (tokens.refreshToken) {
            response.cookies.set({
                name: 'dropbox_refresh_token',
                value: tokens.refreshToken,
                httpOnly: true,
                secure: process.env.NODE_ENV === 'production',
                maxAge: 365 * 24 * 60 * 60, // 1 year
                sameSite: 'lax',
                path: '/',
            })
        }

        // Set a non-httpOnly cookie to indicate connection status to the client
        response.cookies.set({
            name: 'dropbox_connected',
            value: 'true',
            secure: process.env.NODE_ENV === 'production',
            maxAge: tokens.expiresAt
                ? (tokens.expiresAt - Date.now()) / 1000
                : 14 * 24 * 60 * 60,
            sameSite: 'lax',
            path: '/',
        })

        return response
    } catch (error) {
        console.error('Error completing Dropbox OAuth flow:', error)
        return NextResponse.redirect(new URL('/auth/error', request.url))
    }
}

/**
 * Create API route handlers for a Next.js app
 */
export function createNextDropboxApiHandlers() {
    return {
        /**
         * Handler for status check route
         */
        async status() {
            const cookieStore = await cookies()
            const isConnected = !!cookieStore.get('dropbox_access_token')?.value

            return NextResponse.json({ connected: isConnected })
        },

        /**
         * Handler for OAuth start route
         */
        async oauthStart() {
            const dropboxSync = createDropboxSyncClient({
                clientId: process.env.DROPBOX_APP_KEY || '',
            })

            const redirectUri =
                process.env.DROPBOX_REDIRECT_URI ||
                `${
                    process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
                }/api/dropbox/auth/callback`

            const authUrl = await dropboxSync.auth.getAuthUrl(redirectUri)

            return NextResponse.redirect(authUrl)
        },

        /**
         * Handler for logout route
         */
        async logout() {
            const response = NextResponse.json({ success: true })

            // Clear all Dropbox-related cookies
            response.cookies.delete('dropbox_access_token')
            response.cookies.delete('dropbox_refresh_token')
            response.cookies.delete('dropbox_connected')

            return response
        },
    }
}
