import { computed, toValue, type CSSProperties, type MaybeRefOrGetter } from 'vue'
import { useProjectStore } from '@/store/modules/project'
import type { Language } from '@/types/language'

type ResolvedLanguageText = {
  text: string
  fontFamily?: string
  fontSize?: string
}

const TOKEN_REGEXP = /#\{([A-Za-z_][A-Za-z0-9_]*)\}/g

const normalizeFontSize = (fontSize?: string | number | null) => {
  const value = String(fontSize ?? '').trim()
  if (!value) return undefined
  return /^\d+(\.\d+)?$/.test(value) ? `${value}px` : value
}

export const useLanguage = () => {
  const projectStore = useProjectStore()

  const currentLanguage = computed(() => projectStore.project?.currentLanguage || 'zh-CN')

  const getLanguageValue = (item: Language) => {
    const values = item.values || []
    if (!values.length) return undefined

    const current = currentLanguage.value
    const currentPrimary = current.split('-')[0]

    return (
      values.find((value) => value.language === current) ||
      values.find((value) => value.language.split('-')[0] === currentPrimary) ||
      values.find((value) => value.value) ||
      values[0]
    )
  }

  const resolveText = (source?: string | null, useTag = false): ResolvedLanguageText => {
    const raw = String(source ?? '')
    let overrideFontFamily: string | undefined
    let overrideFontSize: string | undefined

    const text = raw.replace(TOKEN_REGEXP, (token, key: string) => {
      const language = projectStore.project?.languages?.find((item) => item.key === key)
      if (!language) return token

      const value = getLanguageValue(language)
      if (!value) return token

      if (!overrideFontFamily && value.font) {
        const font = projectStore.project?.resources.fonts?.find((item) => item.id === value.font)
        if (font?.fileName) {
          overrideFontFamily = `'${font.fileName}'`
        }
      }

      if (!overrideFontSize && value.fontSize) {
        overrideFontSize = normalizeFontSize(value.fontSize)
      }

      return useTag
        ? `<span style="font-family: ${overrideFontFamily}; font-size: ${overrideFontSize}">${value.value || ''}</span>`
        : value.value || ''
    })

    return {
      text,
      fontFamily: overrideFontFamily,
      fontSize: overrideFontSize
    }
  }

  const getResolvedFontStyle = (source?: string | null): CSSProperties => {
    const resolved = resolveText(source)
    const style: CSSProperties = {}

    if (resolved.fontFamily) {
      style.fontFamily = resolved.fontFamily
    }
    if (resolved.fontSize) {
      style.fontSize = resolved.fontSize
    }

    return style
  }

  const getTextStyle = (
    baseStyle: MaybeRefOrGetter<CSSProperties | undefined>,
    source: MaybeRefOrGetter<string | null | undefined>
  ) => {
    return computed<CSSProperties>(() => {
      const style = { ...(toValue(baseStyle) || {}) }
      Object.assign(style, getResolvedFontStyle(toValue(source)))

      return style
    })
  }

  return {
    currentLanguage,
    resolveText,
    getResolvedFontStyle,
    getTextStyle
  }
}
