<script setup lang="ts">
import type { CSSProperties } from 'vue';
import type { SectionBlock, SectionLayout } from '~/types/site';
import { resolveAssetUrl } from '~/utils/resolveAssetUrl';
import LayoutHeroSplit from './layouts/LayoutHeroSplit.vue';
import LayoutFullBanner from './layouts/LayoutFullBanner.vue';
import LayoutFeatureGrid from './layouts/LayoutFeatureGrid.vue';
import LayoutSplitContent from './layouts/LayoutSplitContent.vue';
import LayoutGallery from './layouts/LayoutGallery.vue';
import LayoutStats from './layouts/LayoutStats.vue';
import LayoutTitleMedia from './layouts/LayoutTitleMedia.vue';
import LayoutMosaic from './layouts/LayoutMosaic.vue';
import LayoutMarquee from './layouts/LayoutMarquee.vue';
import LayoutSpecTable from './layouts/LayoutSpecTable.vue';

const props = defineProps<{ section: SectionBlock }>();

// 布局类型 -> 组件映射
const layoutComponents: Record<SectionLayout, unknown> = {
  hero_split: LayoutHeroSplit,
  full_banner: LayoutFullBanner,
  feature_grid: LayoutFeatureGrid,
  split_content: LayoutSplitContent,
  gallery: LayoutGallery,
  stats: LayoutStats,
  title_media: LayoutTitleMedia,
  mosaic: LayoutMosaic,
  marquee: LayoutMarquee,
  spec_table: LayoutSpecTable
};

const layoutComponent = computed(() => layoutComponents[props.section.layout] ?? null);

const isDark = computed(() => props.section.theme === 'dark');

// 背景样式
const bgStyle = computed(() => {
  const { bg_type, bg_value } = props.section;
  if (bg_type === 'color' && bg_value) {
    return { backgroundColor: bg_value };
  }
  // 渐变：bg_value 为完整 CSS 渐变函数（如 linear-gradient(...)）；仅在形如渐变函数时应用，避免把普通字符串当背景
  if (bg_type === 'gradient' && bg_value && bg_value.includes('gradient(')) {
    return { background: bg_value };
  }
  return {};
});

const hasBgImage = computed(() => props.section.bg_type === 'image' && !!props.section.bg_value);
const hasBgVideo = computed(() => props.section.bg_type === 'video' && !!props.section.bg_value);
// 背景图/视频资源地址（支持 /uploads/... 相对路径）
const bgMediaUrl = computed(() => resolveAssetUrl(props.section.bg_value));

// 区块宽度百分比（config.width_percent）：占视口宽度比例并居中，
// 未配置或 100 时全宽；md 以下始终全宽（见模板 class）
// 内容区最大宽度（config.container_width）：'1200'（默认）/ '1400' / '1600' / 'full'，
// 通过 --sec-cw 下发给 section-container shortcut（见 uno.config.ts）
// 区块圆角（config.border_radius）：单位 px，未配置或 0 为直角（默认）；
// 外层 section 已有 overflow-hidden，背景图/视频自动被圆角裁剪
const borderRadius = computed(() => {
  const r = Number(props.section.config?.border_radius);
  return r > 0 ? `${r}px` : '0px';
});

// 区块垂直内边距（config.padding_y）：单位 px，未设置时不下发变量（各布局用 var 回退自身默认值），0 = 完全贴边
const paddingY = computed(() => {
  const v = props.section.config?.padding_y;
  return typeof v === 'number' && v >= 0 ? `${v}px` : '';
});

// 区块上下外边距（config.margin_y）：单位 px，区块与相邻区块的间隙（露出页面背景）；
// 未设置或 0 = 紧贴相邻区块（默认，全宽无缝拼接设计）
const marginY = computed(() => {
  const v = props.section.config?.margin_y;
  return typeof v === 'number' && v > 0 ? `${v}px` : '';
});

// 标题字号（config.title_font_size）：桌面端 px，未设置时不下发变量（main.css 的 section h2 规则兜底 36px）；
// 移动端按桌面值 62.5% 等比缩小（--sec-title-fs-m）
const titleFontSize = computed(() => {
  const v = props.section.config?.title_font_size;
  if (typeof v !== 'number' || v <= 0) return null;
  return { desktop: `${v}px`, mobile: `${Math.round(v * 0.625)}px` };
});

const sectionStyleVars = computed<CSSProperties>(() => {
  const w = Number(props.section.config?.width_percent);
  const cw = props.section.config?.container_width;
  const containerWidth = cw === 'full' ? '100%' : Number(cw) > 0 ? `${cw}px` : '1200px';
  return {
    '--sec-w': w > 0 && w < 100 ? `${w}%` : '100%',
    '--sec-cw': containerWidth,
    borderRadius: borderRadius.value,
    ...(paddingY.value ? { '--sec-py': paddingY.value } : {}),
    ...(marginY.value ? { marginTop: marginY.value, marginBottom: marginY.value } : {}),
    ...(titleFontSize.value ? { '--sec-title-fs': titleFontSize.value.desktop, '--sec-title-fs-m': titleFontSize.value.mobile } : {})
  } as CSSProperties;
});

// 背景图/视频显示模式（config.bg_fit）：cover 铺满（默认）/ contain 完整显示 / auto 原尺寸
const bgFit = computed<'cover' | 'contain' | 'auto'>(() => {
  const f = props.section.config?.bg_fit;
  return f === 'contain' || f === 'auto' ? f : 'cover';
});

const bgImageClass = computed(() =>
  ({
    cover: 'absolute inset-0 bg-cover bg-center',
    contain: 'absolute inset-0 bg-contain bg-center bg-no-repeat',
    auto: 'absolute inset-0 bg-auto bg-center bg-no-repeat'
  })[bgFit.value]
);

const bgVideoClass = computed(() =>
  ({
    cover: 'absolute inset-0 w-full h-full object-cover',
    contain: 'absolute inset-0 w-full h-full object-contain',
    auto: 'absolute inset-0 w-full h-full object-none'
  })[bgFit.value]
);
</script>

<template>
  <section
    class="relative overflow-hidden md:w-[var(--sec-w)] md:mx-auto"
    :class="isDark ? 'bg-gray-950 text-white' : 'bg-white text-gray-900 dark:bg-dark-900 dark:text-white'"
    :style="[bgStyle, sectionStyleVars]"
  >
    <!-- 背景图：显示模式由 config.bg_fit 控制（默认铺满） -->
    <div
      v-if="hasBgImage"
      :class="bgImageClass"
      :style="{ backgroundImage: `url(${bgMediaUrl})` }"
    />

    <!-- 背景视频：显示模式由 config.bg_fit 控制（默认铺满） -->
    <video
      v-if="hasBgVideo"
      :src="bgMediaUrl"
      :class="bgVideoClass"
      autoplay
      muted
      loop
      playsinline
    />

    <!-- 布局内容 -->
    <div class="relative z-10">
      <component :is="layoutComponent" v-if="layoutComponent" :section="section" />
    </div>
  </section>
</template>
