import React from 'react'
import { render, waitFor } from '@testing-library/react-native'
import FavoritesScreen from '../favorites'

// Mock react-native-safe-area-context
jest.mock('react-native-safe-area-context', () => ({
    SafeAreaProvider: ({ children }: any) => children,
    SafeAreaView: ({ children }: any) => children,
    useSafeAreaInsets: () => ({ top: 0, right: 0, bottom: 0, left: 0 }),
}))

// Mock expo-linear-gradient
jest.mock('expo-linear-gradient', () => ({
    LinearGradient: 'LinearGradient',
}))

// Mock expo-image
jest.mock('expo-image', () => ({
    Image: 'Image',
}))

// Mock expo-status-bar
jest.mock('expo-status-bar', () => ({
    StatusBar: 'StatusBar',
}))

// Mock @react-navigation/native
jest.mock('@react-navigation/native', () => ({
    useFocusEffect: jest.fn(),
    useNavigation: () => ({
        navigate: jest.fn(),
        goBack: jest.fn(),
    }),
}))

// Mock components
jest.mock('@/components/ErrorState', () => 'ErrorState')
jest.mock('@/components/LoadingState', () => 'LoadingState')

// Mock home blocks
jest.mock('@/components/blocks/home', () => ({
    TitleBar: 'TitleBar',
    TemplateCard: 'TemplateCard',
}))

// Mock dependencies
jest.mock('expo-router', () => ({
    useRouter: jest.fn(() => ({
        push: jest.fn(),
    })),
}))

jest.mock('react-i18next', () => ({
    useTranslation: () => ({
        t: (key: string) => key,
        i18n: { language: 'zh-CN' },
    }),
}))

jest.mock('@/hooks/use-user-favorites', () => ({
    useUserFavorites: jest.fn(),
}))

const renderWithProviders = (component: React.ReactElement) => {
    return render(component)
}

describe('FavoritesScreen', () => {
    beforeEach(() => {
        jest.clearAllMocks()
    })

    it('should render the favorites screen', async () => {
        const { useUserFavorites } = require('@/hooks/use-user-favorites')
        const { useFocusEffect } = require('@react-navigation/native')

        useFocusEffect.mockImplementation((callback: any) => callback())

        useUserFavorites.mockReturnValue({
            favorites: [],
            loading: false,
            loadingMore: false,
            error: null,
            execute: jest.fn(),
            refetch: jest.fn(),
            loadMore: jest.fn(),
            hasMore: false,
        })

        const { getByText } = renderWithProviders(<FavoritesScreen />)

        await waitFor(() => {
            expect(getByText('我的收藏')).toBeTruthy()
        })
    })

    it('should call execute on mount', async () => {
        const { useUserFavorites } = require('@/hooks/use-user-favorites')
        const { useFocusEffect } = require('@react-navigation/native')

        useFocusEffect.mockImplementation((callback: any) => callback())

        const executeMock = jest.fn()
        useUserFavorites.mockReturnValue({
            favorites: [],
            loading: false,
            loadingMore: false,
            error: null,
            execute: executeMock,
            refetch: jest.fn(),
            loadMore: jest.fn(),
            hasMore: false,
        })

        renderWithProviders(<FavoritesScreen />)

        await waitFor(() => {
            expect(executeMock).toHaveBeenCalled()
        })
    })

    describe('Loading States', () => {
        it('should show loading state when loading', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [],
                loading: true,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { UNSAFE_queryAllByType } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                const loadingStates = UNSAFE_queryAllByType('LoadingState' as any)
                expect(loadingStates.length).toBe(1)
            })
        })

        it('should not show loading when data is loaded', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [{
                    id: '1',
                    templateId: 'template-1',
                    createdAt: new Date(),
                    template: {
                        id: 'template-1',
                        title: 'Test Template',
                        previewUrl: 'https://example.com/preview.jpg',
                    },
                }],
                loading: false,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { UNSAFE_queryAllByType } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                const loadingStates = UNSAFE_queryAllByType('LoadingState' as any)
                expect(loadingStates.length).toBe(0)
            })
        })
    })

    describe('Error States', () => {
        it('should show error state when there is an error', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            const executeMock = jest.fn()
            useUserFavorites.mockReturnValue({
                favorites: [],
                loading: false,
                loadingMore: false,
                error: { status: 500, message: 'Server Error' },
                execute: executeMock,
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { getByText } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                expect(getByText('加载收藏失败')).toBeTruthy()
            })
        })
    })

    describe('Empty States', () => {
        it('should show empty state when there are no favorites', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [],
                loading: false,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { getByText } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                expect(getByText('暂无收藏')).toBeTruthy()
            })
        })
    })

    describe('Template List', () => {
        it('should render template cards when favorites are loaded', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [
                    {
                        id: '1',
                        templateId: 'template-1',
                        createdAt: new Date(),
                        template: {
                            id: 'template-1',
                            title: 'Test Template 1',
                            previewUrl: 'https://example.com/preview1.jpg',
                        },
                    },
                    {
                        id: '2',
                        templateId: 'template-2',
                        createdAt: new Date(),
                        template: {
                            id: 'template-2',
                            title: 'Test Template 2',
                            previewUrl: 'https://example.com/preview2.jpg',
                        },
                    },
                ],
                loading: false,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { getByText } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                expect(getByText('Test Template 1')).toBeTruthy()
                expect(getByText('Test Template 2')).toBeTruthy()
            })
        })

        it('should filter out items without template', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [
                    {
                        id: '1',
                        templateId: 'template-1',
                        createdAt: new Date(),
                        template: {
                            id: 'template-1',
                            title: 'Valid Template',
                            previewUrl: 'https://example.com/preview.jpg',
                        },
                    },
                    {
                        id: '2',
                        templateId: 'template-2',
                        createdAt: new Date(),
                        template: null,
                    },
                ],
                loading: false,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { getByText } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                expect(getByText('Valid Template')).toBeTruthy()
            })
        })
    })

    describe('Pull to Refresh', () => {
        it('should call refetch when screen is focused', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            let focusCallback: any
            useFocusEffect.mockImplementation((callback: any) => {
                focusCallback = callback
                callback()
            })

            const refetchMock = jest.fn()
            useUserFavorites.mockReturnValue({
                favorites: [],
                loading: false,
                loadingMore: false,
                error: null,
                execute: jest.fn(),
                refetch: refetchMock,
                loadMore: jest.fn(),
                hasMore: false,
            })

            renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                expect(refetchMock).toHaveBeenCalled()
            })
        })
    })

    describe('Load More', () => {
        it('should show loading indicator when loading more', async () => {
            const { useUserFavorites } = require('@/hooks/use-user-favorites')
            const { useFocusEffect } = require('@react-navigation/native')

            useFocusEffect.mockImplementation((callback: any) => callback())

            useUserFavorites.mockReturnValue({
                favorites: [
                    {
                        id: '1',
                        templateId: 'template-1',
                        createdAt: new Date(),
                        template: {
                            id: 'template-1',
                            title: 'Test Template',
                            previewUrl: 'https://example.com/preview.jpg',
                        },
                    },
                ],
                loading: false,
                loadingMore: true,
                error: null,
                execute: jest.fn(),
                refetch: jest.fn(),
                loadMore: jest.fn(),
                hasMore: true,
            })

            const { UNSAFE_queryAllByType } = renderWithProviders(<FavoritesScreen />)

            await waitFor(() => {
                const activityIndicators = UNSAFE_queryAllByType('ActivityIndicator' as any)
                expect(activityIndicators.length).toBeGreaterThan(0)
            })
        })
    })
})
