import React, { useCallback, useState } from 'react';
import {
    Alert,
    Button,
    Label,
    Sidecar,
    Tooltip,
    useToast,
} from '@theorchard/suite-components';
import { formatJsxMessage } from '@theorchard/suite-frontend';
import { useTemplateArtistLookup } from 'src/data/queries/templateArtistLookup';
import { useTemplateAlbumLookup } from 'src/data/queries/templateAlbumLookup';
import SpotifySelect from '../spotifySelect';
import type { SpotifyResourceType } from '../spotifySelect/getSpotifyUrlType';
import { usePopulateTemplateMutation } from 'src/data/mutations/populateTemplate';
import useGetTemplateStatus from 'src/data/queries/getTemplateStatus';
import type { TemplateLookupResult } from 'src/types';
import './index.scss';
import { isEmpty } from 'lodash';

const TYPE_LABEL_KEY = {
    artist: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelArtist',
    album: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelAlbum',
    playlist: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelPlaylist',
    track: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelTrack',
    show: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelShow',
    episode: 'bulkDigitalAudio.spotifyPopulatorSidecar.typeLabelEpisode',
} as const satisfies Record<SpotifyResourceType, string>;

const SpotifyPopulatorSidecar = ({
    isOpen,
    onClose,
}: {
    isOpen: boolean;
    onClose: () => void;
}) => {
    const templateArtistLookup = useTemplateArtistLookup();
    const templateAlbumLookup = useTemplateAlbumLookup();
    const [artists, setArtists] = useState<TemplateLookupResult[]>([]);
    const [albums, setAlbums] = useState<TemplateLookupResult[]>([]);
    const [populating, setPopulating] = useState(false);
    const [error, setError] = useState(false);
    const toast = useToast();

    const { setTaskToken } = useGetTemplateStatus({
        onSuccess: downloadUrl => {
            setPopulating(false);
            const link = document.createElement('a');
            link.href = downloadUrl;
            link.download = '';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            toast($t('bulkDigitalAudio.spotifyPopulatorSidecar.successToast'), {
                variant: 'success',
            });
            setAlbums([]);
            setArtists([]);
            onClose();
        },
        onFailure: () => {
            setPopulating(false);
            setError(true);
        },
    });

    const populateTemplate = usePopulateTemplateMutation(token =>
        setTaskToken(token)
    );

    const handleConfirmClick = async () => {
        setPopulating(true);
        setError(false);
        await populateTemplate({ artists, albums });
    };

    const invalidArtistMessage = useCallback(
        (pastedType: SpotifyResourceType) =>
            $t('bulkDigitalAudio.spotifyPopulatorSidecar.invalidLinkError', {
                pastedType: $t(TYPE_LABEL_KEY[pastedType]),
                expectedType: $t(TYPE_LABEL_KEY.artist),
            }),
        []
    );

    const invalidAlbumMessage = useCallback(
        (pastedType: SpotifyResourceType) =>
            $t('bulkDigitalAudio.spotifyPopulatorSidecar.invalidLinkError', {
                pastedType: $t(TYPE_LABEL_KEY[pastedType]),
                expectedType: $t(TYPE_LABEL_KEY.album),
            }),
        []
    );

    const invalidArtistLinkMessage = useCallback(
        () =>
            $t(
                'bulkDigitalAudio.spotifyPopulatorSidecar.invalidSpotifyLinkErrorArtist'
            ),
        []
    );

    const invalidAlbumLinkMessage = useCallback(
        () =>
            $t(
                'bulkDigitalAudio.spotifyPopulatorSidecar.invalidSpotifyLinkErrorAlbum'
            ),
        []
    );

    const downloadButton = (
        <Button
            variant="primary"
            size="lg"
            loading={populating}
            disabled={isEmpty(artists) && isEmpty(albums)}
            onClick={handleConfirmClick}
            data-testid="spotify-populator-sidecar--confirm-button"
        >
            {$t('bulkDigitalAudio.spotifyPopulatorSidecar.downloadButton')}
        </Button>
    );

    const footer = (
        <footer className="ModalFooter ReactModal-footer">
            <Button onClick={onClose} size="lg" variant="quartenary">
                {$t('bulkDigitalAudio.spotifyPopulatorSidecar.cancelButton')}
            </Button>
            {populating ? (
                <Tooltip
                    id="spotify-populator-loading-tooltip"
                    message={$t(
                        'bulkDigitalAudio.spotifyPopulatorSidecar.loadingTooltip'
                    )}
                    maxWidth={234}
                >
                    {downloadButton}
                </Tooltip>
            ) : (
                downloadButton
            )}
        </footer>
    );

    return (
        <Sidecar.Custom
            isOpen={isOpen}
            onRequestClose={onClose}
            className="spotify-populator-sidecar"
            title={$t('bulkDigitalAudio.spotifyPopulatorSidecar.title')}
            customFooter={footer}
        >
            {error && (
                <Alert
                    className="spotify-populator-sidecar--error"
                    variant="error"
                    text={
                        <>
                            <div>
                                <b>
                                    {$t(
                                        'bulkDigitalAudio.spotifyPopulatorSidecar.errorTitle'
                                    )}
                                </b>
                            </div>
                            <div>
                                {$t(
                                    'bulkDigitalAudio.spotifyPopulatorSidecar.errorBody'
                                )}
                            </div>
                        </>
                    }
                />
            )}
            <p>{$t('bulkDigitalAudio.spotifyPopulatorSidecar.bodyOne')}</p>
            <p>
                {formatJsxMessage(
                    'bulkDigitalAudio.spotifyPopulatorSidecar.bodyTwo',
                    {
                        b: ({ children }) => <b>{children}</b>,
                    }
                )}
            </p>
            <div className="spotify-populator-sidecar--lookup">
                <Label
                    text={$t(
                        'bulkDigitalAudio.spotifyPopulatorSidecar.artistLookupLabel'
                    )}
                />
                <SpotifySelect
                    lookup={templateArtistLookup}
                    onChange={setArtists}
                    expectedType="artist"
                    invalidTypeMessage={invalidArtistMessage}
                    invalidLinkMessage={invalidArtistLinkMessage}
                />
            </div>
            <div className="spotify-populator-sidecar--lookup">
                <Label
                    text={$t(
                        'bulkDigitalAudio.spotifyPopulatorSidecar.albumLookupLabel'
                    )}
                />
                <SpotifySelect
                    lookup={templateAlbumLookup}
                    onChange={setAlbums}
                    expectedType="album"
                    invalidTypeMessage={invalidAlbumMessage}
                    invalidLinkMessage={invalidAlbumLinkMessage}
                />
            </div>
        </Sidecar.Custom>
    );
};

export default SpotifyPopulatorSidecar;
