import type { CSSProperties } from "vue"
import type { PptxElement, PptxFill } from "./pptxTypes"
import { getElementBorderRadius, getNumber } from "./pptxUtils"

function normalizeRatio(n: unknown) {
  const v = getNumber(n)
  if (!v) return 0
  if (v > 1) return Math.max(0, Math.min(1, v / 100))
  return Math.max(0, Math.min(1, v))
}

export function getImageCropRect(el: PptxElement) {
  const rect = (el as any)?.rect
  const crop = (el as any)?.crop
  const raw = rect && typeof rect === "object" ? rect : crop && typeof crop === "object" ? crop : null
  if (!raw) return null

  const t = normalizeRatio(raw.t)
  const b = normalizeRatio(raw.b)
  const l = normalizeRatio(raw.l)
  const r = normalizeRatio(raw.r)
  if (!t && !b && !l && !r) return null

  const safeL = Math.max(0, Math.min(0.9, l))
  const safeR = Math.max(0, Math.min(0.9, r))
  const safeT = Math.max(0, Math.min(0.9, t))
  const safeB = Math.max(0, Math.min(0.9, b))
  if (safeL + safeR >= 0.98 || safeT + safeB >= 0.98) return null
  return { t: safeT, b: safeB, l: safeL, r: safeR }
}

function getImageGeom(el: PptxElement) {
  const g = String((el as any)?.geom || (el as any)?.shapeType || "").toLowerCase()
  return g
}

export function getImageWrapStyle(el: PptxElement) {
  const geom = getImageGeom(el)
  const isEllipse = geom === "ellipse" || geom === "circle"
  const borderRadius = isEllipse ? "50%" : getElementBorderRadius(el)
  return {
    width: "100%",
    height: "100%",
    position: "relative" as const,
    overflow: "hidden",
    borderRadius,
  } as CSSProperties
}

function normalizeFilterFactor(value: unknown, base = 1) {
  if (value == null) return base
  const n = getNumber(value)
  if (!n) return base
  const v = n > 10 ? n / 100 : n
  return Math.max(0, Math.min(3, v))
}

function buildImageFilter(el: PptxElement) {
  const filters = (el as any)?.filters
  if (!filters || typeof filters !== "object") return undefined

  const brightness = normalizeFilterFactor(filters.brightness, 1)
  const contrast = normalizeFilterFactor(filters.contrast, 1)
  const saturation = normalizeFilterFactor(filters.saturation, 1)
  const colorTemperature = getNumber(filters.colorTemperature)

  const parts: string[] = []
  if (brightness !== 1) parts.push(`brightness(${brightness})`)
  if (contrast !== 1) parts.push(`contrast(${contrast})`)
  if (saturation !== 1) parts.push(`saturate(${saturation})`)
  if (colorTemperature) {
    const t = Math.max(-100, Math.min(100, colorTemperature))
    const hue = t * 0.6
    const sepia = Math.min(1, Math.abs(t) / 200)
    parts.push(`hue-rotate(${hue}deg)`)
    if (t > 0 && sepia) parts.push(`sepia(${sepia})`)
  }
  return parts.length ? parts.join(" ") : undefined
}

export function getImageStyle(el: PptxElement) {
  const crop = getImageCropRect(el)
  const filter = buildImageFilter(el)

  if (!crop) {
    return {
      width: "100%",
      height: "100%",
      objectFit: "fill",
      filter,
      display: "block",
    } as CSSProperties
  }

  const scaleX = 1 / (1 - crop.l - crop.r)
  const scaleY = 1 / (1 - crop.t - crop.b)
  const translateX = -crop.l * 100
  const translateY = -crop.t * 100

  return {
    width: "100%",
    height: "100%",
    objectFit: "fill",
    display: "block",
    transformOrigin: "top left",
    transform: `translate(${translateX}%, ${translateY}%) scale(${scaleX}, ${scaleY})`,
    filter,
  } as CSSProperties
}

export function getMediaSrc(el: PptxElement) {
  const fillObj = typeof el.fill === "object" && el.fill ? (el.fill as PptxFill) : null
  const candidates = [
    (el as any).src,
    (el as any).url,
    (el as any).picBase64,
    (el as any).mediaBase64,
    (el as any).base64,
    (el as any).blob,
    (el as any).blobUrl,
    (el as any).value?.picBase64,
    (el as any).value?.src,
    fillObj?.value?.picBase64,
    fillObj?.value?.src,
  ]
  const found = candidates.find((v) => typeof v === "string" && v.trim())
  return found ? String(found) : ""
}
