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

// Mock react-native-safe-area-context FIRST
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 icons
jest.mock('@/components/icon', () => ({
    DownArrowIcon: () => 'DownArrowIcon',
    PointsIcon: () => 'PointsIcon',
    SearchIcon: () => 'SearchIcon',
}))

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

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

// Mock react-native RefreshControl (directly from react-native)
jest.mock('react-native', () =>
  Object.assign({}, jest.requireActual('react-native'), {
    RefreshControl: 'RefreshControl',
  })
)

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

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

jest.mock('@/hooks/use-activates', () => ({
    useActivates: jest.fn(() => ({
        load: jest.fn(),
        data: {
            activities: [
                {
                    id: '1',
                    title: 'Test Activity',
                    desc: 'Test Description',
                    coverUrl: 'https://example.com/image.jpg',
                    link: '/test',
                },
            ],
        },
        error: null,
    })),
}))

jest.mock('@/hooks/use-categories', () => ({
    useCategories: jest.fn(() => ({
        load: jest.fn(),
        data: {
            categories: [
                {
                    id: 'cat1',
                    name: 'Test Category',
                    templates: [
                        {
                            id: 'template1',
                            title: 'Test Template',
                            webpPreviewUrl: 'https://example.com/preview.webp',
                            previewUrl: 'https://example.com/preview.jpg',
                            coverImageUrl: 'https://example.com/cover.png',
                            aspectRatio: '1:1',
                        },
                    ],
                },
            ],
        },
        loading: false,
        error: null,
    })),
}))

jest.mock('@/hooks/use-user-balance', () => ({
    useUserBalance: jest.fn(() => ({
        balance: 1234,
        loading: false,
        error: null,
    })),
}))

jest.mock('@/hooks/use-categories-with-tags', () => ({
    useCategoriesWithTags: jest.fn(() => ({
        load: jest.fn(),
        data: {
            categories: [
                {
                    id: 'cat1',
                    name: 'Test Category',
                },
            ],
        },
        loading: false,
        error: null,
    })),
}))

jest.mock('@/hooks/use-category-templates', () => ({
    useCategoryTemplates: jest.fn(() => ({
        templates: [
            {
                id: 'template1',
                title: 'Test Template',
                webpPreviewUrl: 'https://example.com/preview.webp',
                previewUrl: 'https://example.com/preview.jpg',
                coverImageUrl: 'https://example.com/cover.png',
                aspectRatio: '1:1',
            },
        ],
        loading: false,
        loadingMore: false,
        execute: jest.fn(),
        loadMore: jest.fn(),
        hasMore: false,
    })),
}))

jest.mock('@/hooks/use-sticky-tabs', () => ({
    useStickyTabs: jest.fn(() => ({
        isSticky: false,
        tabsHeight: 0,
        titleBarHeightRef: { current: 0 },
        handleScroll: jest.fn(),
        handleTabsLayout: jest.fn(),
        handleTitleBarLayout: jest.fn(),
    })),
}))

jest.mock('@/hooks/use-tab-navigation', () => ({
    useTabNavigation: jest.fn(() => ({
        activeIndex: 0,
        selectedCategoryId: 'cat1',
        tabs: [{ id: 'cat1', name: 'Test Category' }],
        selectTab: jest.fn(),
        selectCategoryById: jest.fn(),
    })),
}))

jest.mock('@/hooks/use-template-filter', () => ({
    useTemplateFilter: jest.fn(({ templates }) => ({
        filteredTemplates: templates,
    })),
}))

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

