'use client';

import React, { useEffect, useRef, useState } from 'react';
import { motion, useAnimation } from 'framer-motion';
import cardsData from '@/data/cardData.json';
import Image from 'next/image';

const CARD_WIDTH = 100;
const CARD_MARGIN = 10;
const STEP = CARD_WIDTH + CARD_MARGIN;
const VISIBLE_CARDS = 11;
const BUFFER = 3;

type Card = { id: number; img: string; chance: number };

function pickWinnerCardIndex(cards: Card[]): number {
  const totalChance = cards.reduce((sum, card) => sum + card.chance, 0);
  const rand = Math.random() * totalChance;

  let accum = 0;
  for (let i = 0; i < cards.length; i++) {
    accum += cards[i].chance;
    if (rand <= accum) return i;
  }

  return cards.length - 1; // на випадок точності
}

export default function Roulette() {
  const controls = useAnimation();

  const [cards] = useState<Card[]>(cardsData.cards.map((card, i) => ({ ...card, id: i })));

  const [activeIndex, setActiveIndex] = useState<number | null>(null);

  // Подвійний масив для плавної циклічності
  const cardsToRender = [...cards, ...cards];

  const positionRef = useRef(0);
  const speedRef = useRef(0);
  const isRunningRef = useRef(false);
  const containerRef = useRef<HTMLDivElement>(null);

  const totalLength = cards.length * STEP;

  const centerNearestCard = async () => {
    if (!containerRef.current) return;

    const containerCenter = containerRef.current.offsetWidth / 2;
    let pos = positionRef.current % totalLength; // нормалізуємо позицію в межах одного циклу

    if (pos < 0) pos += totalLength; // якщо від'ємна, поправляємо

    // Позиції центрів карток в cardsToRender (подвійний масив)
    const cardCenters = cardsToRender.map((_, i) => i * STEP - pos + CARD_WIDTH / 2);

    let nearestIndex = 0;
    let minDistance = Infinity;

    for (let i = 0; i < cardCenters.length; i++) {
      const dist = Math.abs(cardCenters[i] - containerCenter);
      if (dist < minDistance) {
        minDistance = dist;
        nearestIndex = i;
      }
    }

    const desiredCenter = nearestIndex * STEP;
    const newPosition = desiredCenter - (containerCenter - CARD_WIDTH / 2);

    await controls.start({
      x: -newPosition,
      transition: { type: 'spring', stiffness: 120, damping: 20, mass: 1 },
    });

    positionRef.current = newPosition;

    setActiveIndex(nearestIndex);

    const winnerCard = cardsToRender[nearestIndex % cards.length];
    console.log('Фактична Виграшна картка:', winnerCard);

    setTimeout(() => setActiveIndex(null), 1500);
  };

  const accelerate = () =>
    new Promise<void>(res => {
      let start: number | null = null;
      const anim = (time: number) => {
        if (!start) start = time;
        const elapsed = (time - start) / 1000;
        speedRef.current = elapsed < 3 ? 2500 * (elapsed / 3) : 2500;
        if (elapsed < 3) requestAnimationFrame(anim);
        else res();
      };
      requestAnimationFrame(anim);
    });

  const decelerate = () =>
    new Promise<void>(res => {
      let start: number | null = null;
      const anim = (time: number) => {
        if (!start) start = time;
        const elapsed = (time - start) / 1000;
        speedRef.current = elapsed < 5 ? 1500 * (1 - elapsed / 5) : 0;
        if (elapsed < 5) requestAnimationFrame(anim);
        else {
          isRunningRef.current = false;
          res();
        }
      };
      requestAnimationFrame(anim);
    });

  const startLoop = async () => {
    isRunningRef.current = true;

    const winnerIndex = pickWinnerCardIndex(cards);
    console.log('Обрана виграшна картка:', cards[winnerIndex]);

    await accelerate();
    await new Promise(r => setTimeout(r, 2000));
    await decelerate();
    await centerNearestCard();
    await new Promise(r => setTimeout(r, 5000));
    startLoop();
  };

  useEffect(() => {
    let lastTimestamp: number | null = null;

    const animate = (timestamp: number) => {
      if (!lastTimestamp) lastTimestamp = timestamp;
      const delta = (timestamp - lastTimestamp) / 1000;

      if (isRunningRef.current) {
        positionRef.current += speedRef.current * delta;

        // Якщо позиція пройшла більше половини довжини (одного повного набору карт),
        // безшовно скидати позицію назад
        if (positionRef.current >= totalLength) {
          positionRef.current -= totalLength;
        }

        controls.set({ x: -positionRef.current });
      }

      lastTimestamp = timestamp;
      requestAnimationFrame(animate);
    };

    requestAnimationFrame(animate);
    startLoop();

    return () => {
      isRunningRef.current = false;
    };
  }, [controls]);

  return (
    <div
      ref={containerRef}
      className="roulette-container mx-auto w-[1280px] relative overflow-hidden"
      style={{
        height: 200,
      }}
    >
      <motion.div animate={controls} className="flex mt-[50px] gap-[10px]">
        {cardsToRender.map((card, index) => (
          <motion.div
            key={index}
            animate={{ scale: activeIndex === index ? 1.5 : 1 }}
            transition={{ type: 'spring', stiffness: 200, damping: 15 }}
            className="min-w-[100px] h-[100px] rounded-xl flex items-center justify-center shadow-[0_0_8px_#1c7ed6] select-none"
          >
            <Image
              src={card.img}
              alt={`Card ${card.id}`}
              width={100}
              height={100}
              className="w-[100px] h-[100px]"
            />
          </motion.div>
        ))}
      </motion.div>
    </div>
  );
} це рулетка. в нас є виграшна картка, необхідно щоб при кожному новому обертанні вибирадась вибрана картка і анімація обертання зупинялась на цій картці коли вона буде по центру контейнера