'use client'

import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { FileText, Plus } from 'lucide-react'
import type { PageSection, PostHeaderConfig } from '../../lib/post-editor-service.js'
import { SectionRenderer, type PostRenderContext } from '../page-editor/sections/index.js'
import { getViewport, type ViewportId } from '../page-editor/viewports.js'
import { PostHeader } from './PostHeader.js'

interface PostEditorCanvasProps {
  sections: PageSection[]
  header: PostHeaderConfig
  context: PostRenderContext
  selectedId: string | null
  viewport: ViewportId
  onSelect: (id: string) => void
  onAddSection: () => void
}

/**
 * Post preview canvas. Mirrors the Page editor canvas (scaled surface that
 * fits the selected viewport) but renders the post header above the section
 * list so the editor shows the full post layout — header regions plus body
 * sections — exactly as it will ship.
 */
export function PostEditorCanvas({
  sections,
  header,
  context,
  selectedId,
  viewport,
  onSelect,
  onAddSection,
}: PostEditorCanvasProps) {
  const vp = getViewport(viewport)
  const containerRef = useRef<HTMLDivElement>(null)
  const surfaceRef = useRef<HTMLDivElement>(null)
  const sectionRefs = useRef<Map<string, HTMLElement>>(new Map())
  const [scale, setScale] = useState(1)
  const [surfaceHeight, setSurfaceHeight] = useState<number | null>(null)

  const registerRef = useCallback((id: string, el: HTMLElement | null) => {
    if (el) sectionRefs.current.set(id, el)
    else sectionRefs.current.delete(id)
  }, [])

  useLayoutEffect(() => {
    const container = containerRef.current
    if (!container) return
    const recompute = () => {
      const available = container.clientWidth - 48
      const next = Math.min(1, available / vp.width)
      setScale(next > 0 ? next : 1)
      if (surfaceRef.current) {
        setSurfaceHeight(surfaceRef.current.offsetHeight * (next > 0 ? next : 1))
      }
    }
    recompute()
    const ro = new ResizeObserver(recompute)
    ro.observe(container)
    if (surfaceRef.current) ro.observe(surfaceRef.current)
    return () => ro.disconnect()
  }, [vp.width, sections, header, context])

  useEffect(() => {
    if (!selectedId) return
    const el = sectionRefs.current.get(selectedId)
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
  }, [selectedId])

  return (
    <div ref={containerRef} className="bg-muted h-full overflow-auto p-6">
      <div
        className="mx-auto"
        style={{ width: vp.width * scale, height: surfaceHeight ?? undefined }}
      >
        <div
          ref={surfaceRef}
          className="border-border origin-top overflow-hidden rounded-xl border bg-white shadow-sm"
          style={{ width: vp.width, transform: `scale(${scale})`, transformOrigin: 'top left' }}
        >
          <PostHeader config={header} context={context} />
          {sections.length === 0 ? (
            <EmptyBody onAddSection={onAddSection} />
          ) : (
            sections.map((section) => (
              <SectionRenderer
                key={section.id}
                section={section}
                context={context}
                editable
                selected={section.id === selectedId}
                onSelect={onSelect}
                registerRef={registerRef}
              />
            ))
          )}
        </div>
      </div>
    </div>
  )
}

function EmptyBody({ onAddSection }: { onAddSection: () => void }) {
  // This block sits inside the fixed-white preview surface, so the neutral
  // greys intentionally match the website-preview palette used by PostHeader
  // and the section renderers (not the admin theme tokens, which flip in dark
  // mode and would lose contrast on the always-white surface). The CTA is the
  // one true admin affordance here, so it uses the brand `primary` token,
  // which carries a guaranteed-contrast foreground in both modes.
  return (
    <div className="flex flex-col items-center justify-center gap-3 border-t border-zinc-100 px-6 py-16 text-center">
      <span className="flex h-12 w-12 items-center justify-center rounded-full bg-zinc-100">
        <FileText className="h-5 w-5 text-zinc-400" aria-hidden />
      </span>
      <p className="text-sm text-zinc-500">
        The header is set by the template. Add body sections to build out this post.
      </p>
      <button
        type="button"
        onClick={onAddSection}
        className="bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors"
      >
        <Plus className="h-4 w-4" aria-hidden />
        Add Section
      </button>
    </div>
  )
}
