import React, { useEffect, useState } from 'react';
import {
    Button,
    GridTable,
    GlyphButton,
    Section,
} from '@theorchard/suite-components';
import { useIdentity } from '@theorchard/suite-frontend';
import { Link, useParams } from 'react-router-dom';
import { isEmpty } from 'lodash-es';
import { AbacusContractPartyTargetType } from 'src/apollo/definitions/globalTypes';
import { useContractPartyList } from 'src/apollo/queries/contract-party';
import { NO_NR_CONTRIBUTORS_TEXT } from 'src/apollo/type-constants/contract';
import ContractAdvancePaidListTableColumns from 'src/components/contract-detail/nr-contract-contributors-table-columns';
import { ABACUS_PROFILE } from 'src/constants';
import { editContractContributors } from 'src/urls/frontend-royalties';
import type { GetContractPartyListQuery } from 'src/apollo/queries/contract-party/__generated__/get-contract-party-list';
import type { AbacusNrContractContributor } from 'src/types/abacus-nr-contract-contributor';
import RestrictedByAbacusProfileWrapper from 'src/components/restricted-by-abacus-profile-wrapper';

type ContractPartyListItem =
    GetContractPartyListQuery['abacusContractParties']['items'][0];
type ContractPartyObject = Extract<
    NonNullable<
        GetContractPartyListQuery['abacusContractParties']['items'][0]['contractPartyObject']
    >,
    { __typename?: 'NrContributor' }
>;
type AbacusSchedule = ContractPartyObject['abacusSchedules'][0];

export interface NrContractContributorsListProps {
    nrContractContributorsTotal: number;
    setNrContractContributorsTotal: (params: number) => void;
}

export const NrContractContributorsList: React.FC<
    NrContractContributorsListProps
> = ({ nrContractContributorsTotal, setNrContractContributorsTotal }) => {
    const { contractId } = useParams<{ contractId: string }>();
    const defaultItemsPerPage = 10;
    const [pageSize, setPageSize] = useState<number>(defaultItemsPerPage);
    const [page, setPage] = useState<number>(0);

    const [contractPartyRequestParams, setContractPartRequestParams] = useState(
        {
            contractId,
            limit: pageSize,
            offset: page * pageSize,
            targetType: AbacusContractPartyTargetType.CONTRIBUTOR,
        }
    );

    const { profileType } = useIdentity();
    const isAbacusProfile = profileType === ABACUS_PROFILE;

    const { data: contractPartyList, loading: isContractPartyListLoading } =
        useContractPartyList(contractPartyRequestParams);

    useEffect(() => {
        setNrContractContributorsTotal(
            contractPartyList?.abacusContractParties?.totalCount || 0
        );
    }, [contractPartyList?.abacusContractParties?.totalCount]);

    useEffect(() => {
        setContractPartRequestParams({
            ...contractPartyRequestParams,
            limit: pageSize,
            offset: page * pageSize,
        });
    }, [page, pageSize]);

    const formatNrContractContributorsList = (
        nrContributorsList: Array<ContractPartyListItem> | []
    ) => {
        let updatedItem: Array<AbacusNrContractContributor> = [];
        let contributorsList: Array<AbacusNrContractContributor> = [];
        nrContributorsList?.forEach((contributor: ContractPartyListItem) => {
            const item = {
                contributorId: contributor.targetId,
                contractPartyId: contributor.contractPartyId,
                contributorName: contributor.contractPartyObject?.name,
            };
            if (
                contributor?.contractPartyObject &&
                'abacusSchedules' in contributor.contractPartyObject
            ) {
                const { abacusSchedules } = contributor.contractPartyObject;
                updatedItem = abacusSchedules.map(
                    (abacusSchedule: AbacusSchedule) => ({
                        ...item,
                        autoAdd: abacusSchedule.conditions?.autoAdd,
                        scheduleId: abacusSchedule.scheduleId,
                        scheduleName: abacusSchedule.scheduleName,
                        scheduleAttachmentsCount:
                            abacusSchedule.scheduleAttachments.totalCount,
                        isAbacusProfile,
                    })
                ) || [
                    {
                        ...item,
                        autoAdd: null,
                        scheduleId: '',
                        scheduleName: null,
                        scheduleAttachmentsCount: null,
                        isAbacusProfile,
                    },
                ];
            }
            contributorsList = [...contributorsList, ...updatedItem];
        });

        return contributorsList;
    };

    return (
        <Section>
            <Section.Header>
                <div className="d-flex flex-column" style={{ width: '100%' }}>
                    <div
                        className="d-flex flex-row align-items-center"
                        style={{ gap: '8px' }}
                    >
                        <Section.Title className="h3">
                            Contributors
                        </Section.Title>
                        <RestrictedByAbacusProfileWrapper>
                            <Link
                                to={editContractContributors(contractId)}
                                data-testid="ContractDetail-nr-contributors-button"
                                className="ml-auto"
                            >
                                {!isContractPartyListLoading &&
                                isEmpty(
                                    contractPartyList?.abacusContractParties
                                        ?.items
                                ) ? (
                                    <Button
                                        className="ContractDetail-nr-contributors-addButton"
                                        data-testid="nr-contributors-addButton"
                                        variant="primary"
                                    >
                                        <span>&nbsp;+ Add&nbsp;</span>
                                    </Button>
                                ) : (
                                    <GlyphButton
                                        className="ContractDetail-nr-contributors-editButton"
                                        data-testid="nr-contributors-editButton"
                                        variant="primary"
                                        name="edit"
                                    />
                                )}
                            </Link>
                        </RestrictedByAbacusProfileWrapper>
                    </div>
                </div>
            </Section.Header>
            {!isContractPartyListLoading &&
            isEmpty(contractPartyList?.abacusContractParties?.items) ? (
                <Section.Body>
                    <Section>
                        <div
                            className="mb-2 text-muted"
                            data-testid="noContributors"
                        >
                            {NO_NR_CONTRIBUTORS_TEXT}
                        </div>
                    </Section>
                </Section.Body>
            ) : (
                <Section.Body>
                    <Section>
                        <GridTable
                            bordered
                            className="ContractNrContributorsList-table"
                            columnDefs={ContractAdvancePaidListTableColumns()}
                            columnSpan={{
                                columns: ['contributorId'],
                                spanKey: (data: AbacusNrContractContributor) =>
                                    data.contributorId,
                                alignment: 'center',
                            }}
                            data={formatNrContractContributorsList(
                                contractPartyList?.abacusContractParties
                                    ?.items || []
                            )}
                            defaultColumnDefs={{
                                headerTextWrap: 'nowrap',
                            }}
                            loading={isContractPartyListLoading}
                            loadingRows={defaultItemsPerPage}
                            maxHeight={500}
                            page={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? page
                                    : undefined
                            }
                            pageSize={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? pageSize
                                    : undefined
                            }
                            paginated={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? true
                                    : undefined
                            }
                            onPageChange={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? setPage
                                    : undefined
                            }
                            onPageSizeChange={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? setPageSize
                                    : undefined
                            }
                            rowKey={(data: AbacusNrContractContributor) =>
                                data.scheduleId
                            }
                            showUpdateIndicator={
                                nrContractContributorsTotal >
                                defaultItemsPerPage
                                    ? true
                                    : undefined
                            }
                            totalCount={nrContractContributorsTotal}
                            variant="zebra"
                        />
                    </Section>
                </Section.Body>
            )}
        </Section>
    );
};
