<template>
  <div
    ref="boxRef"
    :style="styleMap?.mainStyle"
    class="w-full h-full flex overflow-hidden box-border relative"
    :class="nowrap ? 'whitespace-nowrap' : 'break-all'"
  >
    <ImageBg
      v-if="styleMap?.mainStyle?.imageSrc"
      :src="styleMap?.mainStyle?.imageSrc"
      :imageStyle="styleMap?.mainStyle?.imageStyle"
    />
    <span ref="txtRef" class="w-full overflow-hidden whitespace-pre! z-1" :style="contentStyle">{{
      getContent
    }}</span>
    <div
      v-if="part === 'scrollbar' || showHScroll"
      class="h-scrollbar absolute bottom-6px left-6px h-4px w-20%"
      :style="styleMap?.scrollbarStyle"
    ></div>
    <div
      v-if="part === 'scrollbar' || showVScroll"
      class="v-scrollbar absolute right-6px top-6px w-4px h-20%"
      :style="styleMap?.scrollbarStyle"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue'
import { useWidgetStyle } from '../hooks/useWidgetStyle'
import ImageBg from '../ImageBg.vue'
import { useLanguage } from '../hooks/useLanguage'

const props = defineProps<{
  width: number
  height: number
  styles: any
  part?: string
  state?: string
  text: string
  placeholder: string
  maxLength: number
  allowString: string
  passwordMode: boolean
  passwordReplaceText: string
  nowrap: boolean
}>()

const boxRef = ref<HTMLDivElement | null>()
const txtRef = ref<HTMLSpanElement | null>()
const showVScroll = ref(false)
const showHScroll = ref(false)
const { resolveText, getTextStyle } = useLanguage()

const resolvedText = computed(() => resolveText(props.text))
const resolvedPlaceholder = computed(() => resolveText(props.placeholder))

const handleResize = async () => {
  await nextTick()
  const boxHeight = boxRef.value?.offsetHeight || 0
  const boxWidth = boxRef.value?.offsetWidth || 0
  const txtHeight = txtRef.value?.offsetHeight || 0
  const txtWidth = txtRef.value?.offsetWidth || 0

  showVScroll.value = txtHeight > boxHeight
  showHScroll.value = txtWidth > boxWidth
}

// 文本内容
const getContent = computed(() => {
  const { passwordMode, passwordReplaceText } = props
  const text = resolvedText.value.text
  const placeholder = resolvedPlaceholder.value.text

  return passwordMode ? (passwordReplaceText || '*').repeat(text.length) : text || placeholder
})

watch(() => [props.width, props.height, getContent.value, props.nowrap], handleResize, {
  immediate: true
})

const contentSource = computed(() => (resolvedText.value.text ? props.text : props.placeholder))
const textStyle = getTextStyle(() => undefined, contentSource)
const contentStyle = computed(() => ({
  ...textStyle.value,
  color: !resolvedText.value.text ? '#ccc' : '',
  height: 'fit-content',
  display: props.nowrap ? 'table' : 'inline-block'
}))

const styleMap = useWidgetStyle({
  widget: 'lv_textarea',
  props
})
</script>

<style scoped></style>
