import {describe, expect, it, vi, beforeEach, afterEach} from 'vitest'

import {
  render,
  screen,
  userEvent,
  mockShop,
  mockMinisSDK,
  resetAllMocks,
} from '../../test-utils'

import {
  MerchantCard,
  MerchantCardContainer,
  MerchantCardHeader,
  MerchantCardInfo,
  MerchantCardName,
  MerchantCardRating,
} from './merchant-card'

// Mock hooks
vi.mock('../../hooks/navigation/useShopNavigation', () => ({
  useShopNavigation: () => ({
    navigateToShop: mockMinisSDK.navigateToShop,
    navigateToProduct: mockMinisSDK.navigateToProduct,
  }),
}))

// Mock utils with simple implementations
vi.mock('../../utils', () => ({
  extractBrandTheme: vi.fn(() => ({
    type: 'default',
    backgroundColor: 'white',
  })),
  getFeaturedImages: vi.fn(() => []),
  formatReviewCount: vi.fn((count: number) => {
    if (count >= 1000) return `${(count / 1000).toFixed(1)}k`
    return count.toString()
  }),
  normalizeRating: vi.fn((rating: number) => rating.toFixed(1)),
}))

vi.mock('../../utils/colors', () => ({
  isDarkColor: vi.fn(() => false),
}))

describe('MerchantCard', () => {
  beforeEach(() => {
    resetAllMocks()
  })

  afterEach(() => {
    vi.clearAllMocks()
  })

  describe('Rendering', () => {
    it('renders with basic shop information', () => {
      const shop = mockShop()
      render(<MerchantCard shop={shop} />)

      expect(screen.getByText(shop.name)).toBeInTheDocument()
      // createShop returns 4.3 rating with 50 reviews
      expect(screen.getByText('4.3 (50)')).toBeInTheDocument() // Rating and review count
    })

    it('renders shop logo when available', () => {
      const shop = mockShop({
        visualTheme: {
          logoImage: {
            url: 'https://example.com/logo.png',
            altText: 'Shop Logo',
            sensitive: false,
          },
          featuredImages: [],
          id: '123',
        },
      })

      render(<MerchantCard shop={shop} />)

      const logo = screen.getByAltText(`${shop.name} logo`)
      expect(logo).toBeInTheDocument()
      expect(logo).toHaveAttribute('src', 'https://example.com/logo.png')
    })

    it('renders shop initial when logo is not available', () => {
      const shop = mockShop({
        name: 'Test Shop',
        visualTheme: null,
      })

      render(<MerchantCard shop={shop} />)

      expect(screen.getByText('T')).toBeInTheDocument()
    })

    it('renders without reviews when not available', () => {
      const shop = mockShop({
        reviewAnalytics: {
          averageRating: null,
          reviewCount: 0,
        },
      })

      render(<MerchantCard shop={shop} />)

      expect(
        screen.queryByTestId('merchant-card-rating')
      ).not.toBeInTheDocument()
    })
  })

  describe('Interactions', () => {
    it('handles shop click navigation', async () => {
      const user = userEvent.setup()
      const shop = mockShop()

      render(<MerchantCard shop={shop} />)

      const card = screen.getByText(shop.name).closest('div')
        ?.parentElement?.parentElement
      await user.click(card!)

      expect(mockMinisSDK.navigateToShop).toHaveBeenCalledWith({
        shopId: shop.id,
      })
    })

    it('does not navigate when touchable is false', async () => {
      const user = userEvent.setup()
      const shop = mockShop()

      render(<MerchantCard shop={shop} touchable={false} />)

      const card = screen.getByText(shop.name).closest('div')
        ?.parentElement?.parentElement
      await user.click(card!)

      expect(mockMinisSDK.navigateToShop).not.toHaveBeenCalled()
    })
  })

  describe('Custom Composition', () => {
    it('renders with custom children layout', () => {
      const shop = mockShop()

      render(
        <MerchantCard shop={shop}>
          <MerchantCardContainer>
            <div data-testid="custom-layout">
              <MerchantCardName>Custom Name</MerchantCardName>
              <MerchantCardRating />
            </div>
          </MerchantCardContainer>
        </MerchantCard>
      )

      expect(screen.getByTestId('custom-layout')).toBeInTheDocument()
      expect(screen.getByText('Custom Name')).toBeInTheDocument()
      // createShop returns 4.3 rating with 50 reviews
      expect(screen.getByText('4.3 (50)')).toBeInTheDocument()
    })

    it('allows individual component usage', () => {
      const shop = mockShop()

      render(
        <MerchantCard shop={shop}>
          <MerchantCardContainer>
            <MerchantCardHeader withLogo />
            <MerchantCardInfo>
              <MerchantCardName />
              <MerchantCardRating />
            </MerchantCardInfo>
          </MerchantCardContainer>
        </MerchantCard>
      )

      expect(screen.getByText(shop.name)).toBeInTheDocument()
      // createShop returns 4.3 rating with 50 reviews
      expect(screen.getByText('4.3 (50)')).toBeInTheDocument()
    })
  })

  describe('Edge Cases', () => {
    it('handles shop without visual theme', () => {
      const shop = mockShop({
        visualTheme: null,
      })

      render(<MerchantCard shop={shop} />)

      expect(screen.getByText(shop.name)).toBeInTheDocument()
    })

    it('handles shop with empty name', () => {
      const shop = mockShop({
        name: '',
      })

      render(<MerchantCard shop={shop} />)

      // Should still render with empty name
      const heading = screen.getByRole('heading', {level: 3})
      expect(heading).toBeInTheDocument()
    })

    it('handles very long shop names', () => {
      const shop = mockShop({
        name: 'This is a very long shop name that should be truncated in the UI',
      })

      render(<MerchantCard shop={shop} />)

      const nameElement = screen.getByText(shop.name)
      expect(nameElement).toHaveClass('truncate')
    })

    it('handles high review counts', () => {
      const shop = mockShop({
        reviewAnalytics: {
          averageRating: 4.8,
          reviewCount: 12500,
        },
      })

      render(<MerchantCard shop={shop} />)

      expect(screen.getByText('4.8 (12.5k)')).toBeInTheDocument()
    })
  })

  describe('Accessibility', () => {
    it('maintains proper heading hierarchy', () => {
      const shop = mockShop()
      render(<MerchantCard shop={shop} />)

      const heading = screen.getByRole('heading', {level: 3})
      expect(heading).toHaveTextContent(shop.name)
    })

    it('provides fallback alt text for logo', () => {
      const shop = mockShop({
        visualTheme: {
          logoImage: {
            url: 'https://example.com/logo.png',
            altText: null,
            sensitive: false,
          },
          featuredImages: [],
          id: '123',
        },
      })

      render(<MerchantCard shop={shop} />)

      const logo = screen.getByAltText(`${shop.name} logo`)
      expect(logo).toBeInTheDocument()
    })
  })
})
