// @vitest-environment happy-dom
import { describe, expect, it, vi, beforeEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'

/**
 * The login screen resolves its logo to match the admin sidebar:
 *   1. the brand uploaded in Settings → Appearance (cached admin brand, then
 *      the unauthenticated `/public/brand` endpoint for fresh browsers),
 *   2. the static `config.admin.branding.logo`,
 *   3. the bundled Actuate wordmark,
 * and `branding.logo === null` hides the logo entirely (whitelabel opt-out).
 *
 * `cmsApi` is mocked because the component fetches `/public/brand` on mount.
 */
const cmsApiMock = vi.fn()
vi.mock('../../lib/api.js', () => ({
  cmsApi: (...args: unknown[]) => cmsApiMock(...args),
}))

import { Login } from '../../views/Login.js'

const onLogin = vi.fn(async () => ({ success: true }))

beforeEach(() => {
  cmsApiMock.mockReset()
  // Default: no public brand configured.
  cmsApiMock.mockResolvedValue({ data: {}, status: 200 })
})

describe('Login — logo resolution', () => {
  it('renders the bundled Actuate logo when nothing is branded', async () => {
    render(<Login onLogin={onLogin} />)
    // Bundled SVG exposes role="img" + aria-label="Actuate Media".
    expect(screen.getByRole('img', { name: 'Actuate Media' })).toBeTruthy()
    // No <img> logo element.
    expect(screen.queryByRole('img', { name: 'Actuate CMS' })).toBeNull()
    await waitFor(() => expect(cmsApiMock).toHaveBeenCalledWith('/public/brand'))
  })

  it('shows the neutral logo placeholder when branded but no logo is set', async () => {
    render(<Login onLogin={onLogin} branding={{ name: 'Acme Co' }} />)
    // Placeholder slot, not the bundled Actuate wordmark.
    expect(screen.getByRole('img', { name: 'Logo placeholder' })).toBeTruthy()
    expect(screen.queryByRole('img', { name: 'Actuate Media' })).toBeNull()
    // The brand name still renders as the headline.
    expect(screen.getByRole('heading', { name: 'Acme Co' })).toBeTruthy()
  })

  it('shows the placeholder for a fresh browser when /public/brand reports a branded site (initials) but no logo', async () => {
    // No config name, no cached admin brand — only the public brand initials
    // signal a branded install. The logo-less fallback must be the placeholder,
    // not the Actuate wordmark.
    cmsApiMock.mockResolvedValue({
      data: { public: { primary: null, initials: 'AC' } },
      status: 200,
    })

    render(<Login onLogin={onLogin} />)

    await waitFor(() => {
      expect(screen.getByRole('img', { name: 'Logo placeholder' })).toBeTruthy()
    })
    expect(screen.queryByRole('img', { name: 'Actuate Media' })).toBeNull()
  })

  it('uses the static config logo when no appearance brand exists', async () => {
    render(
      <Login onLogin={onLogin} branding={{ logo: 'https://cdn.example.com/config-logo.png' }} />,
    )
    const img = (await screen.findByAltText('Actuate CMS')) as HTMLImageElement
    expect(img.getAttribute('src')).toBe('https://cdn.example.com/config-logo.png')
  })

  it('prefers the uploaded appearance logo from /public/brand over the config logo', async () => {
    cmsApiMock.mockResolvedValue({
      data: { public: { primary: { url: 'https://cdn.example.com/appearance-logo.svg' } } },
      status: 200,
    })

    render(
      <Login onLogin={onLogin} branding={{ logo: 'https://cdn.example.com/config-logo.png' }} />,
    )

    await waitFor(() => {
      const img = screen.getByAltText('Actuate CMS') as HTMLImageElement
      expect(img.getAttribute('src')).toBe('https://cdn.example.com/appearance-logo.svg')
    })
  })

  it('hides the logo entirely when branding.logo is null (whitelabel) and skips the fetch', async () => {
    render(<Login onLogin={onLogin} branding={{ logo: null }} />)
    expect(screen.queryByRole('img', { name: 'Actuate Media' })).toBeNull()
    expect(screen.queryByAltText('Actuate CMS')).toBeNull()
    expect(cmsApiMock).not.toHaveBeenCalled()
  })
})
