import React from 'react'
import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'

// Mocked first so Directory (and ProjectLayout, which it imports entryNoun
// from) resolve the deployment hook and api without a live fetch.
let mockDeployment = {}
vi.mock('../api', () => ({ getProject: vi.fn(), createProject: vi.fn() }))
vi.mock('../context/DeploymentProvider', () => ({
  useDeployment: () => mockDeployment,
}))
import Directory from './Directory.jsx'

function renderDir(overrides = {}) {
  mockDeployment = {
    name: 'Wiggleverse',
    tagline: 'a directory of projects',
    projects: [],
    viewer: null,
    defaultProjectId: null,
    refresh: vi.fn(),
    ...overrides,
  }
  return render(<MemoryRouter><Directory /></MemoryRouter>)
}

describe('Directory', () => {
  it('renders a card per visible project with the type-driven noun + link', () => {
    renderDir({
      projects: [
        { id: 'ohm', name: 'Open Human Model', type: 'document', visibility: 'public' },
        { id: 'ecomm', name: 'Ecomm', type: 'bdd', visibility: 'public' },
      ],
    })
    const ohm = screen.getByText('Open Human Model').closest('a')
    expect(ohm).toHaveAttribute('href', '/p/ohm/')
    const ecomm = screen.getByText('Ecomm').closest('a')
    expect(ecomm).toHaveAttribute('href', '/p/ecomm/')
    // bdd → "Features", document → "RFCs"
    expect(screen.getByText('RFCs')).toBeInTheDocument()
    expect(screen.getByText('Features')).toBeInTheDocument()
  })

  it('renders the deployment name and tagline', () => {
    renderDir({ projects: [{ id: 'ohm', name: 'OHM', type: 'document', visibility: 'public' }] })
    expect(screen.getByText('Wiggleverse')).toBeInTheDocument()
    expect(screen.getByText('a directory of projects')).toBeInTheDocument()
  })

  it('renders an empty list without crashing when no projects are visible', () => {
    renderDir({ projects: [] })
    expect(screen.getByText('Wiggleverse')).toBeInTheDocument()
  })

  // §22 S5 — role-aware empty states (C3.1 / C3.2).
  it('shows a "Create your first project" CTA to a global Owner on an empty directory', () => {
    renderDir({ projects: [], viewer: { can_create_project: true } })
    expect(screen.getByText('Create your first project')).toBeInTheDocument()
  })

  it('shows a "nothing shared with you yet" note to a non-owner on an empty directory', () => {
    renderDir({ projects: [], viewer: { can_create_project: false } })
    expect(screen.getByText(/Nothing has been shared with you yet/i)).toBeInTheDocument()
    expect(screen.queryByText('Create your first project')).not.toBeInTheDocument()
  })

  it('offers a "New project" control to an Owner when the directory is non-empty', () => {
    renderDir({
      projects: [{ id: 'ohm', name: 'OHM', type: 'document', visibility: 'public' }],
      viewer: { can_create_project: true },
    })
    expect(screen.getByText('New project')).toBeInTheDocument()
  })

  it('does not offer a create control to a non-owner when the directory is non-empty', () => {
    renderDir({
      projects: [{ id: 'ohm', name: 'OHM', type: 'document', visibility: 'public' }],
      viewer: { can_create_project: false },
    })
    expect(screen.queryByText('New project')).not.toBeInTheDocument()
  })
})
