import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { UploadAreaStatus } from '../uploadAreaStatus';
import type { StatusProps } from '../../status';
import type { UploadAreaStatusProps } from '../types';

describe('<UploadAreaStatus>', () => {
    const defaultProps: UploadAreaStatusProps = {
        status: '3 files uploaded',
        statusVariant: 'success',
        header: 'Files',
        files: [
            { name: 'document1.pdf', status: 'Success', statusVariant: 'success' },
            { name: 'document2.pdf', status: 'Success', statusVariant: 'success' },
            { name: 'document3.pdf', status: 'Failed', statusVariant: 'error' },
        ],
    };

    const renderComponent = (props?: Partial<UploadAreaStatusProps>) =>
        render(<UploadAreaStatus {...defaultProps} {...props} />);

    describe('rendering', () => {
        test('renders Status component', () => {
            renderComponent();

            expect(screen.getByTestId('Status')).toBeInTheDocument();
        });

        test('renders main status with correct text', () => {
            renderComponent({ status: 'Upload complete' });

            expect(screen.getByText('Upload complete')).toBeInTheDocument();
        });

        test('renders GlyphButton for popover trigger', () => {
            renderComponent();

            expect(screen.getByRole('button')).toBeInTheDocument();
        });
    });

    describe('status variants', () => {
        test.each<StatusProps['variant']>([
            'success',
            'error',
            'warning',
            'info',
            'revision',
            'loading',
        ])('renders %s variant correctly', (variant) => {
            renderComponent({ statusVariant: variant });

            expect(screen.getByTestId('Status')).toHaveClass(`variant-${variant}`);
        });
    });

    describe('popover', () => {
        test('renders popover with correct id', () => {
            renderComponent();

            expect(screen.getByTestId('Popover')).toHaveAttribute('id', 'UploadAreaStatus');
        });

        test('popover contains GridTable when opened', async () => {
            renderComponent();
            const button = screen.getByRole('button');

            fireEvent.click(button);

            const table = await screen.findByTestId('GridTable');
            expect(table).toBeInTheDocument();
        });
    });

    describe('file list', () => {
        test('renders all files in the table', async () => {
            renderComponent();
            const button = screen.getByRole('button');

            fireEvent.click(button);

            expect(await screen.findByText('document1.pdf')).toBeInTheDocument();
            expect(await screen.findByText('document2.pdf')).toBeInTheDocument();
            expect(await screen.findByText('document3.pdf')).toBeInTheDocument();
        });

        test('renders file statuses', async () => {
            renderComponent();
            const button = screen.getByRole('button');

            fireEvent.click(button);

            const successStatuses = await screen.findAllByText('Success');
            expect(successStatuses).toHaveLength(2);

            const failedStatus = await screen.findByText('Failed');
            expect(failedStatus).toBeInTheDocument();
        });

        test('renders header when provided', async () => {
            renderComponent({ header: 'Uploaded Files' });
            const button = screen.getByRole('button');

            fireEvent.click(button);

            expect(await screen.findByText('Uploaded Files')).toBeInTheDocument();
        });

        test('handles empty files array', () => {
            renderComponent({ files: [] });

            expect(screen.getByTestId('Status')).toBeInTheDocument();
        });

        test('renders filled status badges for files', async () => {
            renderComponent();
            const button = screen.getByRole('button');

            fireEvent.click(button);

            const table = await screen.findByTestId('GridTable');
            const filledStatuses = table.querySelectorAll('.Status.filled');
            expect(filledStatuses.length).toBeGreaterThan(0);
        });
    });
});
