import type { CSSProperties } from "vue"
import type { PptxElement, PptxFill } from "./pptxTypes"
import { getBorderInfo, getElementBorderRadius, getNumber } from "./pptxUtils"
import { hasImageFill, isAudioElement, isImageElement, isShapeElement, isVideoElement } from "./pptxPredicates"

export function getSlideBackground(fill?: PptxFill) {
  if (!fill || !fill.type) return "#fff"
  if (fill.type === "color") return String(fill.value || "#fff")
  if (fill.type === "gradient") {
    const colors = Array.isArray(fill.value?.colors) ? fill.value.colors : []
    const rot = getNumber(fill.value?.rot)
    const path = String(fill.value?.path || "rect")
    const stops = colors
      .map((c: any) => {
        const pos = String(c?.pos ?? "")
        const color = String(c?.color ?? "")
        if (!color) return ""
        return pos ? `${color} ${pos}` : color
      })
      .filter(Boolean)
      .join(", ")
    if (!stops) return "#fff"
    if (path === "rect") {
      const angle = (90 - rot + 360) % 360
      return `linear-gradient(${angle}deg, ${stops})`
    }
    return `radial-gradient(circle, ${stops})`
  }
  if (fill.type === "image") {
    const src = String(fill.value?.picBase64 || fill.value?.src || "")
    if (!src) return "#fff"
    return `center / cover no-repeat url(${src})`
  }
  return "#fff"
}

export function getElementZIndex(el: PptxElement, elementIndex: number) {
  const base = getNumber(el.order) || elementIndex
  const source = (el as any)?.__source
  const offset = source === "slide" ? 100000 : 0
  return base + offset
}

export function getElementShadowFilter(el: PptxElement) {
  const shadow = (el as any)?.shadow
  if (!shadow || typeof shadow !== "object") return undefined
  const h = getNumber((shadow as any).h)
  const v = getNumber((shadow as any).v)
  const blur = Math.max(0, getNumber((shadow as any).blur))
  const color = String((shadow as any).color || "").trim()
  if (!color || (!h && !v && !blur)) return undefined
  return `drop-shadow(${h}px ${v}px ${blur}px ${color})`
}

export function getElementBorderCss(el: PptxElement) {
  if (isShapeElement(el)) return undefined
  const border = getBorderInfo(el)
  if (!border.color || !border.width) return undefined
  return `${border.width}px solid ${border.color}`
}

export function getElementBackground(el: PptxElement) {
  if (isShapeElement(el) || hasImageFill(el) || isImageElement(el) || isVideoElement(el) || isAudioElement(el)) return undefined

  if (typeof el.fill === "string") {
    const raw = el.fill.trim()
    return raw ? raw : undefined
  }

  const fill = typeof el.fill === "object" && el.fill ? (el.fill as PptxFill) : null
  if (!fill || !fill.type) return undefined
  if (fill.type === "color") return String(fill.value || "") || undefined
  if (fill.type === "gradient") {
    const colors = Array.isArray(fill.value?.colors) ? fill.value.colors : []
    const rot = getNumber(fill.value?.rot)
    const path = String(fill.value?.path || "rect")
    const stops = colors
      .map((c: any) => {
        const pos = String(c?.pos ?? "")
        const color = String(c?.color ?? "")
        if (!color) return ""
        return pos ? `${color} ${pos}` : color
      })
      .filter(Boolean)
      .join(", ")
    if (!stops) return undefined
    if (path === "rect") {
      const angle = (90 - rot + 360) % 360
      return `linear-gradient(${angle}deg, ${stops})`
    }
    return `radial-gradient(circle, ${stops})`
  }
  return undefined
}

export function getElementStyle(el: PptxElement, elementIndex: number) {
  const left = getNumber(el.left)
  const top = getNumber(el.top)
  const width = Math.max(0, getNumber(el.width))
  const height = Math.max(0, getNumber(el.height))

  const rotate = getNumber(el.rotate)
  const flipH = !!el.isFlipH
  const flipV = !!el.isFlipV
  const zIndex = getElementZIndex(el, elementIndex)
  const opacity = el.opacity == null ? 1 : Math.max(0, Math.min(1, getNumber(el.opacity)))

  const transforms: string[] = []
  if (rotate) transforms.push(`rotate(${rotate}deg)`)
  if (flipH) transforms.push(`scaleX(-1)`)
  if (flipV) transforms.push(`scaleY(-1)`)

  const background = getElementBackground(el)
  const border = getElementBorderCss(el)
  const radius = getElementBorderRadius(el)
  const shadowFilter = getElementShadowFilter(el)

  return {
    position: "absolute" as const,
    left: `${left}px`,
    top: `${top}px`,
    width: `${width}px`,
    height: `${height}px`,
    zIndex,
    opacity,
    background,
    border,
    borderRadius: radius,
    filter: shadowFilter,
    transformOrigin: "center center",
    transform: transforms.length ? transforms.join(" ") : undefined,
  } as CSSProperties
}

