<script setup lang="ts">
import type { SectionsData } from '@vigilkids/section-core'

import { computed } from 'vue'

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

const props = defineProps<{
  /** 是否处于编辑器预览模式（启用 data-* 属性和高亮） */
  editorMode?: boolean
  /** 当前选中的 Section ID（编辑器模式下高亮） */
  selectedSectionId?: string | null
  /** 是否全选所有 Section（编辑器 Ctrl+A） */
  allSectionsSelected?: boolean
  /** Sections 数据（与 content_json 结构一致） */
  sectionsData: SectionsData
  /** 产品标识，用于解析产品级 Section 组件覆盖 */
  productCode?: string
}>()

const emit = defineEmits<{
  (e: 'section-click', sectionId: string): void
  (e: 'setting-update', sectionId: string, key: string, value: unknown): void
  (e: 'block-setting-update', sectionId: string, blockId: string, key: string, value: unknown): void
  (e: 'inline-edit-start', sectionId: string, key: string): void
  (e: 'inline-edit-end'): void
  (e: 'inline-edit-undo-redo', action: 'redo' | 'undo'): void
}>()

const registry = useRegistry()

const orderedSections = computed(() =>
  props.sectionsData.section_order
    .filter(id => id in props.sectionsData.sections)
    .map(id => ({
      id,
      section: props.sectionsData.sections[id]!,
    }))
    .filter(item => !item.section.disabled),
)
</script>

<template>
  <main class="section-renderer">
    <template v-for="(item, index) in orderedSections" :key="item.id">
      <!-- 前 2 个 Section 直接渲染，保障 LCP/FCP -->
      <SectionErrorBoundary
        v-if="index < 2"
        :section-id="item.id"
        :section-type="item.section.type"
      >
        <SectionWrapper
          :section-id="item.id"
          :section-type="item.section.type"
          :editor-mode="editorMode"
          :is-selected="allSectionsSelected || selectedSectionId === item.id"
          :settings="item.section.settings"
          @click="emit('section-click', item.id)"
        >
          <component
            :is="registry.resolve(item.section.type, productCode) ?? FallbackSection"
            :settings="item.section.settings"
            :blocks="item.section.blocks"
            :block-order="item.section.block_order"
            :editor-mode="editorMode"
            @update:setting="
              (key: string, value: unknown) => emit('setting-update', item.id, key, value)
            "
            @update:block-setting="
              (blockId: string, key: string, value: unknown) =>
                emit('block-setting-update', item.id, blockId, key, value)
            "
            @inline-edit-start="(key: string) => emit('inline-edit-start', item.id, key)"
            @inline-edit-end="emit('inline-edit-end')"
            @undo-redo="(action: 'redo' | 'undo') => emit('inline-edit-undo-redo', action)"
          />
        </SectionWrapper>
      </SectionErrorBoundary>

      <!-- 剩余 Section 通过 IntersectionObserver 懒加载 -->
      <LazySection
        v-else
        :section-id="item.id"
        :section-type="item.section.type"
        :settings="item.section.settings"
        :blocks="item.section.blocks"
        :block-order="item.section.block_order"
        :editor-mode="editorMode"
        :is-selected="allSectionsSelected || selectedSectionId === item.id"
        :product-code="productCode"
        @section-click="emit('section-click', $event)"
        @setting-update="
          (sectionId: string, key: string, value: unknown) =>
            emit('setting-update', sectionId, key, value)
        "
        @block-setting-update="
          (sectionId: string, blockId: string, key: string, value: unknown) =>
            emit('block-setting-update', sectionId, blockId, key, value)
        "
        @inline-edit-start="
          (sectionId: string, key: string) => emit('inline-edit-start', sectionId, key)
        "
        @inline-edit-end="emit('inline-edit-end')"
        @inline-edit-undo-redo="(action: 'redo' | 'undo') => emit('inline-edit-undo-redo', action)"
      />
    </template>
  </main>
</template>
