<script lang="ts">
/** 根据 Section 类型返回占位高度，防止 CLS 布局偏移 */
</script>

<script setup lang="ts">
import { computed, ref } from 'vue'

import { useLazyRender } from '../composables/useLazyRender'
import { useRegistry } from '../composables/useRegistry'
import FallbackSection from './FallbackSection.vue'
import SectionErrorBoundary from './SectionErrorBoundary.vue'
import SectionWrapper from './SectionWrapper.vue'

const props = defineProps<{
  /** Block 实例映射 */
  blocks: Record<string, { type: string, settings: Record<string, unknown> }>
  /** Block 排序 */
  blockOrder: string[]
  /** 编辑器模式 */
  editorMode?: boolean
  /** 是否选中 */
  isSelected?: boolean
  /** 产品标识，用于解析产品级 Section 组件覆盖 */
  productCode?: string
  /** IntersectionObserver rootMargin，控制提前加载距离 */
  rootMargin?: string
  /** Section ID */
  sectionId: string
  /** Section 类型 */
  sectionType: string
  /** Section 设置 */
  settings: Record<string, unknown>
}>()

const emit = defineEmits<{
  (e: 'sectionClick', sectionId: string): void
  (e: 'settingUpdate', sectionId: string, key: string, value: unknown): void
  (e: 'blockSettingUpdate', sectionId: string, blockId: string, key: string, value: unknown): void
  (e: 'inlineEditStart', sectionId: string, key: string): void
  (e: 'inlineEditEnd'): void
  (e: 'inlineEditUndoRedo', action: 'redo' | 'undo'): void
}>()

function getPlaceholderHeight(type: string): string {
  const heights: Record<string, string> = {
    'hero-banner': '400px',
    'feature-grid': '300px',
    'text-with-image': '250px',
    'testimonials': '280px',
    'faq': '200px',
    'cta': '180px',
    'rich-text': '200px',
    'spacer': '40px',
  }
  return heights[type] ?? '200px'
}

const containerRef = ref<HTMLElement | null>(null)
const { isVisible } = useLazyRender(containerRef, {
  rootMargin: props.rootMargin ?? '200px',
  // SSR 输出完整 HTML，客户端 hydration 后再由 Observer 接管
  ssrEager: true,
})

const registry = useRegistry()

// 解析注册表中的组件，未注册则降级到 FallbackSection
const resolvedComponent = computed(
  () => registry.resolve(props.sectionType, props.productCode) ?? FallbackSection,
)
</script>

<template>
<div ref="containerRef">
    <template v-if="isVisible || isSelected">
      <SectionErrorBoundary :section-id="sectionId" :section-type="sectionType">
        <SectionWrapper
          :section-id="sectionId"
          :section-type="sectionType"
          :editor-mode="editorMode"
          :is-selected="isSelected"
          :settings="settings"
          @click="emit('sectionClick', sectionId)"
        >
          <component
            :is="resolvedComponent"
            :settings="settings"
            :blocks="blocks"
            :block-order="blockOrder"
            :editor-mode="editorMode"
            @update:setting="
              (key: string, value: unknown) => emit('settingUpdate', sectionId, key, value)
            "
            @update:block-setting="
              (blockId: string, key: string, value: unknown) =>
                emit('blockSettingUpdate', sectionId, blockId, key, value)
            "
            @inline-edit-start="(key: string) => emit('inlineEditStart', sectionId, key)"
            @inline-edit-end="emit('inlineEditEnd')"
            @undo-redo="(action: 'redo' | 'undo') => emit('inlineEditUndoRedo', action)"
          />
        </SectionWrapper>
      </SectionErrorBoundary>
    </template>

    <!-- CLS 占位：未加载时保持最小高度，防止内容加载后布局偏移 -->
    <div
      v-else
      class="section-lazy-placeholder"
      :data-section-type="sectionType"
      :style="{ minHeight: getPlaceholderHeight(sectionType) }"
    />
  </div>
</template>

<style scoped>
.section-lazy-placeholder{animation:shimmer 1.5s infinite;background:linear-gradient(90deg,#f3f4f6 25%,#e5e7eb 50%,#f3f4f6 75%);background-size:200% 100%;border-radius:4px}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}
</style>
