import React from 'react';
import { Alert } from 'react-native';
import { fireEvent, render, screen } from '@testing-library/react-native';
import type { SharedValue } from 'react-native-reanimated';
import PageHeader from '../PageHeader';
import type { PageHeaderData } from '../types';
import type { LoadingState } from '../../../types/types';

const progress = { value: 0 } as unknown as SharedValue<number>;
const onBackPress = jest.fn();

const handlers = {
    onBackPress,
    onStarPress: jest.fn(),
    onContentPress: jest.fn()
};

const data: PageHeaderData = {
    title: 'Smooth Criminal',
    subtitle: 'Michael Jackson',
    meta: '14 Sep 2012',
    isDeleted: false,
    isFavorite: true
};

const dataState: LoadingState<PageHeaderData> = { status: 'data', data };

describe('PageHeader', () => {
    let alertSpy: jest.SpyInstance;

    beforeEach(() => {
        jest.clearAllMocks();
        alertSpy = jest.spyOn(Alert, 'alert').mockImplementation(() => {});
    });

    afterEach(() => {
        alertSpy.mockRestore();
    });

    it('shows the current state as text', () => {
        render(
            <PageHeader
                progress={progress}
                loadingState={dataState}
                {...handlers}
            />
        );

        expect(screen.getByText('state: data')).toBeTruthy();
    });

    it('alerts the data when Show props is tapped', () => {
        render(
            <PageHeader
                progress={progress}
                loadingState={dataState}
                {...handlers}
            />
        );

        fireEvent.press(screen.getByLabelText('Show props'));

        expect(alertSpy).toHaveBeenCalledTimes(1);
        const message = alertSpy.mock.calls[0][1];
        expect(message).toContain('title: Smooth Criminal');
        expect(message).toContain('subtitle: Michael Jackson');
        expect(message).toContain('meta: 14 Sep 2012');
        expect(message).toContain('isFavorite: true');
    });

    it('calls onBackPress when the back action is pressed', () => {
        render(
            <PageHeader
                progress={progress}
                loadingState={dataState}
                {...handlers}
            />
        );

        fireEvent.press(screen.getByLabelText('Back'));

        expect(onBackPress).toHaveBeenCalledTimes(1);
    });

    it('shows the loading state', () => {
        render(
            <PageHeader
                progress={progress}
                loadingState={{ status: 'loading' }}
                {...handlers}
            />
        );

        expect(screen.getByText('state: loading')).toBeTruthy();
    });

    it('shows the error state', () => {
        render(
            <PageHeader
                progress={progress}
                loadingState={{ status: 'error', error: new Error('boom') }}
                {...handlers}
            />
        );

        expect(screen.getByText('state: error')).toBeTruthy();
    });
});
