'use client'

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

interface EditorCanvasProps {
  sections: PageSection[]
  selectedId: string | null
  viewport: ViewportId
  onSelect: (id: string) => void
  onAddSection: () => void
  /** Section types rendered as placeholders — shows the "Structure view" notice. */
  structuralTypes?: string[]
  sitePreviewAvailable?: boolean
}

/**
 * The preview canvas. Renders the page at the selected viewport's logical
 * width and scales it down with a CSS transform so wide viewports (1440px,
 * 1920px) fit inside the available canvas column. Scale is recomputed from
 * a ResizeObserver so it stays correct as panels open/close.
 */
export function EditorCanvas({
  sections,
  selectedId,
  viewport,
  onSelect,
  onAddSection,
  structuralTypes = [],
  sitePreviewAvailable = false,
}: EditorCanvasProps) {
  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)
  }, [])

  // Recompute scale + scaled height from the container width.
  useLayoutEffect(() => {
    const container = containerRef.current
    if (!container) return

    const recompute = () => {
      // 48px breathing room so the surface never kisses the column edges.
      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])

  // Scroll the selected section into view within the canvas.
  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">
      {sections.length === 0 ? (
        <EmptyCanvas onAddSection={onAddSection} />
      ) : (
        <>
          <StructureNotice
            structuralTypes={structuralTypes}
            sitePreviewAvailable={sitePreviewAvailable}
          />
          <div
            className="mx-auto"
            style={{ width: vp.width * scale, height: surfaceHeight ?? undefined }}
          >
            {/* `actuate-canvas` is the public hook for consumer brand CSS:
                site styles that should render in this preview scope to
                `.actuate-admin .actuate-canvas` instead of the admin root. */}
            <div
              ref={surfaceRef}
              className="actuate-canvas border-border bg-card origin-top overflow-hidden rounded-xl border shadow-sm"
              style={{
                width: vp.width,
                transform: `scale(${scale})`,
                transformOrigin: 'top left',
              }}
            >
              {sections.map((section) => (
                <SectionRenderer
                  key={section.id}
                  section={section}
                  editable
                  selected={section.id === selectedId}
                  onSelect={onSelect}
                  registerRef={registerRef}
                />
              ))}
            </div>
          </div>
        </>
      )}
    </div>
  )
}

function EmptyCanvas({ onAddSection }: { onAddSection: () => void }) {
  return (
    <div className="mx-auto flex h-full max-w-md flex-col items-center justify-center text-center">
      <div className="bg-card border-border mb-4 flex h-14 w-14 items-center justify-center rounded-full border">
        <LayoutTemplate className="text-muted-foreground h-6 w-6" aria-hidden />
      </div>
      <h2 className="text-foreground text-lg font-medium">This page has no sections yet</h2>
      <p className="text-muted-foreground mt-1 mb-5 text-sm">
        Add your first section to start building the page. You can reorder, hide, and edit sections
        at any time.
      </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>
  )
}
