import React, { type FC, useEffect, useState } from 'react';
import {
    Alert,
    GlyphButton,
    GridTable,
    SearchInput,
    Section,
    useToast,
} from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import { Illustration } from '@theorchard/suite-icons';
import { type UpdatePublishingSongWriterMetaDataInput } from 'src/data/schemaTypes';
import EditPublishingCompanies from 'src/pages/songWriterEditModal/components/associatedCompositions/editPublishingCompanies';
import { useIsEmployeeWithFullAccess } from 'src/utils/helpers';
import {
    type AssociatedComposition,
    formatAssociatedComps,
    mapAssociatedCompositions,
    moveAssociatedComposition,
    moveAssociatedCompositions,
} from '../../utils';
import PublisherSearchDropdown from '../publisherSearchDropdown';
import type { UpdateSongWriterAgreementsInputWithPublisherName } from '../../utils';
import type { Publisher } from 'src/data/queries';
import type { UpdateSongWriterAgreementsInput } from 'src/data/schemaTypes';
import type { WriterAgreement } from 'src/types';

interface Props {
    initialControlledAgreements: WriterAgreement[];
    initialNonControlledAgreements: WriterAgreement[];
    controlledComps: AssociatedComposition[];
    setControlledComps: React.Dispatch<
        React.SetStateAction<AssociatedComposition[]>
    >;
    nonControlledComps: AssociatedComposition[];
    setNonControlledComps: React.Dispatch<
        React.SetStateAction<AssociatedComposition[]>
    >;
    labelUuid: string;
    updatedWriter: UpdatePublishingSongWriterMetaDataInput;
    setUpdateSongWriterAgreementsInput: React.Dispatch<
        React.SetStateAction<UpdateSongWriterAgreementsInput | undefined>
    >;
    updateSongWriterAgreementsInput:
        | UpdateSongWriterAgreementsInputWithPublisherName
        | undefined;
}

export const SECTION_CLASSNAME = 'SongWriterEditModal-associatedComps';

