import React, { useState } from 'react';
import {
    Button,
    Field,
    GlyphButton,
    Label,
    Popover,
    Radio,
    Section,
    useToast,
} from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import { cloneDeep } from 'lodash';
import PublisherSearchDropdown from 'src/pages/songWriterEditModal/components/publisherSearchDropdown';
import { CLASSNAME } from 'src/pages/songWriterEditModal/songWriterEditModal';
import {
    generateEditPublishingCompanyDescription,
    getAssociatedCompositionsToUpdate,
    getCompositionsFromSelectedRows,
    updateCompositionAgreementsInputWithSelectedPublisher,
    updatePublisherDataForAssociatedCompositions,
} from 'src/pages/songWriterEditModal/utils';
import type { Publisher } from 'src/data/queries';
import type {
    CompositionAgreementPublisherInput,
    UpdateSongWriterAgreementsInput,
} from 'src/data/schemaTypes';
import type { AssociatedComposition } from 'src/pages/songWriterEditModal/utils';

interface Props {
    labelUuid: string;
    associatedCompositions: AssociatedComposition[];
    setAssociatedCompositions: React.Dispatch<
        React.SetStateAction<AssociatedComposition[]>
    >;
    selectedCompositionIds: string[];
    editedAssociatedComposition?: AssociatedComposition;
    songWriterUuid: string;
    setUpdateSongWriterAgreementsInput: React.Dispatch<
        React.SetStateAction<UpdateSongWriterAgreementsInput | undefined>
    >;
}

