import React, { useEffect, useState } from 'react';
import {
    Alert,
    LoadingIndicator,
    ToastProvider,
    useToast,
} from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { useParams } from 'react-router-dom';
import { AbacusContractPartyTargetType } from 'src/apollo/definitions/globalTypes';
import { useSoftDeleteContractParty } from 'src/apollo/mutations/contract-party';
import { useContractById } from 'src/apollo/queries/contract';
import { useContractPartyList } from 'src/apollo/queries/contract-party';
import {
    noContributors,
    CONTRIBUTORS_HEADERS,
    NO_CONTRIBUTORS_FOUND,
} from 'src/apollo/type-constants/contract';
import ContributorsList from 'src/components/contract-contributors-form/contributors-list';
import ContributorsSearch from 'src/components/contract-contributors-form/contributors-search';
import { LinkButton } from 'src/components/shared/link-button';
import { CONTRACT_TYPES } from 'src/constants';
import { getContractDetail } from 'src/urls/frontend-royalties';
import type { GetContractPartyListQuery } from 'src/apollo/queries/contract-party/__generated__/get-contract-party-list';
import './styles.scss';

type AbacusContractPartyItem =
    GetContractPartyListQuery['abacusContractParties']['items'][0];

export const ContractContributorsForm: React.FC = () => {
    const { contractId } = useParams<{ contractId: string }>();
    const [addingContributorId, setAddingContributorId] = useState<string>('');
    const [contractContributors, setContractContributors] = useState<
        AbacusContractPartyItem[]
    >([]);
    const [deletedContractParty, setDeletedContractParty] = useState<any>({});
    const [isClearFilter, setIsClearFilter] = useState<boolean>(false);
    const filterValues = {
        contractId,
        limit: 100,
        offset: 0,
        targetType: AbacusContractPartyTargetType.CONTRIBUTOR,
    };

    const addToast = useToast();
    const {
        data: contract,
        error: contractError,
        loading,
    } = useContractById(contractId);

    const {
        data: contractPartyList,
        error: contractPartyError,
        loading: contractPartyListLoading,
    } = useContractPartyList(filterValues);

    const deleteContractParty = useSoftDeleteContractParty(
        contractId,
        deletedContractParty?.contractPartyId,
        AbacusContractPartyTargetType.CONTRIBUTOR
    );
    const contractType =
        contract?.abacusContract?.contractType ||
        CONTRACT_TYPES.NEIGHBOURING_RIGHTS;

    useEffect(() => {
        if (contractPartyList) {
            const { items }: any = contractPartyList.abacusContractParties;
            setContractContributors(items);
        }
    }, [contractPartyList]);

    useEffect(() => {
        if (!isEmpty(deletedContractParty)) {
            setIsClearFilter(true);
            handleDeleteContractContributor(
                deletedContractParty?.contractPartyId,
                deletedContractParty?.contributorName
            );
        }
    }, [deletedContractParty]);

    const handleDeleteContractContributor = (
        contractPartyId: string,
        contributorName: string
    ) => {
        deleteContractParty({ variables: { contractPartyId } })
            .then(() => {
                setDeletedContractParty({});
                addToast(
                    `Contributor "${contributorName}" removed from this contract.`
                );
            })
            .catch(() => {
                setDeletedContractParty({});
                addToast(
                    `Error while removing contributor "${contributorName}".`,
                    { variant: 'danger' }
                );
            });
    };
    if (loading) return <LoadingIndicator />;

    if (contractType !== CONTRACT_TYPES.NEIGHBOURING_RIGHTS && !loading)
        return (
            <div className="ContractContributors-invalid-contract">
                {/* eslint-disable-next-line react/no-unescaped-entities */}
                <i>{noContributors(contractType)}</i>
            </div>
        );

    const noContributorsText = (
        <div
            className="ContractContributors-no-contributors"
            data-testid="noContributors"
        >
            <i>{NO_CONTRIBUTORS_FOUND}</i>
        </div>
    );
    return (
        <div className="ContractContributors">
            <div className="ContractContributors-top-nav">
                <h2 className="PageTitle">Contributors</h2>
            </div>
            {(contractError || contractPartyError) && (
                <Alert
                    variant="error"
                    text={contractError?.message || contractPartyError?.message}
                />
            )}
            <ContributorsList
                className="ContractContributors-list"
                addingContributorId={addingContributorId}
                contractPartyListLoading={contractPartyListLoading}
                contractContributors={contractContributors}
                noContributorsFoundText={noContributorsText}
                contributorsListHeader={CONTRIBUTORS_HEADERS}
                deletedContractParty={deletedContractParty}
                setDeletedContractParty={setDeletedContractParty}
            />
            <hr />
            <ToastProvider toastTime={3000}>
                <ContributorsSearch
                    addedContractContributors={contractContributors}
                    addingContributorId={addingContributorId}
                    isClearFilter={isClearFilter}
                    setIsClearFilter={setIsClearFilter}
                    setAddingContributorId={setAddingContributorId}
                />
            </ToastProvider>
            <div className="ContractContributors-back-button">
                <LinkButton
                    buttonSize="md"
                    label="Back to Contract"
                    target={getContractDetail(contractId)}
                    variant="default"
                />
            </div>
        </div>
    );
};

export default ContractContributorsForm;
