import React from 'react';
import { Router } from 'react-router-dom';
import { screen, fireEvent } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import AttachedContractsCards from '../attached-contracts-cards'; // Adjust path as needed
import {
    ABACUS_PROFILE,
    CONTRACT_TYPE_MAP,
    USER_FEATURES,
} from 'src/constants';
import * as urls from 'src/urls/frontend-royalties';
import { AbacusContractLifecycleStatus } from 'src/apollo/definitions/globalTypes';
import { createMemoryHistory } from 'history';

jest.mock('src/urls/frontend-royalties', () => ({
    getContractDetail: jest.fn(id => `/contract/${id}`),
}));

describe('AttachedContractsCards', () => {
    const features = {
        [USER_FEATURES.ABACUS_PRIMARY_CONTRACT]: false,
    };

    const baseContract = {
        contractId: '12345',
        contractName: 'Test Contract',
        contractType: 'distribution',
        runController: { runControllerName: 'AWAL' },
        lifecycle: {
            lifecycleStatus: AbacusContractLifecycleStatus.ACTIVE,
        },
    };

    const history = createMemoryHistory();
    const render = (
        component: React.ReactElement,
        features: { [x: number]: boolean }
    ) =>
        renderInAppContext(<Router history={history}>{component}</Router>, {
            identity: createIdentity({ features, profileType: ABACUS_PROFILE }),
        });

    it('renders a heading', () => {
        render(<AttachedContractsCards contracts={[baseContract]} />, features);
        const header = screen.getByTestId('paymentDetailContractsTitle');
        expect(header).toBeInTheDocument();
        expect(header).toHaveTextContent(/contracts/i);
    });

    it('renders contract name, id, type and run controller', () => {
        render(<AttachedContractsCards contracts={[baseContract]} />, features);

        expect(screen.getByText(/Test Contract/)).toBeInTheDocument();
        expect(screen.getByText(/12345/)).toBeInTheDocument();
        expect(
            screen.getByText(CONTRACT_TYPE_MAP['distribution'])
        ).toBeInTheDocument();
        expect(screen.getByText('AWAL')).toBeInTheDocument();
    });

    it('renders contract status when lifecycle is ACTIVE', () => {
        render(<AttachedContractsCards contracts={[baseContract]} />, features);
        expect(screen.getByText('Active')).toBeInTheDocument(); // assuming 'Active' is label for 'ACTIVE'
    });

    it('hides contract status when lifecycle is INACTIVE', () => {
        const inactiveContract = {
            ...baseContract,
            lifecycle: {
                lifecycleStatus: AbacusContractLifecycleStatus.INACTIVE,
            },
        };
        render(
            <AttachedContractsCards contracts={[inactiveContract]} />,
            features
        );
        expect(screen.queryByText('Active')).not.toBeInTheDocument();
    });

    it('renders fallback message when no contracts are passed', () => {
        render(<AttachedContractsCards contracts={[]} />, features);
        expect(
            screen.getByText(/No contracts are attached to this payee/i)
        ).toBeInTheDocument();
    });

    it('renders TruncatedText', () => {
        const longName =
            'This contract name is definitely over 40 characters in length..........';
        const contract = {
            ...baseContract,
            contractName: longName,
        };
        render(<AttachedContractsCards contracts={[contract]} />, features);
        expect(
            screen.getByTestId('TruncatedContractHeader')
        ).toBeInTheDocument();
    });

    it('navigates to contract detail on click', () => {
        const contractId = baseContract.contractId;
        render(<AttachedContractsCards contracts={[baseContract]} />, features);

        const card = screen.getByText(/Test Contract/).closest('div');
        fireEvent.click(card!);

        expect(urls.getContractDetail).toHaveBeenCalledWith(contractId);
        expect(history.location.pathname).toBe(`/contract/${contractId}`);
    });

    it('renders multiple contracts when ff is disabled and there is a primary contract', () => {
        const mockContracts = [
            {
                contractId: '12345',
                contractName: 'A Test Contract',
                contractType: 'distribution',
                runController: { runControllerName: 'AWAL' },
                lifecycle: {
                    lifecycleStatus: AbacusContractLifecycleStatus.ACTIVE,
                },
                isPrimaryContract: false,
            },
            {
                contractId: '12346',
                contractName: 'B Test Contract',
                contractType: 'distribution',
                runController: { runControllerName: 'AWAL' },
                lifecycle: {
                    lifecycleStatus: AbacusContractLifecycleStatus.ACTIVE,
                },
                isPrimaryContract: true,
            },
        ];
        render(<AttachedContractsCards contracts={mockContracts} />, features);

        const cards = screen.getAllByTestId('contractCard-testId');
        expect(cards[0]).toHaveTextContent(/A Test Contract/);
        expect(cards[1]).toHaveTextContent(/B Test Contract/);

        expect(cards[0]).not.toHaveTextContent('Primary Contract');
        expect(cards[1]).not.toHaveTextContent('Primary Contract');
    });

    it('renders multiple contracts when ff is enabled and there is a primary contract', () => {
        const mockContracts = [
            {
                contractId: '12345',
                contractName: 'A Test Contract',
                contractType: 'distribution',
                runController: { runControllerName: 'AWAL' },
                lifecycle: {
                    lifecycleStatus: AbacusContractLifecycleStatus.ACTIVE,
                },
                isPrimaryContract: false,
            },
            {
                contractId: '12346',
                contractName: 'B Test Contract',
                contractType: 'distribution',
                runController: { runControllerName: 'AWAL' },
                lifecycle: {
                    lifecycleStatus: AbacusContractLifecycleStatus.ACTIVE,
                },
                isPrimaryContract: true,
            },
        ];
        const enabled_features = {
            [USER_FEATURES.ABACUS_PRIMARY_CONTRACT]: true,
        };
        render(
            <AttachedContractsCards contracts={mockContracts} />,
            enabled_features
        );

        const cards = screen.getAllByTestId('contractCard-testId');
        expect(cards[0]).toHaveTextContent(/B Test Contract/);
        expect(cards[1]).toHaveTextContent(/A Test Contract/);

        expect(cards[0]).toHaveTextContent('Primary Contract');
        expect(cards[1]).not.toHaveTextContent('Primary Contract');
    });
});