const EditPublishingCompanies = ({
    labelUuid,
    songWriterUuid,
    associatedCompositions,
    setAssociatedCompositions,
    selectedCompositionIds,
    editedAssociatedComposition,
    setUpdateSongWriterAgreementsInput,
}: Props) => {
    const toast = useToast();
    const [showContent, setShowContent] = useState(false);

    const [selectedPublisher, setSelectedPublisher] = useState<
        Publisher | undefined
    >(undefined);

    const [updatePublisher, setUpdatePublisher] = useState<boolean>(false);

    const [isDisabled, setIsDisabled] = useState<boolean>(true);

    const selectedCompositions = getCompositionsFromSelectedRows(
        selectedCompositionIds,
        associatedCompositions
    );
    const isAllCompsWithPublisher = editedAssociatedComposition
        ? !!editedAssociatedComposition.publisherId
        : selectedCompositions.every(ac => ac.publisherId);
    const isAllCompsWithoutPublisher = editedAssociatedComposition
        ? !editedAssociatedComposition.publisherId
        : selectedCompositions.every(ac => !ac.publisherId);

    const resetData = () => {
        setUpdatePublisher(false);
        setSelectedPublisher(undefined);
        setIsDisabled(true);
    };

    const handleAssociatedCompositions = (
        associatedCompositionsToUpdate: CompositionAgreementPublisherInput[]
    ) => {
        setAssociatedCompositions(prev => {
            const associatedCompositions = cloneDeep(prev);
            return updatePublisherDataForAssociatedCompositions(
                associatedCompositionsToUpdate,
                associatedCompositions,
                selectedPublisher
            );
        });
    };

    const handleUpdateSongWriterAgreementsInput = (
        agreementsToUpdate: CompositionAgreementPublisherInput[]
    ) => {
        setUpdateSongWriterAgreementsInput(prev => {
            const agreements = cloneDeep(prev?.agreements) || [];

            return {
                label: { uuid: labelUuid },
                agreements:
                    updateCompositionAgreementsInputWithSelectedPublisher(
                        agreementsToUpdate,
                        agreements,
                        selectedPublisher
                    ),
                songWriterUuid,
            };
        });
    };

    const updatePublishingCompanies = () => {
        const associatedCompositionsToUpdate =
            getAssociatedCompositionsToUpdate(
                editedAssociatedComposition,
                selectedPublisher,
                selectedCompositionIds,
                associatedCompositions
            );

        handleAssociatedCompositions(associatedCompositionsToUpdate);
        handleUpdateSongWriterAgreementsInput(associatedCompositionsToUpdate);

        toast(
            formatMessage(
                selectedPublisher
                    ? 'songWriterManager.publishingCompaniesUpdated'
                    : 'songWriterManager.publishingCompaniesUnassigned',
                {
                    num: associatedCompositionsToUpdate.length,
                }
            )
        );

        setShowContent(false);
    };

    const description = generateEditPublishingCompanyDescription(
        isAllCompsWithPublisher,
        isAllCompsWithoutPublisher,
        getCompositionsFromSelectedRows(
            selectedCompositionIds,
            associatedCompositions
        ),
        editedAssociatedComposition
    );

    return (
        <Popover
            className={CLASSNAME + '-editPublishingCompany-popover'}
            placement="top"
            id="edit-publishing-company-popover"
            show={showContent}
            content={
                <>
                    <Section>
                        <Section.Header
                            title={formatMessage(
                                'songWriterManager.editPublishingCompaniesForSelectedCompositions'
                            )}
                        />
                        <Section.Body
                            className={
                                CLASSNAME + '-editPublishingCompany-body'
                            }
                        >
                            <div
                                className={
                                    CLASSNAME +
                                    '-editPublishingCompany-body-description'
                                }
                            >
                                {description}
                            </div>
                            <form>
                                <Field
                                    controlId="editPublishingCompany"
                                    labelText={formatMessage(
                                        'songWriterManager.action'
                                    )}
                                >
                                    <Radio
                                        name="editPublishingCompany"
                                        label={formatMessage(
                                            'songWriterManager.unassignPublishingCompanies'
                                        )}
                                        disabled={isAllCompsWithoutPublisher}
                                        onChange={() => {
                                            setUpdatePublisher(false);
                                            setSelectedPublisher(undefined);
                                            setIsDisabled(false);
                                        }}
                                    />
                                    <Radio
                                        name="editPublishingCompany"
                                        label={formatMessage(
                                            'songWriterManager.updatePublishingCompanies'
                                        )}
                                        id="updatePublishingCompanies"
                                        onChange={() => {
                                            setUpdatePublisher(true);
                                            setIsDisabled(true);
                                        }}
                                    />
                                </Field>
                                {updatePublisher && (
                                    <Field
                                        controlId="updatePublishingCompany"
                                        labelText={formatMessage(
                                            'songWriterManager.updatePublishingCompaniesTo'
                                        )}
                                    >
                                        <PublisherSearchDropdown
                                            labelUuid={labelUuid}
                                            onChange={value => {
                                                if (!value) {
                                                    setSelectedPublisher(
                                                        undefined
                                                    );
                                                    setIsDisabled(true);
                                                    return;
                                                }

                                                setSelectedPublisher({
                                                    id: value?.id || '',
                                                    name: value?.name || '',
                                                });
                                                setIsDisabled(false);
                                            }}
                                            publisherId={selectedPublisher?.id}
                                            removeNoPublishingCompany={true}
                                        />
                                        <Label
                                            className={
                                                CLASSNAME +
                                                '-editPublishingCompany-body-description-update-label'
                                            }
                                            text={formatMessage(
                                                'songWriterManager.updatePublishingCompaniesMessage'
                                            )}
                                        />
                                    </Field>
                                )}
                                <Button
                                    variant="primary"
                                    disabled={isDisabled}
                                    className="btn-save"
                                    onClick={updatePublishingCompanies}
                                >
                                    {formatMessage('generic.save')}
                                </Button>
                                <Button
                                    variant="tertiary"
                                    className="btn-cancel"
                                    onClick={() => {
                                        resetData();
                                        setShowContent(false);
                                    }}
                                >
                                    {formatMessage('generic.cancel')}
                                </Button>
                            </form>
                        </Section.Body>
                    </Section>
                </>
            }
        >
            <GlyphButton
                name="edit"
                className="TableActionButton new-action-btn"
                onClick={() => {
                    resetData();
                    setShowContent(!showContent);
                }}
            />
        </Popover>
    );
};

export default EditPublishingCompanies;