describe('HomeScreen', () => {
    it('should render title bar with app name', async () => {
        const { getByText } = renderWithProviders(<HomeScreen />)

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

    it('should render category tabs when data is loaded', async () => {
        const { getByText } = renderWithProviders(<HomeScreen />)

        await waitFor(() => {
            expect(getByText('Test Category')).toBeTruthy()
        })
    })

    it('should render template cards when category has templates', async () => {
        const { getByText } = renderWithProviders(<HomeScreen />)

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

    it('should not show loading state when data is loaded', async () => {
        const { queryByText } = renderWithProviders(<HomeScreen />)

        await waitFor(() => {
            expect(queryByText('加载中')).toBeNull()
        })
    })

    it('should display user balance from useUserBalance hook', async () => {
        const { getByText } = renderWithProviders(<HomeScreen />)

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

    describe('Loading States', () => {
        it('should show only one loading indicator when categories are loading', async () => {
            const { useCategoriesWithTags } = require('@/hooks/use-categories-with-tags')
            const { useCategoryTemplates } = require('@/hooks/use-category-templates')

            useCategoriesWithTags.mockReturnValue({
                load: jest.fn(),
                data: null,
                loading: true,
                error: null,
            })

            useCategoryTemplates.mockReturnValue({
                templates: [],
                loading: false,
                loadingMore: false,
                execute: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

            const { UNSAFE_getAllByType } = renderWithProviders(<HomeScreen />)

            await waitFor(() => {
                // 应该只有一个 LoadingState 组件
                const loadingStates = UNSAFE_getAllByType('LoadingState' as any)
                expect(loadingStates.length).toBe(1)
            })
        })

        it('should show only one loading indicator when templates are loading', async () => {
            const { useCategoriesWithTags } = require('@/hooks/use-categories-with-tags')
            const { useCategoryTemplates } = require('@/hooks/use-category-templates')

            useCategoriesWithTags.mockReturnValue({
                load: jest.fn(),
                data: {
                    categories: [{ id: 'cat1', name: 'Test Category' }],
                },
                loading: false,
                error: null,
            })

            useCategoryTemplates.mockReturnValue({
                templates: [],
                loading: true,
                loadingMore: false,
                execute: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

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

            await waitFor(() => {
                // 应该只有一个 ActivityIndicator
                const activityIndicators = UNSAFE_queryAllByType('ActivityIndicator' as any)
                expect(activityIndicators.length).toBeLessThanOrEqual(1)
            })
        })

        it('should NOT show multiple loading indicators simultaneously', async () => {
            const { useCategoriesWithTags } = require('@/hooks/use-categories-with-tags')
            const { useCategoryTemplates } = require('@/hooks/use-category-templates')

            // 模拟两个都在加载的情况
            useCategoriesWithTags.mockReturnValue({
                load: jest.fn(),
                data: null,
                loading: true,
                error: null,
            })

            useCategoryTemplates.mockReturnValue({
                templates: [],
                loading: true,
                loadingMore: false,
                execute: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

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

            await waitFor(() => {
                // 即使两个都在加载，也应该只显示一个 loading
                const loadingStates = UNSAFE_queryAllByType('LoadingState' as any)
                const activityIndicators = UNSAFE_queryAllByType('ActivityIndicator' as any)

                // 总共的 loading 指示器不应该超过 1 个
                const totalLoadingIndicators = loadingStates.length + activityIndicators.length
                expect(totalLoadingIndicators).toBeLessThanOrEqual(1)
            })
        })

        it('should show unified loading state during initial load', async () => {
            const { useCategoriesWithTags } = require('@/hooks/use-categories-with-tags')
            const { useCategoryTemplates } = require('@/hooks/use-category-templates')

            useCategoriesWithTags.mockReturnValue({
                load: jest.fn(),
                data: null,
                loading: true,
                error: null,
            })

            useCategoryTemplates.mockReturnValue({
                templates: [],
                loading: true,
                loadingMore: false,
                execute: jest.fn(),
                loadMore: jest.fn(),
                hasMore: false,
            })

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

            await waitFor(() => {
                // 应该只显示一个统一的 loading 状态
                const allLoadingComponents = [
                    ...UNSAFE_queryAllByType('LoadingState' as any),
                    ...UNSAFE_queryAllByType('ActivityIndicator' as any),
                ]
                expect(allLoadingComponents.length).toBe(1)
            })
        })
    })
})