const AssociatedCompositions: FC<Props> = ({
    initialControlledAgreements,
    initialNonControlledAgreements,
    labelUuid,
    updatedWriter,
    setUpdateSongWriterAgreementsInput,
    updateSongWriterAgreementsInput,
    controlledComps,
    setControlledComps,
    nonControlledComps,
    setNonControlledComps,
}) => {
    const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
    const [selectedControlledRows, setSelectedControlledRows] = useState<
        string[]
    >([]);
    const [selectedNonControlledRows, setSelectedNonControlledRows] = useState<
        string[]
    >([]);
    const [selectedPublisher, setSelectedPublisher] = useState<
        Publisher | undefined
    >(undefined);
    const [searchTitle, setSearchTitle] = React.useState('');

    const isEmployeeWithFullAccess = useIsEmployeeWithFullAccess();

    const controlledWriterMissingProIpi =
        controlledComps.length &&
        (updatedWriter.pro === '' || updatedWriter.ipi === '');
    const nonControlledWriterMissingProIpi =
        !controlledComps.length &&
        (updatedWriter.pro === '' || updatedWriter.ipi === '');

    const handleSort = (
        compositions: AssociatedComposition[],
        setCompositions: React.Dispatch<
            React.SetStateAction<AssociatedComposition[]>
        >,
        direction?: 'asc' | 'desc'
    ) => {
        const newSortDirection =
            direction ?? sortDirection === 'asc' ? 'desc' : 'asc';
        setSortDirection(newSortDirection);

        const sortedComps = [...compositions].sort((a, b) => {
            if (newSortDirection === 'asc') {
                return a.title.localeCompare(b.title);
            } else {
                return b.title.localeCompare(a.title);
            }
        });

        setCompositions(sortedComps);
    };

    const toast = useToast();

    useEffect(() => {
        const controlledComps = formatAssociatedComps(
            initialControlledAgreements
        );
        const nonControlledComps = formatAssociatedComps(
            initialNonControlledAgreements
        );

        const allComps = [...controlledComps, ...nonControlledComps];

        const mappedControlledAssociatedCompositions =
            mapAssociatedCompositions(
                allComps,
                'controlled',
                updateSongWriterAgreementsInput,
                selectedPublisher
            );
        const mappedNonControlledAssociatedCompositions =
            mapAssociatedCompositions(
                allComps,
                'nonControlled',
                updateSongWriterAgreementsInput,
                selectedPublisher
            );

        setControlledComps(mappedControlledAssociatedCompositions);
        setNonControlledComps(mappedNonControlledAssociatedCompositions);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [
        selectedPublisher,
        initialControlledAgreements,
        initialNonControlledAgreements,
    ]);

    const isEditDisabled =
        !controlledComps.length &&
        (updatedWriter.pro === '' || updatedWriter.ipi === '');

    const filterPredicate = ({ title }: AssociatedComposition) =>
        title.toLowerCase().includes(searchTitle.toLowerCase());
    const filteredControlledComps = controlledComps.filter(filterPredicate);
    const filteredNonControlledComps =
        nonControlledComps.filter(filterPredicate);

    return (
        <div className={SECTION_CLASSNAME}>
            <div className={`${SECTION_CLASSNAME}-header`}>
                <h2>{formatMessage('songWriters.associatedCompositions')}</h2>
                <div className={`${SECTION_CLASSNAME}-filters`}>
                    <SearchInput
                        onChange={setSearchTitle}
                        placeholder={formatMessage('generic.searchValue')}
                        width={300}
                        expanded
                    />
                    <PublisherSearchDropdown
                        labelUuid={labelUuid}
                        onChange={value => setSelectedPublisher(value)}
                        publisherId={selectedPublisher?.id}
                    />
                </div>

                {!!controlledWriterMissingProIpi ||
                    (nonControlledWriterMissingProIpi && (
                        <Alert
                            variant="information"
                            text={formatMessage(
                                'songWriterManager.cannotMoveComps'
                            )}
                        />
                    ))}
            </div>
            <Section className={`${SECTION_CLASSNAME}-section`}>
                <div
                    className={`${SECTION_CLASSNAME}-controlled ${!controlledComps.length ? 'isEmpty' : ''}`}
                >
                    <Section variant="edit">
                        <Section.Header
                            className={`${SECTION_CLASSNAME}-sectionHeader`}
                            title={formatMessage('generic.controlled')}
                        />
                        <Section.Body>
                            <GridTable
                                variant="zebra"
                                maxHeight={350}
                                rowKey={data =>
                                    `${data.id}/${data.agreementId}`
                                }
                                className={`${SECTION_CLASSNAME}-controlledComps`}
                                data={filteredControlledComps}
                                selectable
                                stickyHeader
                                testId="controlled-compositions"
                                emptyStateComponent={
                                    <div
                                        className={`${SECTION_CLASSNAME}-emptyState`}
                                    >
                                        {!!selectedPublisher &&
                                        !filteredControlledComps.length ? (
                                            <Illustration
                                                name="noResults"
                                                size={100}
                                            />
                                        ) : (
                                            <Illustration
                                                name="emptyState"
                                                size={100}
                                            />
                                        )}
                                        <h4>
                                            {!!selectedPublisher &&
                                            !filteredControlledComps.length
                                                ? formatMessage(
                                                      'songWriterManager.noItems'
                                                  )
                                                : formatMessage(
                                                      'songWriterManager.noCompositions',
                                                      {
                                                          controlledStatus:
                                                              'Controlled',
                                                      }
                                                  )}
                                        </h4>
                                        <div>
                                            {!!selectedPublisher &&
                                            !filteredControlledComps.length
                                                ? formatMessage(
                                                      'songWriterManager.resetFilters'
                                                  )
                                                : null}
                                        </div>
                                    </div>
                                }
                                sortBy={{
                                    key: 'title',
                                    direction: sortDirection,
                                }}
                                onSort={() =>
                                    handleSort(
                                        filteredControlledComps,
                                        setControlledComps
                                    )
                                }
                                columnDefs={[
                                    {
                                        name: 'title',
                                        title: `${formatMessage('songWriterManager.compositions')}`,
                                        sortable: true,
                                        sortKey: 'title',
                                        Cell: ({ data }) => (
                                            <div>
                                                <div>{data.title}</div>
                                                {data.publisherName && (
                                                    <div id="publisher">
                                                        {data.publisherName}
                                                    </div>
                                                )}
                                            </div>
                                        ),
                                    },
                                ]}
                                onSelectedRowsChanged={
                                    setSelectedControlledRows
                                }
                                selectedRowKeys={selectedControlledRows}
                                rowActionsHeader=""
                                rowActions={{
                                    edit: {
                                        renderIcon: row => (
                                            <EditPublishingCompanies
                                                songWriterUuid={
                                                    updatedWriter.id
                                                }
                                                labelUuid={labelUuid}
                                                associatedCompositions={
                                                    filteredControlledComps
                                                }
                                                setAssociatedCompositions={
                                                    setControlledComps
                                                }
                                                selectedCompositionIds={
                                                    selectedControlledRows
                                                }
                                                editedAssociatedComposition={
                                                    row
                                                }
                                                setUpdateSongWriterAgreementsInput={
                                                    setUpdateSongWriterAgreementsInput
                                                }
                                            />
                                        ),
                                        tooltip: formatMessage(
                                            'songWriterManager.editPublishingCo'
                                        ),
                                        disabled: () =>
                                            !isEmployeeWithFullAccess,
                                    },
                                    move: {
                                        icon: (
                                            <GlyphButton
                                                name="arrowRight"
                                                className="TableActionButton new-action-btn"
                                            />
                                        ),
                                        onClick: composition =>
                                            moveAssociatedComposition(
                                                composition,
                                                false,
                                                setControlledComps,
                                                setNonControlledComps,
                                                setUpdateSongWriterAgreementsInput,
                                                true,
                                                toast,
                                                labelUuid,
                                                updatedWriter.id
                                            ),
                                        tooltip: formatMessage(
                                            'songWriterManager.moveComp',
                                            {
                                                controlledStatus:
                                                    'Non-Controlled',
                                            }
                                        ),
                                        disabled: () => isEditDisabled,
                                    },
                                }}
                                rowBulkActions={{
                                    edit: {
                                        icon: (
                                            <EditPublishingCompanies
                                                songWriterUuid={
                                                    updatedWriter.id
                                                }
                                                labelUuid={labelUuid}
                                                associatedCompositions={
                                                    filteredControlledComps
                                                }
                                                setAssociatedCompositions={
                                                    setControlledComps
                                                }
                                                selectedCompositionIds={
                                                    selectedControlledRows
                                                }
                                                setUpdateSongWriterAgreementsInput={
                                                    setUpdateSongWriterAgreementsInput
                                                }
                                            />
                                        ),
                                        tooltip: formatMessage(
                                            'songWriterManager.editPublishingCo'
                                        ),
                                        //eslint-disable-next-line @typescript-eslint/no-empty-function
                                        onClick: () => {},
                                        disabled: !isEmployeeWithFullAccess,
                                    },
                                    move: {
                                        icon: (
                                            <GlyphButton
                                                name="arrowRight"
                                                className="TableActionButton new-action-btn"
                                            />
                                        ),
                                        onClick: () => {
                                            const newControlledStatus =
                                                'Non-Controlled';
                                            moveAssociatedCompositions(
                                                setControlledComps,
                                                setNonControlledComps,
                                                setUpdateSongWriterAgreementsInput,
                                                toast,
                                                setSelectedControlledRows,
                                                selectedControlledRows,
                                                filteredControlledComps,
                                                labelUuid,
                                                updatedWriter.id,
                                                newControlledStatus
                                            );
                                        },
                                        tooltip: formatMessage(
                                            'songWriterManager.moveSelectedComps',
                                            {
                                                controlledStatus:
                                                    'Non-Controlled',
                                            }
                                        ),
                                        disabled: isEditDisabled,
                                    },
                                }}
                            />
                        </Section.Body>
                    </Section>
                </div>
                <div
                    className={`${SECTION_CLASSNAME}-nonControlled ${!nonControlledComps.length ? 'isEmpty' : ''}`}
                >
                    <Section variant="edit">
                        <Section.Header
                            className={`${SECTION_CLASSNAME}-sectionHeader`}
                            title={formatMessage('generic.nonControlled')}
                        />
                        <Section.Body>
                            <GridTable
                                variant="zebra"
                                maxHeight={350}
                                rowKey={data =>
                                    `${data.id}/${data.agreementId}`
                                }
                                className={`${SECTION_CLASSNAME}-nonControlledComps`}
                                selectable
                                data={filteredNonControlledComps}
                                stickyHeader
                                testId="non-controlled-compositions"
                                emptyStateComponent={
                                    <div
                                        className={`${SECTION_CLASSNAME}-emptyState`}
                                    >
                                        {!!selectedPublisher &&
                                        !filteredNonControlledComps.length ? (
                                            <Illustration
                                                name="noResults"
                                                size={100}
                                            />
                                        ) : (
                                            <Illustration
                                                name="emptyState"
                                                size={100}
                                            />
                                        )}
                                        <h4>
                                            {!!selectedPublisher &&
                                            !filteredNonControlledComps.length
                                                ? formatMessage(
                                                      'songWriterManager.noItems'
                                                  )
                                                : formatMessage(
                                                      'songWriterManager.noCompositions',
                                                      {
                                                          controlledStatus:
                                                              'Non-Controlled',
                                                      }
                                                  )}
                                        </h4>
                                        <div>
                                            {!!selectedPublisher &&
                                            !filteredNonControlledComps.length
                                                ? formatMessage(
                                                      'songWriterManager.resetFilters'
                                                  )
                                                : null}
                                        </div>
                                    </div>
                                }
                                sortBy={{
                                    key: 'title',
                                    direction: sortDirection,
                                }}
                                onSort={() =>
                                    handleSort(
                                        filteredNonControlledComps,
                                        setNonControlledComps
                                    )
                                }
                                onSelectedRowsChanged={
                                    setSelectedNonControlledRows
                                }
                                selectedRowKeys={selectedNonControlledRows}
                                rowActionsHeader=""
                                rowActions={{
                                    edit: {
                                        renderIcon: row => (
                                            <EditPublishingCompanies
                                                songWriterUuid={
                                                    updatedWriter.id
                                                }
                                                labelUuid={labelUuid}
                                                associatedCompositions={
                                                    filteredNonControlledComps
                                                }
                                                setAssociatedCompositions={
                                                    setNonControlledComps
                                                }
                                                selectedCompositionIds={
                                                    selectedNonControlledRows
                                                }
                                                editedAssociatedComposition={
                                                    row
                                                }
                                                setUpdateSongWriterAgreementsInput={
                                                    setUpdateSongWriterAgreementsInput
                                                }
                                            />
                                        ),
                                        tooltip: formatMessage(
                                            'songWriterManager.editPublishingCo'
                                        ),
                                        disabled: () =>
                                            !isEmployeeWithFullAccess,
                                    },
                                    move: {
                                        icon: (
                                            <GlyphButton
                                                name="arrowLeft"
                                                className="TableActionButton new-action-btn"
                                            />
                                        ),
                                        onClick: composition =>
                                            moveAssociatedComposition(
                                                composition,
                                                true,
                                                setNonControlledComps,
                                                setControlledComps,
                                                setUpdateSongWriterAgreementsInput,
                                                true,
                                                toast,
                                                labelUuid,
                                                updatedWriter.id
                                            ),
                                        tooltip: formatMessage(
                                            'songWriterManager.moveComp',
                                            { controlledStatus: 'Controlled' }
                                        ),
                                        disabled: () => isEditDisabled,
                                    },
                                }}
                                rowBulkActions={{
                                    edit: {
                                        icon: (
                                            <EditPublishingCompanies
                                                songWriterUuid={
                                                    updatedWriter.id
                                                }
                                                labelUuid={labelUuid}
                                                associatedCompositions={
                                                    filteredNonControlledComps
                                                }
                                                setAssociatedCompositions={
                                                    setNonControlledComps
                                                }
                                                selectedCompositionIds={
                                                    selectedNonControlledRows
                                                }
                                                setUpdateSongWriterAgreementsInput={
                                                    setUpdateSongWriterAgreementsInput
                                                }
                                            />
                                        ),
                                        tooltip: formatMessage(
                                            'songWriterManager.editPublishingCo'
                                        ),
                                        //eslint-disable-next-line @typescript-eslint/no-empty-function
                                        onClick: () => {},
                                        disabled: !isEmployeeWithFullAccess,
                                    },
                                    move: {
                                        icon: (
                                            <GlyphButton
                                                name="arrowLeft"
                                                className="TableActionButton new-action-btn"
                                            />
                                        ),
                                        onClick: () => {
                                            const newControlledStatus =
                                                'Controlled';
                                            moveAssociatedCompositions(
                                                setNonControlledComps,
                                                setControlledComps,
                                                setUpdateSongWriterAgreementsInput,
                                                toast,
                                                setSelectedNonControlledRows,
                                                selectedNonControlledRows,
                                                filteredNonControlledComps,
                                                labelUuid,
                                                updatedWriter.id,
                                                newControlledStatus
                                            );
                                        },
                                        tooltip: formatMessage(
                                            'songWriterManager.moveSelectedComps',
                                            { controlledStatus: 'Controlled' }
                                        ),
                                        disabled: isEditDisabled,
                                    },
                                }}
                                columnDefs={[
                                    {
                                        name: 'title',
                                        title: `${formatMessage('songWriterManager.compositions')}`,
                                        sortable: true,
                                        sortKey: 'title',
                                        Cell: ({ data }) => (
                                            <div>
                                                <div>{data.title}</div>
                                                {data.publisherName && (
                                                    <div id="publisher">
                                                        {data.publisherName}
                                                    </div>
                                                )}
                                            </div>
                                        ),
                                    },
                                ]}
                            />
                        </Section.Body>
                    </Section>
                </div>
            </Section>
        </div>
    );
};

export default AssociatedCompositions;
