import React from 'react';
import {
    Card,
    Section,
    Status,
    StatusProps,
    Tag,
    TruncatedText,
} from '@theorchard/suite-components';
import { useFeatureFlag } from '@theorchard/suite-frontend';
import { CONTRACT_TYPE_MAP, USER_FEATURES } from 'src/constants';
import { getContractDetail } from 'src/urls/frontend-royalties';
import type { AbacusContractLifecycleStatus } from 'src/apollo/definitions/globalTypes';
import {
    CONTRACT_STATUS,
    ContractStatusKey,
    ContractStatusValue,
} from 'src/apollo/type-constants/contract';
import { GetAccountFullDetailQuery } from 'src/apollo/queries/account/__generated__/get-account-full-detail';

type AbacusContract = NonNullable<
    NonNullable<
        NonNullable<GetAccountFullDetailQuery['abacusAccount']>['contracts']
    >[0]
>;

type AbacusContractLifecycle = AbacusContract['lifecycle'];

interface AttachedContractsPropTypes {
    contracts: AbacusContract[];
}

const AttachedContractsCards: React.FC<AttachedContractsPropTypes> = ({
    contracts,
}) => {
    // ACC-9395: TODO remove FF abacus_primary_contract
    const isFeaturePrimaryContractEnabled = useFeatureFlag(
        USER_FEATURES.ABACUS_PRIMARY_CONTRACT
    );

    const renderContractLifecycleStatus = (
        contractLifecycleStatus: AbacusContractLifecycle
    ) => {
        if (!contractLifecycleStatus) {
            return null;
        }
        const lifecycleStatus: AbacusContractLifecycleStatus =
            contractLifecycleStatus['lifecycleStatus'];
        if (lifecycleStatus == 'INACTIVE') {
            return null;
        }

        const contractStatus: ContractStatusValue | undefined =
            CONTRACT_STATUS.get(lifecycleStatus as ContractStatusKey);

        return (
            contractStatus && (
                <Status
                    variant={contractStatus.variant as StatusProps['variant']}
                    text={contractStatus.label}
                    filled={contractStatus.filled}
                    layoutVariant="inline"
                />
            )
        );
    };

    const renderContractHeader = (
        contractName: string,
        contractLifecycleStatus: AbacusContractLifecycle,
        contractId: string,
        isPrimaryContract: boolean
    ) => {
        return (
            <div className="PaymentDetail-contracts-contractCardHeader">
                <div className="PaymentDetail-contracts-contractCardHeader-Left">
                    <h3 className="PaymentDetail-contracts-contractCardHeaderText">
                        <TruncatedText
                            testId="TruncatedContractHeader"
                            key={`${contractName}-truncated`}
                            text={contractName}
                            maxWidth={'25vw'}
                        />
                        &nbsp;•&nbsp;{contractId}
                    </h3>
                    {renderContractLifecycleStatus(contractLifecycleStatus)}
                </div>
                {isPrimaryContract && isFeaturePrimaryContractEnabled && (
                    <Tag variant="category" text="Primary Contract" />
                )}
            </div>
        );
    };

    const formatContracts = () => {
        let sortedContracts = contracts
            .slice()
            .sort((a: AbacusContract, b: AbacusContract) =>
                a.contractName.localeCompare(b.contractName)
            );
        if (isFeaturePrimaryContractEnabled)
            sortedContracts = [
                ...contracts.filter((c: AbacusContract) => c.isPrimaryContract), // primary first
                ...contracts.filter(
                    (c: AbacusContract) => !c.isPrimaryContract
                ), // then others
            ];
        return sortedContracts.map(
            ({
                contractId,
                contractName,
                contractType,
                runController,
                lifecycle,
                isPrimaryContract,
            }) => {
                return {
                    id: contractId,
                    header: renderContractHeader(
                        contractName,
                        lifecycle,
                        contractId,
                        isPrimaryContract
                    ),
                    type:
                        CONTRACT_TYPE_MAP[
                            contractType as keyof typeof CONTRACT_TYPE_MAP
                        ] ?? undefined,
                    runController: runController?.runControllerName,
                    isPrimaryContract: isPrimaryContract,
                };
            }
        );
    };

    const formattedContracts = formatContracts();

    return (
        <Section>
            <Section.Header
                title="Contracts"
                className="PaymentDetail-contracts-title"
                testId="paymentDetailContractsTitle"
            />
            <Section.Body
                className="PaymentDetail-contracts-cardView"
                testId="paymentDetailContracts"
            >
                {formattedContracts.map((contract, index) => (
                    <Card
                        suite
                        testId="contractCard-testId"
                        key={`contractCard-${index}`}
                        href={getContractDetail(contract.id)}
                        className="p-4"
                    >
                        <Card.Header>{contract.header}</Card.Header>
                        <div className="PaymentDetail-contracts-cardView-cardBody">
                            <small>{contract.type}</small>
                            <small>{contract.runController}</small>
                        </div>
                    </Card>
                ))}
                {contracts.length === 0 && (
                    <i>No contracts are attached to this payee</i>
                )}
            </Section.Body>
        </Section>
    );
};

export default AttachedContractsCards;
