﻿import type { FC } from 'react';
import React, { useCallback, useMemo, useState, useEffect } from 'react';
import {
    Alert,
    Button,
    Sidecar,
    Select,
    Label,
    Field,
    Form,
    Tooltip,
} from '@theorchard/suite-components';
import './artistNameUpdateSidecar.scss';
import { formatMessage } from '@theorchard/suite-frontend';
import ArtistSearchDropdown from 'src/components/artistSearchDropdown/artistSearchDropdown';
import VendorAndSubaccountSearchDropdown from 'src/components/vendorAndSubaccountSearchDropdown/vendorAndSubaccountSearchDropdown';
import {
    MENU_FULL_WIDTH,
    REQUEST_TYPE_MERGE,
    REQUEST_TYPE_RENAME,
} from 'src/constants';
import {
    useRenameArtistMutation,
    useMergeArtistMutation,
} from 'src/data/mutations';
import { useProductAndTrackCountLazyQuery } from 'src/data/queries';
import { useArtistMergeFF } from 'src/utils/features';
import type { VendorAndSubaccount, Artist } from 'src/data/types';
import type { ArtistNameUpdateSidecarProps, SelectOptionType } from 'src/types';

export const CLASSNAME = 'ArtistNameUpdateSidecar';

const ArtistNameUpdateSidecar: FC<ArtistNameUpdateSidecarProps> = ({
    isOpen,
    closeModal,
}) => {
    const [requestType, setRequestType] = useState<string | undefined>();
    const [accountId, setAccountId] = useState<string | undefined>();
    const [subaccountId, setSubaccountId] = useState<undefined | number>(0);
    const [selectedAccount, setSelectedAccount] = useState<
        VendorAndSubaccount | undefined
    >();
    const [infoBannerText, setInfoBannerText] = useState<string>('');
    const [artistIdForRename, setArtistIdForRename] = useState<
        string | undefined
    >();
    const [selectedArtistForRename, setSelectedArtistForRename] = useState<
        Artist | undefined
    >();
    const [updatedArtistName, setUpdatedArtistName] = useState<string>('');
    const [loadingOnSave, setLoadingOnSave] = useState(false);
    const [firstArtistForMerge, setFirstArtistForMerge] = useState<
        Artist | undefined
    >();
    const [secondArtistForMerge, setSecondArtistForMerge] = useState<
        Artist | undefined
    >();
    const [mergeArtistOptions, setMergeArtistOptions] = useState<
        SelectOptionType[] | undefined
    >();
    const [sourceArtistId, setSourceArtistId] = useState<string | undefined>();
    const [destinationArtistId, setDestinationArtistId] = useState<
        string | undefined
    >();
    const [confirmDisabled, setconfirmDisabled] = useState(true);

    const [disableOnSave, setDisableOnSave] = useState(false);

    const canSeeArtistMergeOption = useArtistMergeFF();

    const updateNameToControlId = 'ArtistChangeNameInput';

    const requestTypeSelectOptions = useMemo(() => {
        const baseOptions: SelectOptionType[] = [
            {
                label: $t('tools.artistNameUpdateSidecar.rename'),
                value: REQUEST_TYPE_RENAME,
            },
        ];

        if (canSeeArtistMergeOption) {
            baseOptions.push({
                label: $t('tools.artistNameUpdateSidecar.merge'),
                value: REQUEST_TYPE_MERGE,
            });
        }

        return baseOptions;
    }, [canSeeArtistMergeOption]);

    const { renameLabelParticipant } = useRenameArtistMutation({
        uuid: '0',
        name: '',
    });

    const { mergeLabelParticipantAndArtist } = useMergeArtistMutation({
        uuid1: '0',
        uuid2: '0',
        mergedArtistUuid: '0',
    });

    const [executeProductAndTrackCount, { data: countData }] =
        useProductAndTrackCountLazyQuery({ uuid: '' });

    useEffect(() => {
        if (countData) {
            setInfoBannerText(
                $t('tools.artistNameUpdateSidecar.productAndTracksCount', {
                    products: countData.release,
                    tracks: countData.track,
                })
            );
        }
    }, [countData, infoBannerText, setInfoBannerText]);

    useEffect(() => {
        if (firstArtistForMerge && secondArtistForMerge) {
            const mergeArtistDropdownOptions: SelectOptionType[] = [
                {
                    label: `${firstArtistForMerge.name} • ${firstArtistForMerge.artistInfo?.[0]?.id}`,
                    value: firstArtistForMerge.id,
                    artistInfo: firstArtistForMerge.artistInfo,
                },
                {
                    label: `${secondArtistForMerge.name} • ${secondArtistForMerge.artistInfo?.[0]?.id}`,
                    value: secondArtistForMerge.id,
                    artistInfo: secondArtistForMerge.artistInfo,
                },
            ];
            setMergeArtistOptions(mergeArtistDropdownOptions);
        } else {
            setMergeArtistOptions(undefined);
            setSourceArtistId(undefined);
            setDestinationArtistId(undefined);
        }
    }, [firstArtistForMerge, secondArtistForMerge, setMergeArtistOptions]);

    const handleRequestTypeChange = (
        selectedOption: SelectOptionType | undefined
    ) => {
        setRequestType(selectedOption?.value);
        setAccountId(undefined);
        setSubaccountId(0);
        setSelectedAccount(undefined);
        setArtistIdForRename(undefined);
        setSelectedArtistForRename(undefined);
        setFirstArtistForMerge(undefined);
        setSecondArtistForMerge(undefined);
        setSourceArtistId(undefined);
        setDestinationArtistId(undefined);
        setInfoBannerText('');
    };

    const footer = () => (
        <div className={`${CLASSNAME}-buttons`}>
            <Button
                className={`${CLASSNAME}-sidecar-btn-cancel`}
                onClick={handleCloseModal}
                size="lg"
                variant="quaternary"
                disabled={disableOnSave}
            >
                {$t('tools.artistNameUpdateSidecar.cancel')}
            </Button>

            <Tooltip
                className={`${CLASSNAME}-save-in-progress`}
                id={`${CLASSNAME}-save-in-progress`}
                message={$t('tools.artistNameUpdateSidecar.waitMessage')}
                show={loadingOnSave}
                placement="left"
            >
                <Button
                    className={`${CLASSNAME}-sidecar-save`}
                    variant="primary"
                    loading={loadingOnSave}
                    onClick={handleOnSave}
                    size="lg"
                    disabled={confirmDisabled}
                >
                    {loadingOnSave
                        ? $t('tools.artistNameUpdateSidecar.saving')
                        : $t('tools.artistNameUpdateSidecar.save')}
                </Button>
            </Tooltip>
        </div>
    );

    const handleAccountChange = useCallback(
        (account?: VendorAndSubaccount) => {
            if (account?.subaccountId) {
                setSubaccountId(account.subaccountId);
            } else {
                setSubaccountId(0);
            }
            if (account?.vendorId) {
                setAccountId(account.vendorId.toString());
            }
            setSelectedAccount(account);
            setArtistIdForRename(undefined);
            setSelectedArtistForRename(undefined);
            setFirstArtistForMerge(undefined);
            setSecondArtistForMerge(undefined);
            setSourceArtistId(undefined);
            setDestinationArtistId(undefined);
            setUpdatedArtistName('');
            setInfoBannerText('');
        },
        [
            setAccountId,
            setSubaccountId,
            setSelectedAccount,
            setArtistIdForRename,
            setSelectedArtistForRename,
            setUpdatedArtistName,
            setFirstArtistForMerge,
            setSecondArtistForMerge,
            setSourceArtistId,
            setDestinationArtistId,
            setInfoBannerText,
        ]
    );

    const getReleasesAndTracksForLabelParticipant = useCallback(
        async (uuid?: string) => {
            if (uuid) {
                await executeProductAndTrackCount({
                    variables: { uuid },
                });
            }
        },
        [executeProductAndTrackCount]
    );

    const handleArtistChange = useCallback(
        async (artist?: Artist) => {
            setArtistIdForRename(artist?.id.toString());
            setSelectedArtistForRename(artist);
            await getReleasesAndTracksForLabelParticipant(
                artist?.id.toString()
            );
            setInfoBannerText('');
        },
        [
            setArtistIdForRename,
            setSelectedArtistForRename,
            getReleasesAndTracksForLabelParticipant,
            setInfoBannerText,
        ]
    );

    const handleFirstArtistForMergeChange = useCallback(
        (artist?: Artist) => {
            setFirstArtistForMerge(artist);
        },
        [setFirstArtistForMerge]
    );

    const handleSecondArtistForMergeChange = useCallback(
        (artist?: Artist) => {
            setSecondArtistForMerge(artist);
        },
        [setSecondArtistForMerge]
    );

    const handleUpdatedArtistNameChange = (event: {
        currentTarget: { value: string };
    }) => {
        if (event.currentTarget.value == '') {
            setconfirmDisabled(true);
        } else {
            setconfirmDisabled(false);
        }
        setUpdatedArtistName(event.currentTarget.value);
    };

    const handleOnSave = async () => {
        setLoadingOnSave(true);
        setDisableOnSave(true);
        if (
            requestType == REQUEST_TYPE_RENAME &&
            artistIdForRename &&
            updatedArtistName
        ) {
            await renameLabelParticipant({
                variables: {
                    uuid: artistIdForRename,
                    name: updatedArtistName,
                },
            });
            handleCloseModal();
        } else if (
            requestType == REQUEST_TYPE_MERGE &&
            firstArtistForMerge?.id &&
            secondArtistForMerge?.id &&
            sourceArtistId
        ) {
            await mergeLabelParticipantAndArtist({
                variables: {
                    uuid1: firstArtistForMerge?.id,
                    uuid2: secondArtistForMerge?.id,
                    mergedArtistUuid: sourceArtistId,
                },
            });
            handleCloseModal();
        }
    };

    const handleMergeArtistChange = (
        selectedOption: SelectOptionType | undefined
    ) => {
        setconfirmDisabled(false);
        setSourceArtistId(
            mergeArtistOptions?.filter(
                option => option.value !== selectedOption?.value
            )[0].value
        );
        setDestinationArtistId(selectedOption?.value);
    };

    const handleCloseModal = () => {
        setRequestType(undefined);
        setAccountId(undefined);
        setSelectedAccount(undefined);
        setArtistIdForRename(undefined);
        setSelectedArtistForRename(undefined);
        setSourceArtistId(undefined);
        setDestinationArtistId(undefined);
        setUpdatedArtistName('');
        setInfoBannerText('');
        setLoadingOnSave(false);
        setDisableOnSave(false);
        closeModal();
    };

    return (
        <Sidecar.Custom
            className={CLASSNAME}
            data-testid={CLASSNAME}
            isOpen={isOpen}
            onRequestClose={handleCloseModal}
            header={$t('tools.artistNameUpdateSidecar.artistNameUpdateHeader')}
            customFooter={footer()}
        >
            <div className={`${CLASSNAME}-artistname-update-instruction`}>
                {$t(
                    'tools.artistNameUpdateSidecar.artistNameUpdateInstruction'
                )}
            </div>
            <div className={`${CLASSNAME}-request-type-dropdown`}>
                <Label text={$t('tools.artistNameUpdateSidecar.requestType')} />
                <Select
                    name="requestType"
                    menuWidth={MENU_FULL_WIDTH}
                    options={requestTypeSelectOptions}
                    className={`${CLASSNAME}-request-type`}
                    hideFilter
                    placeholder={$t(
                        'tools.artistNameUpdateSidecar.dropdownPlaceHolder'
                    )}
                    onChange={handleRequestTypeChange}
                    testId="request-type-id"
                    disabled={disableOnSave}
                />
            </div>
            {!!requestType && (
                <>
                    <hr className={`${CLASSNAME}-horizontal-line`} />
                    <div className={`${CLASSNAME}-account-search-dropdown`}>
                        <Label
                            testId="account-label"
                            text={$t('tools.artistNameUpdateSidecar.account')}
                        />
                        <VendorAndSubaccountSearchDropdown
                            disabled={!requestType || disableOnSave}
                            menuWidth={MENU_FULL_WIDTH}
                            onChange={handleAccountChange}
                            placeholder={$t(
                                'tools.artistNameUpdateSidecar.accountDropdownPlaceHolder'
                            )}
                            testId="account-search-dropdown"
                            selectedAccount={selectedAccount}
                        />
                        <span
                            className={`${CLASSNAME}-account-search-dropdown-helptext`}
                        >
                            {formatMessage(
                                'tools.artistNameUpdateSidecar.accountDropdownHelptext'
                            )}
                        </span>
                    </div>
                </>
            )}

            {requestType == REQUEST_TYPE_RENAME && (
                <>
                    <div className={`${CLASSNAME}-artist-search-dropdown`}>
                        <Label
                            testId="artist-label"
                            text={$t('tools.artistNameUpdateSidecar.artist')}
                        />
                        <ArtistSearchDropdown
                            id={artistIdForRename}
                            menuWidth={MENU_FULL_WIDTH}
                            disabled={!accountId || disableOnSave}
                            accountId={accountId}
                            subaccountId={subaccountId}
                            onChange={handleArtistChange}
                            selectedArtist={selectedArtistForRename}
                            placeholder={$t(
                                'tools.artistNameUpdateSidecar.artistDropdownPlaceHolder'
                            )}
                            testId="artist-search-dropdown"
                        />
                        <span
                            className={`${CLASSNAME}-artist-search-dropdown-helptext`}
                        >
                            {formatMessage(
                                'tools.artistNameUpdateSidecar.artistDropdownHelptext'
                            )}
                        </span>
                        {artistIdForRename && infoBannerText && (
                            <Alert
                                className={`${CLASSNAME}-products-tracks-banner`}
                                testId={`${CLASSNAME}-banner`}
                                text={infoBannerText}
                                variant="warn"
                            />
                        )}
                    </div>
                    <div className={`${CLASSNAME}-artist-change-name`}>
                        <Field
                            controlId={updateNameToControlId}
                            labelText={$t(
                                'tools.artistNameUpdateSidecar.changeNameTo'
                            )}
                            testId="artist-change-name"
                        >
                            <Form.Control
                                disabled={!artistIdForRename || disableOnSave}
                                type="text"
                                value={updatedArtistName}
                                onChange={handleUpdatedArtistNameChange}
                                placeholder={$t(
                                    'tools.artistNameUpdateSidecar.changeNameToPlaceholder'
                                )}
                            />
                            <span
                                className={`${CLASSNAME}-change-name-to-helptext`}
                            >
                                {formatMessage(
                                    'tools.artistNameUpdateSidecar.changeNameToHelptext'
                                )}
                            </span>
                        </Field>
                    </div>
                </>
            )}

            {requestType == REQUEST_TYPE_MERGE && (
                <>
                    <div className={`${CLASSNAME}-artist-search-dropdown`}>
                        <Label
                            testId="artist-label"
                            text={$t(
                                'tools.artistNameUpdateSidecar.artistName1'
                            )}
                        />
                        <ArtistSearchDropdown
                            id={firstArtistForMerge?.id}
                            menuWidth={MENU_FULL_WIDTH}
                            disabled={!accountId || disableOnSave}
                            accountId={accountId}
                            subaccountId={subaccountId}
                            selectedArtist={firstArtistForMerge}
                            selectedSiblingArtistId={secondArtistForMerge?.id}
                            onChange={handleFirstArtistForMergeChange}
                            placeholder={$t(
                                'tools.artistNameUpdateSidecar.artistDropdownPlaceHolder'
                            )}
                            testId="merge-artist-search-dropdown-1"
                        />
                        <span
                            className={`${CLASSNAME}-artist-search-dropdown-helptext`}
                        >
                            {formatMessage(
                                'tools.artistNameUpdateSidecar.artistDropdownHelptext'
                            )}
                        </span>
                    </div>
                    <div className={`${CLASSNAME}-artist-search-dropdown`}>
                        <Label
                            testId="artist-label"
                            text={$t(
                                'tools.artistNameUpdateSidecar.artistName2'
                            )}
                        />
                        <ArtistSearchDropdown
                            id={secondArtistForMerge?.id}
                            menuWidth={MENU_FULL_WIDTH}
                            disabled={!accountId || disableOnSave}
                            accountId={accountId}
                            subaccountId={subaccountId}
                            selectedArtist={secondArtistForMerge}
                            selectedSiblingArtistId={firstArtistForMerge?.id}
                            onChange={handleSecondArtistForMergeChange}
                            placeholder={$t(
                                'tools.artistNameUpdateSidecar.artistDropdownPlaceHolder'
                            )}
                            testId="merge-artist-search-dropdown-2"
                        />
                        <span
                            className={`${CLASSNAME}-artist-search-dropdown-helptext`}
                        >
                            {formatMessage(
                                'tools.artistNameUpdateSidecar.artistDropdownHelptext'
                            )}
                        </span>
                    </div>
                    <div className={`${CLASSNAME}-merge-artist-dropdown`}>
                        <Label
                            text={$t(
                                'tools.artistNameUpdateSidecar.mergedArtistName'
                            )}
                        />
                        <Select
                            name="mergeArtist"
                            menuWidth={MENU_FULL_WIDTH}
                            options={mergeArtistOptions}
                            className={`${CLASSNAME}-merge-artist`}
                            hideFilter
                            placeholder={$t(
                                'tools.artistNameUpdateSidecar.mergedArtistNamePlaceholder'
                            )}
                            onChange={handleMergeArtistChange}
                            disabled={
                                !(
                                    accountId &&
                                    firstArtistForMerge &&
                                    secondArtistForMerge
                                ) || disableOnSave
                            }
                            selectedValue={destinationArtistId}
                            testId="merge-artist-dropdown"
                        />
                        <span
                            className={`${CLASSNAME}-merge-artist-dropdown-helptext`}
                        >
                            {formatMessage(
                                'tools.artistNameUpdateSidecar.mergedArtistNameHelptext'
                            )}
                        </span>
                    </div>
                </>
            )}
        </Sidecar.Custom>
    );
};

export default ArtistNameUpdateSidecar;
