"use client"

import { useRef, useEffect } from "react"

interface PixelTextRevealProps {
  lines?: string[]
  className?: string
}

export default function PixelTextReveal({
  lines = ["DAL", "Ecosystem"],
  className,
}: PixelTextRevealProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null)

  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return
    const ctx = canvas.getContext("2d")
    if (!ctx) return
    const drawCtx = ctx

    const dpr = window.devicePixelRatio || 1
    const width = canvas.clientWidth
    const height = canvas.clientHeight
    canvas.width = width * dpr
    canvas.height = height * dpr
    ctx.scale(dpr, dpr)

    const cellSize = 5
    const gap = 1.5
    const step = cellSize + gap
    const cols = Math.floor(width / step)
    const rows = Math.floor(height / step)

    const scale = 6
    const offW = cols * scale
    const offH = rows * scale
    const offscreen = document.createElement("canvas")
    offscreen.width = offW
    offscreen.height = offH
    const offCtx = offscreen.getContext("2d")!
    offCtx.fillStyle = "#000"
    offCtx.fillRect(0, 0, offW, offH)
    offCtx.fillStyle = "#fff"
    offCtx.textAlign = "center"
    offCtx.textBaseline = "middle"

    const primarySize = Math.max(48, Math.floor(offH * 0.38))
    const secondarySize = Math.max(36, Math.floor(offH * 0.26))
    const lineGap = Math.floor(offH * 0.06)

    const totalH = primarySize + (lines.length > 1 ? secondarySize + lineGap : 0)
    const baseY = (offH - totalH) / 2

    lines.forEach((line, i) => {
      const size = i === 0 ? primarySize : secondarySize
      offCtx.font = `${i === 0 ? 900 : 800} ${size}px "Inter", "SF Pro Display", system-ui, sans-serif`
      offCtx.letterSpacing = i === 0 ? "0.05em" : "0.02em"
      const y = i === 0
        ? baseY + primarySize / 2
        : baseY + primarySize + lineGap + secondarySize / 2
      offCtx.fillText(line, offW / 2, y)
    })

    const imgData = offCtx.getImageData(0, 0, offW, offH)
    const textMap: boolean[][] = []
    for (let gy = 0; gy < rows; gy++) {
      textMap[gy] = []
      for (let gx = 0; gx < cols; gx++) {
        let sum = 0
        for (let sy = 0; sy < scale; sy++) {
          for (let sx = 0; sx < scale; sx++) {
            sum += imgData.data[((gy * scale + sy) * offW + gx * scale + sx) * 4]
          }
        }
        textMap[gy][gx] = sum / (scale * scale) > 60
      }
    }

    const centerX = cols / 2
    const centerY = rows / 2

    const cells = Array.from({ length: rows }, (_, y) =>
      Array.from({ length: cols }, (_, x) => {
        const isText = textMap[y][x]
        const dist = Math.hypot(x - centerX, y - centerY)
        return {
          opacity: 0,
          target: isText ? 1.0 : 0.006 + Math.random() * 0.014,
          delay: isText
            ? dist * 12 + Math.random() * 200
            : Math.random() * 600,
          isText,
        }
      })
    )

    let fg = document.documentElement.classList.contains("dark")
      ? "255,255,255"
      : "5,5,5"

    const observer = new MutationObserver(() => {
      fg = document.documentElement.classList.contains("dark")
        ? "255,255,255"
        : "5,5,5"
    })
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"],
    })

    const startTime = performance.now()
    let raf: number

    function draw(now: number) {
      const elapsed = now - startTime
      drawCtx.clearRect(0, 0, width, height)

      for (let y = 0; y < rows; y++) {
        for (let x = 0; x < cols; x++) {
          const c = cells[y][x]
          if (elapsed > c.delay) {
            c.opacity += (c.target - c.opacity) * 0.06
          }
          if (c.opacity < 0.004) continue

          drawCtx.fillStyle = `rgba(${fg},${c.opacity})`
          drawCtx.fillRect(x * step, y * step, cellSize, cellSize)
        }
      }

      raf = requestAnimationFrame(draw)
    }

    raf = requestAnimationFrame(draw)
    return () => {
      cancelAnimationFrame(raf)
      observer.disconnect()
    }
  }, [lines])

  return (
    <canvas
      ref={canvasRef}
      className={className}
      style={{ width: "100%", height: "100%", display: "block" }}
    />
  )
}
