import { Dropbox } from 'dropbox'
import type {
    DropboxCredentials,
    DropboxSyncClient,
    AuthMethods,
    SyncMethods,
    TokenResponse,
    SocketMethods,
} from './types'
import { createAuthMethods } from './auth'
import { createSyncMethods } from './sync'
import { createSocketMethods } from './socket'

/**
 * Creates a Dropbox sync client with auth, sync, and socket methods
 */
export function createDropboxSyncClient(
    credentials: DropboxCredentials
): DropboxSyncClient {
    let dropboxClient: Dropbox | null = null

    function getClient(): Dropbox {
        if (!dropboxClient) {
            if (credentials.accessToken) {
                dropboxClient = new Dropbox({
                    accessToken: credentials.accessToken,
                })
            } else if (credentials.clientId) {
                dropboxClient = new Dropbox({ clientId: credentials.clientId })
            } else {
                throw new Error(
                    'Either clientId or accessToken must be provided'
                )
            }
        }
        return dropboxClient
    }

    function setAccessToken(token: string): void {
        dropboxClient = new Dropbox({ accessToken: token })
    }

    const auth = createAuthMethods(getClient, credentials, setAccessToken)
    const socket = createSocketMethods()
    const sync = createSyncMethods(getClient, credentials, socket)

    return {
        auth,
        sync,
        socket,
    }
}
