import { describe, expect, it, vi, beforeEach } from 'vitest'
import { renderHook } from '@testing-library/react'
import { useLocation } from 'react-router-dom'

import { useBreadcrumbs } from './useBreadcrumbs'

// Mock react-router-dom
vi.mock('react-router-dom', () => ({
  useLocation: vi.fn(),
}))

describe('lib/hooks/useBreadcrumbs', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  describe('useBreadcrumbs', () => {
    it('should return empty array for root path', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toEqual([])
    })

    it('should return breadcrumbs for dashboard', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/dashboard',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: '概览',
        path: undefined, // Last item has no path
      })
    })

    it('should return breadcrumbs for users page', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/users',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: '用户管理',
        path: undefined,
      })
    })

    it('should return breadcrumbs for nested path', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/logs/login',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(2)
      expect(result.current[0]).toEqual({
        title: '审计日志',
        path: '/logs',
      })
      expect(result.current[1]).toEqual({
        title: '登录日志',
        path: undefined,
      })
    })

    it('should return breadcrumbs for profile security', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/profile/security',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(2)
      expect(result.current[0]).toEqual({
        title: '个人资料',
        path: '/profile',
      })
      expect(result.current[1]).toEqual({
        title: '安全设置',
        path: undefined,
      })
    })

    it('should skip unknown path segments', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/unknown/path',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      // Unknown paths should return empty array
      expect(result.current).toEqual([])
    })

    it('should return breadcrumbs for roles page', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/roles',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: '角色管理',
        path: undefined,
      })
    })

    it('should return breadcrumbs for permissions page', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/permissions',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: '权限管理',
        path: undefined,
      })
    })

    it('should return breadcrumbs for webhooks page', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/webhooks',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: 'Webhooks',
        path: undefined,
      })
    })

    it('should return breadcrumbs for import-export page', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/import-export',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(1)
      expect(result.current[0]).toEqual({
        title: '导入导出',
        path: undefined,
      })
    })

    it('should return breadcrumbs for operation logs', () => {
      vi.mocked(useLocation).mockReturnValue({
        pathname: '/logs/operation',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      })

      const { result } = renderHook(() => useBreadcrumbs())
      expect(result.current).toHaveLength(2)
      expect(result.current[0]).toEqual({
        title: '审计日志',
        path: '/logs',
      })
      expect(result.current[1]).toEqual({
        title: '操作日志',
        path: undefined,
      })
    })

    it('should memoize result based on pathname', () => {
      const location1 = {
        pathname: '/dashboard',
        search: '',
        hash: '',
        state: null,
        key: 'default',
      }

      vi.mocked(useLocation).mockReturnValue(location1)

      const { result, rerender } = renderHook(() => useBreadcrumbs())
      const firstResult = result.current

      // Rerender with same pathname
      rerender()
      expect(result.current).toBe(firstResult) // Should be same reference

      // Change pathname
      vi.mocked(useLocation).mockReturnValue({
        ...location1,
        pathname: '/users',
      })
      rerender()
      expect(result.current).not.toBe(firstResult) // Should be different reference
    })
  })
})
