/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useRef, useState } from "react"
import styles from "./ticker.module.scss"

type Coin = {
  id: string
  symbol: string
  name: string
  image: string
  current_price: number
  price_change_percentage_24h: number
}

const COINS = [
  "bitcoin",
  "ethereum",
  "tether",
  "usd-coin",
  "binancecoin",
  "solana",
  "ripple",
  "dogecoin",
  "tron",
  "litecoin",
]

const CryptoTicker: React.FC = () => {
  const [coins, setCoins] = useState<Coin[]>([])
  const [loading, setLoading] = useState(true)
  const trackRef = useRef<HTMLDivElement>(null)
  const requestRef = useRef<number>(0)
  const offsetX = useRef(0)
  const [paused, setPaused] = useState(false)
  const baseSpeed = 0.8 // pixels per frame

  useEffect(() => {
    const fetchCoins = async () => {
      try {
        const res = await fetch(
          `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${COINS.join(
            ","
          )}&order=market_cap_desc&sparkline=false&price_change_percentage=24h`
        )
        const data = await res.json()
        setCoins(data)
      } catch (err) {
        console.error(err)
      } finally {
        setLoading(false)
      }
    }
    fetchCoins()
  }, [])

  /* === Animate horizontal marquee + vertical float === */
  const animate = () => {
    if (!paused && trackRef.current) {
      const width = trackRef.current.scrollWidth / 2
      offsetX.current -= baseSpeed
      if (Math.abs(offsetX.current) >= width) offsetX.current = 0
      trackRef.current.style.transform = `translateX(${offsetX.current}px)`
    }
    requestRef.current = requestAnimationFrame(animate)
  }

  useEffect(() => {
    requestRef.current = requestAnimationFrame(animate)
    return () => {
      if (requestRef.current) cancelAnimationFrame(requestRef.current)
    }
  }, [paused, coins])

  const topGainers = coins
    .slice()
    .sort(
      (a, b) =>
        b.price_change_percentage_24h - a.price_change_percentage_24h
    )
    .slice(0, 3)
    .map((c) => c.id)

  const renderItem = (coin?: Coin, index?: number) => {
    const isGainer = coin && topGainers.includes(coin.id)
    const isUp = coin && coin.price_change_percentage_24h >= 0

    /* Float offset for vertical parallax effect */
    const floatOffset = Math.sin((Date.now() / 1000 + (index ?? 0)) * 2) * 4

    return (
      <div
        className={`${styles.card} ${
          isGainer ? styles.topGainer : ""
        } ${isUp ? styles.upPulse : styles.downPulse}`}
        key={index ?? coin?.id}
        style={{ transform: `translateY(${floatOffset}px)` }}
      >
        <div className={styles.icon}>
          {coin ? (
            <img src={coin.image} alt={coin.name} />
          ) : (
            <div className={styles.skeletonCircle} />
          )}
        </div>

        <div className={styles.meta}>
          <span className={styles.symbol}>
            {coin ? coin.symbol.toUpperCase() : "—"}
          </span>
          <span className={styles.price}>
            {coin ? `$${coin.current_price.toLocaleString()}` : "Loading"}
          </span>
        </div>

        <span
          className={`${styles.change} ${
            isUp ? styles.up : styles.down
          }`}
        >
          {coin
            ? `${coin.price_change_percentage_24h.toFixed(2)}%`
            : "—"}
        </span>
      </div>
    )
  }

  return (
    <section className={styles.tickerWrapper}>
      <div className={styles.fadeLeft} />
      <div className={styles.fadeRight} />

      <div
        className={styles.track}
        onMouseEnter={() => setPaused(true)}
        onMouseLeave={() => setPaused(false)}
      >
        <div className={styles.marquee} ref={trackRef}>
          {(loading ? Array(10).fill(null) : coins).map(renderItem)}
          {(loading ? Array(10).fill(null) : coins).map(renderItem)}
        </div>
      </div>
    </section>
  )
}

export default CryptoTicker
