import React, { useEffect, useState } from 'react';
import GoogleDriveIcon from 'src/assets/svg/google-drive-icon.svg';
import {
    ASSET_FILETYPES,
    ASSET_UPLOADING_STATUS,
    GOOGLE_API_JS_URL,
    GOOGLE_DRIVE_SCOPE,
    GOOGLE_IDENTITY_SERVICES_JS_URL,
} from 'src/constants';
import { useGetGoogleAccessTokenMutation } from 'src/data/mutations/getGoogleAccessToken';
import { useStartBulkGoogleAssetTransferJobMutation } from 'src/data/mutations/startBulkGoogleAssetTransferJob';

interface SelectFileFromGoogleDriveProps {
    bulkSessionId: string;
    saveUnidentifiedAssets: (unidentifiedAssets: string[]) => void;
    setAssetUploadingStatus: (
        assetUploadingStatus: ASSET_UPLOADING_STATUS
    ) => void;
}

const SelectFileFromGoogleDrive = (props: SelectFileFromGoogleDriveProps) => {
    const { bulkSessionId, saveUnidentifiedAssets, setAssetUploadingStatus } =
        props;

    const [accessToken, setAccessToken] = useState<string | null>(null);
    const [userId, setUserId] = useState<string | null>(null);
    const [showPicker, setShowPicker] = useState(false);

    const handleGetGoogleAccessTokenMutation = (
        input: { accessToken: string; userId: string } | null
    ) => {
        if (input) {
            const { accessToken, userId } = input;
            setAccessToken(accessToken);
            setUserId(userId);
            setShowPicker(true);
        }
    };

    const getGoogleAccessToken = useGetGoogleAccessTokenMutation(
        handleGetGoogleAccessTokenMutation
    );

    const handleStartBulkGoogleAssetTransferJob = (
        unidentifiedAssets: string[] | null
    ) => {
        if (unidentifiedAssets) {
            saveUnidentifiedAssets(unidentifiedAssets);
            setAssetUploadingStatus(ASSET_UPLOADING_STATUS.TRANSFERRING);
        }
    };

    const startBulkGoogleAssetTransferJob =
        useStartBulkGoogleAssetTransferJobMutation(
            handleStartBulkGoogleAssetTransferJob
        );

    const loadScript = async (src: string) => {
        return await new Promise<void>((resolve, reject) => {
            const script = document.createElement('script');
            script.src = src;
            script.async = true;
            script.onload = () => resolve();
            script.onerror = reject;
            document.body.appendChild(script);
        });
    };

    const loadGoogleScripts = async () => {
        await Promise.all([
            loadScript(GOOGLE_IDENTITY_SERVICES_JS_URL),
            loadScript(GOOGLE_API_JS_URL),
        ]);

        await new Promise(res => gapi.load('picker', res));
    };

    const authorize = async () =>
        await new Promise(() => {
            const codeClient = google.accounts.oauth2.initCodeClient({
                client_id: __GOOGLE_CLIENT_ID__,
                scope: GOOGLE_DRIVE_SCOPE,
                ux_mode: 'popup',
                callback: async (resp: any) => {
                    await getGoogleAccessToken(bulkSessionId, resp.code);
                },
            });

            codeClient.requestCode();
        });

    useEffect(() => {
        if (accessToken && showPicker) {
            new google.picker.PickerBuilder()
                .addView(
                    new google.picker.DocsView(google.picker.ViewId.DOCS)
                        .setIncludeFolders(true)
                        .setMimeTypes(ASSET_FILETYPES.join(','))
                        .setSelectFolderEnabled(true)
                )
                .setOAuthToken(accessToken)
                .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
                .setDeveloperKey(__GOOGLE_DEVELOPER_KEY__)
                .setAppId(__GOOGLE_APP_ID__)
                .setCallback(async (resp: any) => {
                    const files = resp.docs;
                    if (userId && files && files.length) {
                        const fileData = files.map((file: any) => ({
                            id: file.id,
                            name: file.name,
                            type: file.type == 'folder' ? 'folder' : 'file',
                        }));
                        await startBulkGoogleAssetTransferJob(
                            bulkSessionId,
                            userId,
                            fileData
                        );
                    }
                    setShowPicker(false);
                })
                .build()
                .setVisible(true);
        }
    }, [
        accessToken,
        userId,
        showPicker,
        startBulkGoogleAssetTransferJob,
        bulkSessionId,
    ]);

    return (
        <button
            className="select-file-from-third-party"
            onClick={async event => {
                event.stopPropagation();
                await loadGoogleScripts();
                await authorize();
            }}
        >
            <div className="select-file-from-third-party-icon">
                <img src={String(GoogleDriveIcon)} alt="google drive" />
            </div>
            <label className="select-file-from-third-party-label">
                GOOGLE DRIVE
            </label>
        </button>
    );
};

export default SelectFileFromGoogleDrive;
