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

const fetchPostForEditor = vi.fn()
const fetchTemplateForEditor = vi.fn()
vi.mock('../../lib/post-editor-service.js', async (importOriginal) => {
  const actual = await importOriginal<typeof import('../../lib/post-editor-service.js')>()
  return {
    ...actual,
    fetchPostForEditor: (...args: unknown[]) => fetchPostForEditor(...args),
    fetchTemplateForEditor: (...args: unknown[]) => fetchTemplateForEditor(...args),
  }
})

const { PostSectionEditor } = await import('../../views/post-editor/PostSectionEditor.js')

const validConfig = {
  collections: {
    blog: {
      slug: 'blog',
      labels: { singular: 'Post', plural: 'Posts' },
      fields: {
        title: { type: 'text' },
        slug: { type: 'slug' },
        sections: { type: 'json' },
        excerpt: { type: 'text' },
        featuredImage: { type: 'media' },
        body: { type: 'richText' },
        category: { type: 'text' },
        publishDate: { type: 'date' },
        metaTitle: { type: 'text' },
        metaDescription: { type: 'text' },
      },
    },
  },
} as any

function loadedPost(
  sections: Array<{ id: string; sectionType: string; name: string; unmanaged?: boolean }>,
) {
  return {
    id: 'p1',
    postType: 'blog',
    title: 'Logan',
    slug: 'logan',
    excerpt: '',
    featuredImage: '',
    body: '',
    category: '',
    status: 'DRAFT',
    publishDate: null,
    sections: sections.map((s) => ({ ...s, visible: true, content: {}, settings: {} })),
    seoTitle: '',
    seoDescription: '',
    publishedAt: null,
    updatedAt: null,
  }
}

afterEach(() => {
  fetchPostForEditor.mockReset()
  fetchTemplateForEditor.mockReset()
})

describe('PostSectionEditor schema guard', () => {
  it('refuses to operate when the post-type collection is missing the sections field', async () => {
    const badConfig = {
      collections: { blog: { slug: 'blog', fields: { title: { type: 'text' } } } },
    } as any

    render(
      <PostSectionEditor
        postType="blog"
        documentId="p1"
        config={badConfig}
        onNavigate={() => {}}
        session={{}}
      />,
    )

    expect(await screen.findByText(/missing required field/i)).toBeTruthy()
    // The guard must short-circuit before any network read.
    expect(fetchPostForEditor).not.toHaveBeenCalled()
  })

  it('does not block when no config is provided (embedding/test contexts)', async () => {
    fetchTemplateForEditor.mockRejectedValue(new Error('no template'))
    fetchPostForEditor.mockResolvedValue(
      loadedPost([{ id: 's1', sectionType: 'quote', name: 'Quote' }]),
    )
    render(
      <PostSectionEditor
        postType="blog"
        documentId="p1"
        config={undefined}
        onNavigate={() => {}}
        session={{}}
      />,
    )
    expect(await screen.findByText('Sections')).toBeTruthy()
  })
})

describe('PostSectionEditor unmanaged sections', () => {
  it('shows the externally-managed banner when a post has unmanaged sections', async () => {
    fetchTemplateForEditor.mockRejectedValue(new Error('no template'))
    fetchPostForEditor.mockResolvedValue(
      loadedPost([
        { id: 's1', sectionType: 'quote', name: 'Quote' },
        { id: 's2', sectionType: 'opal-prose-band', name: 'Prose Band', unmanaged: true },
      ]),
    )
    render(
      <PostSectionEditor
        postType="blog"
        documentId="p1"
        config={validConfig}
        onNavigate={() => {}}
        session={{}}
      />,
    )

    await screen.findByText('Sections')
    const banner = screen.getByText(/managed outside the editor/)
    expect(banner.textContent).toContain('opal-prose-band')
  })

  it('shows no banner when every section type is registered', async () => {
    fetchTemplateForEditor.mockRejectedValue(new Error('no template'))
    fetchPostForEditor.mockResolvedValue(
      loadedPost([{ id: 's1', sectionType: 'quote', name: 'Quote' }]),
    )
    render(
      <PostSectionEditor
        postType="blog"
        documentId="p1"
        config={validConfig}
        onNavigate={() => {}}
        session={{}}
      />,
    )

    await screen.findByText('Sections')
    expect(screen.queryByText(/managed outside the editor/)).toBeNull()
  })
})
