<template>
  <div
    ref="containerRef"
    :style="{ ...(styleMap?.mainStyle || {}) }"
    class="w-full h-full lvgl_list relative overflow-hidden box-border"
  >
    <ImageBg :src="styleMap?.mainStyle?.imageSrc" :imageStyle="styleMap?.mainStyle?.imageStyle" />
    <div ref="contentRef" class="w-full h-auto z-2">
      <div
        class="flex items-center gap-4px min-h-25px relative"
        v-for="(item, index) in resolvedItems"
        :key="index"
        :style="item.type === 'text' ? styleMap?.itemTextStyle : styleMap?.buttonStyle"
      >
        <ImageBg
          :src="
            item.type === 'text'
              ? styleMap?.itemTextStyle?.imageSrc
              : styleMap?.buttonStyle?.imageSrc
          "
          :imageStyle="
            item.type === 'text'
              ? styleMap?.itemTextStyle?.imageStyle
              : styleMap?.buttonStyle?.imageStyle
          "
        />
        <span v-if="item?.type === 'symbol'" class="z-2">
          <i class="lvgl-icon not-italic whitespace-pre!" v-html="getSymbol(item.img_symbol)"></i>
        </span>
        <div
          v-if="item?.type === 'img'"
          class="z-2"
          :id="item.img_id"
          :style="{
            width: item.img_width + 'px',
            height: item.img_height + 'px',
            position: 'relative'
          }"
        >
          <ImageBg
            :id="item.img_id"
            :image-style="{
              backgroundColor: item.enableCover ? item.img_recolor : '',
              opacity: item.enableAlpha ? item.img_alpha / 255 : 1
            }"
            :image-props="{ width: item.img_width + 'px', height: item.img_height + 'px' }"
          />
        </div>

        <div class="flex-1 flex overflow-hidden" :text-box="index">
          <div
            class="flex-1 z-2"
            :text="index"
            :key="hashKey(item.resolvedText.text) + index"
            :class="item.type === 'text' ? 'whitespace-pre-wrap break-all' : 'whitespace-pre!'"
            :style="getItemTextStyle(item, index)"
          >
            {{ item.resolvedText.text }}
          </div>
        </div>
      </div>
    </div>

    <!-- 滚动条 -->
    <!-- <div
      class="h-scrollbar absolute bottom-6px h-4px"
      :style="{ ...(styleMap?.scrollbarStyle || {}), ...barStyle.hStyle }"
    ></div> -->
    <div
      class="v-scrollbar absolute right-6px w-4px"
      :style="{ ...(styleMap?.scrollbarStyle || {}), ...barStyle.vStyle }"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { useWidgetStyle } from '../hooks/useWidgetStyle'
import { useResizeObserver } from 'vue-hooks-plus'
import { getSymbol } from '@/utils'
import ImageBg from '../ImageBg.vue'
import { useLanguage } from '../hooks/useLanguage'

import type { ListItem } from './data'

const props = defineProps<{
  width: number
  height: number
  styles: any
  part?: string
  state?: string
  items: ListItem[]
}>()
const { resolveText, getResolvedFontStyle } = useLanguage()

const containerRef = ref<HTMLDivElement>()
const contentRef = ref<HTMLDivElement>()
const conHeight = ref(0)
const bodyHeight = ref(0)

useResizeObserver(containerRef, (entries) => {
  const entry = entries[0]
  const { height: _h } = entry.contentRect
  conHeight.value = _h
})
useResizeObserver(contentRef, (entries) => {
  const entry = entries[0]
  const { height: _h } = entry.contentRect
  bodyHeight.value = _h
})

const styleMap = useWidgetStyle({
  widget: 'lv_list',
  props
})

const resolvedItems = computed(() =>
  (props.items || []).map((item) => ({
    ...item,
    resolvedText: resolveText(item?.text)
  }))
)

function hashKey(str: string) {
  let hash = 0
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i)
    hash = (hash << 5) - hash + char
    hash |= 0 // 转换为 32 位整数
  }
  return hash.toString()
}

const barStyle = computed(() => {
  const { styles, part, state } = props

  let style = styles.find((item) => item.part?.name === part && item.part?.state === state)

  if (!style) {
    styles.find((item) => item.part?.name === part && item.part?.state === 'default')
  }

  const gapTop = (style?.border?.width || 0) + (style?.padding?.top || 0)
  const gapBottom = (style?.border?.width || 0) + (style?.padding?.bottom || 0)

  // const viewportHeight = conHeight.value || 0 // 可视区域高度
  // const contentHeight = containerRef.value?.scrollHeight || 0 // 内容总高度
  // const trackHeight = viewportHeight - gapTop - gapBottom // 滚动条轨道高度

  // const thumbHeight = Math.max(
  //   20, // 最小高度（通常浏览器设为20px）
  //   (viewportHeight / contentHeight) * trackHeight
  // )

  return {
    gapTop,
    gapBottom,
    vStyle: {
      display: bodyHeight.value > conHeight.value ? '' : 'none',
      top: `${gapTop}px`,
      height: `${80}px`
    }
  }
})

const getNeedScroll = (record: ListItem, index: number) => {
  if (record.type === 'text') return
  const boxEl = document.querySelector(`[text-box="${index}"]`)
  const textEl = document.querySelector(`[text="${index}"]`)

  return boxEl && textEl && textEl.clientWidth > boxEl.clientWidth
}

const getItemTextStyle = (
  item: ListItem & { resolvedText: { text: string } },
  index: number
) => {
  return {
    ...getResolvedFontStyle(item.text),
    ...(getNeedScroll(item, index) ? { animation: 'h-scroll linear 5s infinite' } : {})
  }
}
</script>

<style lang="less" scoped>
.lvgl_list {
  &::-webkit-scrollbar {
    display: none;
  }
}
</style>
