import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte'
import CommunityUser from './CommunityUser.svelte'
import { auth } from '../lib/stores/auth.js'

const mockPush = vi.fn()
vi.mock('svelte-spa-router', () => ({
  push: (...args) => mockPush(...args),
}))

vi.mock('../lib/stores/auth.js', () => {
  const { writable } = require('svelte/store')
  const store = writable({ user: { id: 'u1' }, loading: false, error: null })
  return { auth: { subscribe: store.subscribe, set: store.set } }
})

const mockFetchPublishedDecksByOwner = vi.fn()
const mockCopyDeckToUser = vi.fn()
const mockGetMyDeckRating = vi.fn()
const mockSubmitDeckRating = vi.fn()
vi.mock('../lib/api/decks.js', () => ({
  fetchPublishedDecksByOwner: (...args) => mockFetchPublishedDecksByOwner(...args),
  copyDeckToUser: (...args) => mockCopyDeckToUser(...args),
  getMyDeckRating: (...args) => mockGetMyDeckRating(...args),
  submitDeckRating: (...args) => mockSubmitDeckRating(...args),
}))

describe('CommunityUser', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    auth.set({ user: { id: 'u1' }, loading: false, error: null })
    mockFetchPublishedDecksByOwner.mockResolvedValue({
      decks: [],
      owner_display_name: 'Test User',
      owner_email: 'test@example.com',
    })
  })

  it('loads and shows owner name when no decks', async () => {
    render(CommunityUser, { props: { params: { id: 'owner1' } } })
    expect(screen.getByText('Loading…')).toBeInTheDocument()
    await waitFor(() => expect(screen.getByText(/Decks by Test User/)).toBeInTheDocument())
    expect(mockFetchPublishedDecksByOwner).toHaveBeenCalledWith('owner1', 'u1')
  })

  it('shows error when fetch fails', async () => {
    mockFetchPublishedDecksByOwner.mockRejectedValue(new Error('Not found'))
    render(CommunityUser, { props: { params: { id: 'owner1' } } })
    await waitFor(() => expect(screen.getByText('Not found')).toBeInTheDocument())
  })

  it('goCommunity button calls push to /community', async () => {
    render(CommunityUser, { props: { params: { id: 'owner1' } } })
    await waitFor(() => expect(screen.getByRole('button', { name: /Community/ })).toBeInTheDocument())
    await fireEvent.click(screen.getByRole('button', { name: /Community/ }))
    expect(mockPush).toHaveBeenCalledWith('/community')
  })

  it('renders deck list when decks returned', async () => {
    mockFetchPublishedDecksByOwner.mockResolvedValue({
      decks: [
        { id: 'd1', title: 'Deck One', owner_id: 'owner1', question_count: 3, user_has_this: false },
      ],
      owner_display_name: 'Alice',
      owner_email: 'a@b.com',
    })
    render(CommunityUser, { props: { params: { id: 'owner1' } } })
    await waitFor(() => expect(screen.getByText('Deck One')).toBeInTheDocument())
    expect(screen.getByText(/Decks by Alice/)).toBeInTheDocument()
  })
})
