<template>
  <div :style="styleMap?.mainStyle" class="w-full h-full box-border relative">
    <ImageBg :src="styleMap?.mainStyle?.imageSrc" :image-style="styleMap?.mainStyle?.imageStyle" />
    <div
      class="absolute overflow-hidden"
      :style="indicatorStyle"
    >
      <ImageBg
        :src="styleMap?.indicatorStyle?.imageSrc"
        :image-style="styleMap?.indicatorStyle?.imageStyle"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useWidgetStyle } from '../hooks/useWidgetStyle'
import ImageBg from '../ImageBg.vue'
import type { CSSProperties } from 'vue'

const props = defineProps<{
  width?: number
  height?: number
  styles: any
  state?: string
  part?: string
  min: number
  max: number
  value: number
  animationTime: number
  animation: boolean
  mode: 'normal' | 'symmetrical' | 'range'
  startValue: number
}>()

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

const isGradientBackground = (background: unknown) => {
  return typeof background === 'string' && /(?:linear|radial|conic)-gradient\(/.test(background)
}

const getOffset = (value: string | number | undefined, total = 0) => {
  if (typeof value === 'number') return value
  if (!value || value === 'auto') return 0
  if (value.endsWith('%')) {
    return (Number(value.replace('%', '')) / 100) * total
  }
  if (value.endsWith('px')) {
    return Number(value.replace('px', ''))
  }
  return Number(value) || 0
}

const indicatorGradientStyle = computed<CSSProperties>(() => {
  const indicatorBackground = styleMap.value?.indicatorStyle?.background
  if (!isGradientBackground(indicatorBackground)) return {}

  const width = Number(props.width || 0)
  const height = Number(props.height || 0)
  const left = getOffset(otherStyle.value.left, width)
  const top = getOffset(otherStyle.value.top, height)

  return {
    backgroundSize: `${width}px ${height}px`,
    backgroundPosition: `${-left}px ${-top}px`,
    backgroundRepeat: 'no-repeat'
  }
})

const indicatorStyle = computed(() => ({
  ...(styleMap.value?.indicatorStyle || {}),
  ...indicatorGradientStyle.value,
  ...otherStyle.value
}))

const otherStyle = computed(() => {
  const { value = 0, max: e = 100, min: s = 0, width = 0, height = 0, mode, startValue } = props
  // 不管范围值如何，都取实际最小值和最大值
  const min = Math.min(e, s)
  const max = Math.max(e, s)
  const count = max - min
  let percent = ((value - min) / count) * 100
  if (percent > 100) percent = 100
  if (percent < -100) percent = -100
  // 开始值
  const a = ((startValue - min) / count) * 100
  const start = `${a < 0 ? 0 : a > 100 ? 100 : a}%`

  let top = 'auto',
    left = 'auto',
    right = 'auto',
    bottom = 'auto'

  // 横向样式
  if (width >= height) {
    top = '0'
    if (max > min) {
      // 左->右
      left = '0'
      right = `${100 - percent}%`
      if (mode === 'range') {
        left = start
        right = `${100 - percent}%`
      }
      if (mode === 'symmetrical') {
        left = value > 0 ? `${(-min / count) * 100}%` : `${percent}%`
        right = value > 0 ? `${100 - percent}%` : `${(-min / count) * 100}%`
      }
    } else {
      // 右->左
      right = '0'
      left = `${100 - percent}%`
      if (mode === 'range') {
        right = start
        left = `${100 - percent}%`
      }
      if (mode === 'symmetrical') {
        left = value > 0 ? `${(-min / count) * 100}%` : `${percent}%`
        right = value > 0 ? `${100 - percent}%` : `${(-min / count) * 100}%`
      }
    }
  }

  // 纵向样式
  if (width < height) {
    left = '0'
    if (max < min) {
      // 上->下
      top = '0'
      bottom = `${100 - percent}%`
      if (mode === 'range') {
        top = start
        bottom = `${100 - percent}%`
      }
      if (mode === 'symmetrical') {
        top = value > 0 ? `${(-min / count) * 100}%` : `${percent}%`
        bottom = value > 0 ? `${100 - percent}%` : `${(-min / count) * 100}%`
      }
    } else {
      // 下->上
      bottom = '0'
      top = `${100 - percent}%`
      if (mode === 'range') {
        bottom = start
        top = `${100 - percent}%`
      }
      if (mode === 'symmetrical') {
        bottom = value > 0 ? `${(-min / count) * 100}%` : `${percent}%`
        top = value > 0 ? `${100 - percent}%` : `${(-min / count) * 100}%`
      }
    }
  }

  return {
    width: width >= height ? 'auto' : '100%',
    height: width > height ? '100%' : 'auto',
    // 判断开始结束值 设置位置反转
    top: e > s ? top : bottom,
    left: e > s ? left : right,
    right: e > s ? right : left,
    bottom: e > s ? bottom : top
  }
})
</script>
