"use client"

import { useEffect, useRef, useState } from "react"

const TextPressure = ({
  text = "ardacity",
  fontFamily = "Compressa VF",
  // This font is just an example, you should not use it in commercial projects.
  fontUrl = "https://res.cloudinary.com/dr6lvwubh/raw/upload/v1529908256/CompressaPRO-GX.woff2",

  width = true,
  weight = true,
  italic = true,
  alpha = false,

  flex = true,
  stroke = false,
  scale = false,

  textColor = "auto",
  strokeColor = "#FF0000",
  strokeWidth = 2,
  className = "",

  minFontSize = 24,
}) => {
  const containerRef = useRef(null)
  const titleRef = useRef(null)
  const spansRef = useRef([])

  const mouseRef = useRef({ x: 0, y: 0 })
  const cursorRef = useRef({ x: 0, y: 0 })

  const [fontSize, setFontSize] = useState(minFontSize)
  const [scaleY, setScaleY] = useState(1)
  const [lineHeight, setLineHeight] = useState(1)
  const [detectedTextColor, setDetectedTextColor] = useState(textColor || "#000000")

  const chars = text.split("")

  const dist = (a, b) => {
    const dx = b.x - a.x
    const dy = b.y - a.y
    return Math.sqrt(dx * dx + dy * dy)
  }

  // Detect theme and set text color accordingly
  useEffect(() => {
    if (textColor) {
      setDetectedTextColor(textColor)
      return
    }

    const detectTheme = () => {
      // Check if prefers-color-scheme media query is supported
      if (window.matchMedia) {
        const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches
        setDetectedTextColor(isDarkMode ? "#FFFFFF" : "#000000")
      } else {
        // Fallback to checking background color brightness
        if (containerRef.current) {
          const parent = containerRef.current.parentElement
          if (parent) {
            const bgColor = window.getComputedStyle(parent).backgroundColor
            const rgb = bgColor.match(/\d+/g)
            if (rgb && rgb.length >= 3) {
              // Calculate brightness using the formula: (0.299*R + 0.587*G + 0.114*B)
              const brightness = (0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]) / 255
              setDetectedTextColor(brightness > 0.5 ? "#000000" : "#FFFFFF")
            } else {
              setDetectedTextColor("#000000") // Default to black if can't detect
            }
          }
        }
      }
    }

    detectTheme()
    
    // Listen for theme changes
    const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
    const handleThemeChange = (e) => {
      setDetectedTextColor(e.matches ? "#FFFFFF" : "#000000")
    }
    
    if (darkModeMediaQuery.addEventListener) {
      darkModeMediaQuery.addEventListener("change", handleThemeChange)
    } else if (darkModeMediaQuery.addListener) {
      // For older browsers
      darkModeMediaQuery.addListener(handleThemeChange)
    }
    
    return () => {
      if (darkModeMediaQuery.removeEventListener) {
        darkModeMediaQuery.removeEventListener("change", handleThemeChange)
      } else if (darkModeMediaQuery.removeListener) {
        darkModeMediaQuery.removeListener(handleThemeChange)
      }
    }
  }, [textColor, containerRef.current])

  useEffect(() => {
    const handleMouseMove = (e) => {
      cursorRef.current.x = e.clientX
      cursorRef.current.y = e.clientY
    }
    const handleTouchMove = (e) => {
      const t = e.touches[0]
      cursorRef.current.x = t.clientX
      cursorRef.current.y = t.clientY
    }

    window.addEventListener("mousemove", handleMouseMove)
    window.addEventListener("touchmove", handleTouchMove, { passive: false })

    if (containerRef.current) {
      const { left, top, width, height } = containerRef.current.getBoundingClientRect()
      mouseRef.current.x = left + width / 2
      mouseRef.current.y = top + height / 2
      cursorRef.current.x = mouseRef.current.x
      cursorRef.current.y = mouseRef.current.y
    }

    return () => {
      window.removeEventListener("mousemove", handleMouseMove)
      window.removeEventListener("touchmove", handleTouchMove)
    }
  }, [])

  const setSize = () => {
    if (!containerRef.current || !titleRef.current) return

    const { width: containerW, height: containerH } = containerRef.current.getBoundingClientRect()

    let newFontSize = containerW / (chars.length / 2)
    newFontSize = Math.max(newFontSize, minFontSize)

    setFontSize(newFontSize)
    setScaleY(1)
    setLineHeight(1)

    requestAnimationFrame(() => {
      if (!titleRef.current) return
      const textRect = titleRef.current.getBoundingClientRect()

      if (scale && textRect.height > 0) {
        const yRatio = containerH / textRect.height
        setScaleY(yRatio)
        setLineHeight(yRatio)
      }
    })
  }

  useEffect(() => {
    setSize()
    window.addEventListener("resize", setSize)
    return () => window.removeEventListener("resize", setSize)
  }, [scale, text])

  useEffect(() => {
    let rafId
    const animate = () => {
      mouseRef.current.x += (cursorRef.current.x - mouseRef.current.x) / 15
      mouseRef.current.y += (cursorRef.current.y - mouseRef.current.y) / 15

      if (titleRef.current) {
        const titleRect = titleRef.current.getBoundingClientRect()
        const maxDist = titleRect.width / 2

        spansRef.current.forEach((span) => {
          if (!span) return

          const rect = span.getBoundingClientRect()
          const charCenter = {
            x: rect.x + rect.width / 2,
            y: rect.y + rect.height / 2,
          }

          const d = dist(mouseRef.current, charCenter)

          const getAttr = (distance, minVal, maxVal) => {
            const val = maxVal - Math.abs((maxVal * distance) / maxDist)
            return Math.max(minVal, val + minVal)
          }

          const wdth = width ? Math.floor(getAttr(d, 5, 200)) : 100
          const wght = weight ? Math.floor(getAttr(d, 100, 900)) : 400
          const italVal = italic ? getAttr(d, 0, 1).toFixed(2) : 0
          const alphaVal = alpha ? getAttr(d, 0, 1).toFixed(2) : 1

          span.style.opacity = alphaVal
          span.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`
        })
      }

      rafId = requestAnimationFrame(animate)
    }

    animate()
    return () => cancelAnimationFrame(rafId)
  }, [width, weight, italic, alpha, chars.length])

  return (
    <div ref={containerRef} className="relative w-full h-full overflow-hidden bg-transparent">
      <style>{`
        @font-face {
          font-family: '${fontFamily}';
          src: url('${fontUrl}');
          font-style: normal;
        }
        .stroke span {
          position: relative;
          color: ${detectedTextColor};
        }
        .stroke span::after {
          content: attr(data-char);
          position: absolute;
          left: 0;
          top: 0;
          color: transparent;
          z-index: -1;
          -webkit-text-stroke-width: ${strokeWidth}px;
          -webkit-text-stroke-color: ${strokeColor};
        }
      `}</style>

      <h1
        ref={titleRef}
        className={`text-pressure-title ${className} ${
          flex ? "flex justify-between" : ""
        } ${stroke ? "stroke" : ""} uppercase text-center`}
        style={{
          fontFamily,
          fontSize: fontSize,
          lineHeight,
          transform: `scale(1, ${scaleY})`,
          transformOrigin: "center top",
          margin: 0,
          fontWeight: 100,
          color: stroke ? undefined : detectedTextColor,
        }}
      >
        {chars.map((char, i) => (
          <span key={i} ref={(el) => (spansRef.current[i] = el)} data-char={char} className="inline-block">
            {char}
          </span>
        ))}
      </h1>
    </div>
  )
}

export default TextPressure
