import React from 'react';
import { render, screen, cleanup } from '@testing-library/react';
import { useIdentity } from '@theorchard/suite-frontend';
import { usePPEnabledFF } from 'src/utils/features';
import { useCrudPermissions } from 'src/utils/identityPermissions';
import { ROUTE_CATALOG } from '../constants';
import {
    CatalogRedirect,
    CatalogEntry,
    useHasPermission,
    CreatePerformanceRedirect,
} from '../index';

jest.mock('react-router-dom', () => ({
    Redirect: ({ to }: { to: string }) => (
        <div data-testid="redirect">{to}</div>
    ),
}));

jest.mock('@theorchard/suite-frontend', () => ({
    useIdentity: jest.fn(),
    initApplicationModule: jest.fn(),
}));

jest.mock('src/utils/features', () => ({
    usePPEnabledFF: jest.fn(),
}));

jest.mock('src/utils/identityPermissions', () => ({
    useCrudPermissions: jest.fn(),
}));

// mock the actual CatalogPage imported by index.tsx
jest.mock('../pages/catalogPage', () => () => (
    <div data-testid="catalog-page" />
));

// mock the CreatePage imported by index.tsx
jest.mock('../pages/createPage', () => () => <div data-testid="create-page" />);

const useIdentityMock = useIdentity as jest.Mock;
const usePPEnabledFFMock = usePPEnabledFF as jest.Mock;
const useCrudPermissionsMock = useCrudPermissions as jest.Mock;

const permissionsTrue = {
    data: true,
    loading: false,
    error: null,
};
const permissionsFalse = {
    ...permissionsTrue,
    data: false,
};

describe('useHasPermission', () => {
    afterEach(() => {
        jest.resetAllMocks();
        cleanup();
    });

    it('returns canView true when checkAllPermissions returns true', () => {
        useIdentityMock.mockReturnValue({ id: 'user-1' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsFalse,
        });

        const TestComp: React.FC = () => {
            const { canView } = useHasPermission();
            return <div data-testid="perm">{canView ? 'yes' : 'no'}</div>;
        };

        render(<TestComp />);
        expect(screen.getByTestId('perm')).toHaveTextContent('yes');
    });

    it('returns canView false when checkViewPermission returns false', () => {
        useIdentityMock.mockReturnValue({ id: 'user-2' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsFalse,
            checkCreatePermission: () => permissionsFalse,
        });

        const TestComp: React.FC = () => {
            const {
                canView: { data },
            } = useHasPermission();
            return <div data-testid="perm">{data ? 'yes' : 'no'}</div>;
        };

        render(<TestComp />);
        expect(screen.getByTestId('perm')).toHaveTextContent('no');
    });
    it('returns canCreate true when checkAllPermissions returns true', () => {
        useIdentityMock.mockReturnValue({ id: 'user-1' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsTrue,
        });

        const { canCreate } = useHasPermission();
        expect(canCreate.data).toBe(true);
    });

    it('returns canCreate false when checkViewPermission returns false', () => {
        useIdentityMock.mockReturnValue({ id: 'user-2' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsFalse,
        });

        const { canCreate } = useHasPermission();
        expect(canCreate.data).toBe(false);
    });
});

describe('CatalogRedirect & CatalogEntry', () => {
    afterEach(() => {
        jest.resetAllMocks();
        cleanup();
    });

    it('CatalogRedirect sends to ROUTE_CATALOG when canView is true', () => {
        useIdentityMock.mockReturnValue({ id: 'user-3' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsFalse,
        });

        render(<CatalogRedirect />);
        expect(screen.getByTestId('redirect')).toHaveTextContent(ROUTE_CATALOG);
    });

    it('CatalogRedirect sends to sr-ownership when canView is false', () => {
        useIdentityMock.mockReturnValue({ id: 'user-4' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsFalse,
            checkCreatePermission: () => permissionsFalse,
        });

        render(<CatalogRedirect />);
        expect(screen.getByTestId('redirect')).toHaveTextContent(
            '/catalog/sr-ownership'
        );
    });

    it('CatalogEntry renders CatalogPage when canView is true', () => {
        useIdentityMock.mockReturnValue({ id: 'user-5' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsFalse,
        });

        render(<CatalogEntry />);
        expect(screen.getByTestId('catalog-page')).toBeInTheDocument();
    });

    it('CatalogEntry redirects to sr-ownership when canView is false', () => {
        useIdentityMock.mockReturnValue({ id: 'user-6' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsFalse,
            checkCreatePermission: () => permissionsFalse,
        });

        render(<CatalogEntry />);
        expect(screen.getByTestId('redirect')).toHaveTextContent(
            '/catalog/sr-ownership'
        );
    });
});

describe('CreatePerformanceRedirect', () => {
    afterEach(() => {
        jest.resetAllMocks();
        cleanup();
    });

    it('renders CreatePage when canCreate is true', () => {
        useIdentityMock.mockReturnValue({ id: 'user-7' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsTrue,
        });

        render(<CreatePerformanceRedirect />);
        expect(screen.getByTestId('create-page')).toBeInTheDocument();
    });

    it('redirects to Catalog when canCreate is false', () => {
        useIdentityMock.mockReturnValue({ id: 'user-8' });
        usePPEnabledFFMock.mockReturnValue(true);
        useCrudPermissionsMock.mockReturnValue({
            checkViewPermission: () => permissionsTrue,
            checkCreatePermission: () => permissionsFalse,
        });

        render(<CreatePerformanceRedirect />);
        expect(screen.getByTestId('redirect')).toHaveTextContent(ROUTE_CATALOG);
    });
});
