'use client';

import React, { useState, useEffect, useRef } from 'react';
import { RotateCw, Trophy, Trash2, RefreshCw, Shuffle, Sparkles, Gift } from 'lucide-react';
import { useVoucherRows } from '@/services/queries/vouchers';
import { Voucher, VoucherRow } from '@/types/services/voucher';
import { toast } from 'react-toastify';

interface SpinRow {
  id: string;
  rowNumber: number;
  vouchers: Voucher[];
  displayVouchers: Voucher[];
  isSpinning: boolean;
  isShuffling: boolean;
  winner: Voucher | null;
  wheelRef: React.RefObject<HTMLDivElement>;
  selectedWinner: Voucher | null;
}

interface WinnerHistory {
  rowNumber: number;
  winner: Voucher;
  timestamp: Date;
}

const RandomDrawApp: React.FC = () => {
  const [spinRows, setSpinRows] = useState<SpinRow[]>([]);
  const [numberOfRows, setNumberOfRows] = useState<number>(5);
  const [winnersHistory, setWinnersHistory] = useState<WinnerHistory[]>([]);
  const [isRevealingWinners, setIsRevealingWinners] = useState<boolean>(false);
  const [revealedWinners, setRevealedWinners] = useState<Set<number>>(new Set());
  const [isSequentialSpinning, setIsSequentialSpinning] = useState<boolean>(false);
  const [currentSpinningRow, setCurrentSpinningRow] = useState<number | null>(null);
  const [selectedPrize, setSelectedPrize] = useState<number>(1); // 1 for Emas 0.25 Gram, 2 for Emas 3 Gram
  const audioContextRef = useRef<AudioContext | null>(null);
  const tickIntervalRefs = useRef<Map<string, NodeJS.Timeout>>(new Map());
  const shuffleIntervalRefs = useRef<Map<string, NodeJS.Timeout>>(new Map());

  // Use React Query hook for fetching voucher data - disabled by default
  const { data: voucherData, isLoading: isLoadingData, refetch: refetchVouchers, error: fetchError } = useVoucherRows({ 
    rows: numberOfRows, 
    winner_number: selectedPrize 
  }, {
    enabled: false // Disable automatic fetching - only fetch when Load Data is clicked
  });

  // Initialize Audio Context
  useEffect(() => {
    const initAudio = () => {
      if (!audioContextRef.current) {
        audioContextRef.current = new (window.AudioContext || (window as any).webkitAudioContext)();
      }
    };

    document.addEventListener('click', initAudio, { once: true });

    return () => {
      document.removeEventListener('click', initAudio);
      tickIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
      shuffleIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
    };
  }, []);

  // Create tick sound effect
  const playTickSound = () => {
    if (!audioContextRef.current) return;

    const ctx = audioContextRef.current;
    const oscillator = ctx.createOscillator();
    const gainNode = ctx.createGain();

    oscillator.connect(gainNode);
    gainNode.connect(ctx.destination);

    oscillator.frequency.setValueAtTime(800, ctx.currentTime);
    oscillator.frequency.exponentialRampToValueAtTime(200, ctx.currentTime + 0.05);

    gainNode.gain.setValueAtTime(0, ctx.currentTime);
    gainNode.gain.linearRampToValueAtTime(0.1, ctx.currentTime + 0.01);
    gainNode.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.05);

    oscillator.start(ctx.currentTime);
    oscillator.stop(ctx.currentTime + 0.05);
  };

  // Create drum roll sound
  const playDrumRoll = () => {
    if (!audioContextRef.current) return;

    const ctx = audioContextRef.current;
    const oscillator = ctx.createOscillator();
    const gainNode = ctx.createGain();
    const noiseNode = ctx.createBufferSource();

    // Create noise buffer for snare-like sound
    const bufferSize = ctx.sampleRate * 0.05;
    const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
    const data = buffer.getChannelData(0);
    for (let i = 0; i < bufferSize; i++) {
      data[i] = Math.random() * 2 - 1;
    }
    noiseNode.buffer = buffer;

    oscillator.connect(gainNode);
    noiseNode.connect(gainNode);
    gainNode.connect(ctx.destination);

    oscillator.frequency.setValueAtTime(200, ctx.currentTime);
    gainNode.gain.setValueAtTime(0.05, ctx.currentTime);
    gainNode.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.1);

    oscillator.start(ctx.currentTime);
    oscillator.stop(ctx.currentTime + 0.1);
    noiseNode.start(ctx.currentTime);
  };

  // Create winner sound
  const playWinnerSound = () => {
    if (!audioContextRef.current) return;

    const ctx = audioContextRef.current;
    const notes = [523.25, 659.25, 783.99, 1046.5]; // C, E, G, C (higher octave)

    notes.forEach((freq, index) => {
      const oscillator = ctx.createOscillator();
      const gainNode = ctx.createGain();

      oscillator.connect(gainNode);
      gainNode.connect(ctx.destination);

      oscillator.frequency.setValueAtTime(freq, ctx.currentTime + index * 0.1);

      gainNode.gain.setValueAtTime(0, ctx.currentTime + index * 0.1);
      gainNode.gain.linearRampToValueAtTime(0.2, ctx.currentTime + index * 0.1 + 0.05);
      gainNode.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + index * 0.1 + 0.5);

      oscillator.start(ctx.currentTime + index * 0.1);
      oscillator.stop(ctx.currentTime + index * 0.1 + 0.5);
    });
  };

  // Start tick sound during spinning
  const startTickSound = (rowId: string, duration: number) => {
    const existingInterval = tickIntervalRefs.current.get(rowId);
    if (existingInterval) {
      clearTimeout(existingInterval);
    }

    let tickInterval = 50;
    const maxInterval = 200;
    const intervalIncrement = (maxInterval - tickInterval) / (duration / 100);

    const tick = () => {
      playTickSound();
      tickInterval += intervalIncrement;

      if (tickInterval < maxInterval) {
        const timeoutId = setTimeout(tick, Math.min(tickInterval, maxInterval));
        tickIntervalRefs.current.set(rowId, timeoutId);
      }
    };

    tick();

    setTimeout(() => {
      const interval = tickIntervalRefs.current.get(rowId);
      if (interval) {
        clearTimeout(interval);
        tickIntervalRefs.current.delete(rowId);
      }
    }, duration + 100);
  };

  // Shuffle array
  const shuffleArray = <T,>(array: T[]): T[] => {
    const shuffled = [...array];
    for (let i = shuffled.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    }
    return shuffled;
  };

  // Process voucher data when it changes
  useEffect(() => {
    if (voucherData && voucherData.rows) {
      const newSpinRows: SpinRow[] = voucherData.rows.map(row => ({
        id: `row-${row.row_number}-${Date.now()}`,
        rowNumber: row.row_number,
        vouchers: row.vouchers,
        displayVouchers: [...row.vouchers],
        isSpinning: false,
        isShuffling: false,
        winner: null,
        wheelRef: React.createRef<HTMLDivElement>(),
        selectedWinner: null,
      }));
      setSpinRows(newSpinRows);
      setRevealedWinners(new Set());
    }
  }, [voucherData]);

  // Show error if fetch failed
  useEffect(() => {
    if (fetchError) {
      toast.error('Failed to load voucher data. Please check your connection and try again.');
    }
  }, [fetchError]);

  // Remove auto-refetch - data will only load when Load Data button is clicked

  // Shuffle all rows (Acak functionality)
  const shuffleAllRows = () => {
    setSpinRows(prev => prev.map(row => ({
      ...row,
      isShuffling: true
    })));

    // Animate shuffling for each row
    spinRows.forEach((row, index) => {
      let shuffleCount = 0;
      const maxShuffles = 20;

      const shuffleInterval = setInterval(() => {
        shuffleCount++;

        setSpinRows(prev => prev.map(r => {
          if (r.id === row.id) {
            return {
              ...r,
              displayVouchers: shuffleArray(r.vouchers)
            };
          }
          return r;
        }));

        playTickSound();

        if (shuffleCount >= maxShuffles) {
          clearInterval(shuffleInterval);
          setTimeout(() => {
            setSpinRows(prev => prev.map(r => {
              if (r.id === row.id) {
                return {
                  ...r,
                  isShuffling: false
                };
              }
              return r;
            }));
          }, index * 100);
        }
      }, 100);

      shuffleIntervalRefs.current.set(row.id, shuffleInterval as any);
    });
  };

  // Reveal winners dramatically
  const revealWinnersDramatically = async () => {
    setIsRevealingWinners(true);
    setRevealedWinners(new Set());

    // First, arrange winners to be in the winner zone for each row
    const arrangedRows = spinRows.map(row => {
      const winner = row.vouchers.find(v => v.is_winner);
      if (!winner) return row;

      // Create a new display order with winner at position 3 or 4 (will be in winner zone)
      const otherVouchers = row.vouchers.filter(v => v.voucher_code !== winner.voucher_code);
      const shuffledOthers = shuffleArray(otherVouchers);

      // Place winner at index 3 (4th position) which will be in the winner zone
      const newDisplayVouchers = [
        ...shuffledOthers.slice(0, 3),
        winner,
        ...shuffledOthers.slice(3)
      ];

      return {
        ...row,
        displayVouchers: newDisplayVouchers
      };
    });

    // Update display to show arranged vouchers
    setSpinRows(arrangedRows);

    // Start drum roll effect
    const drumRollInterval = setInterval(() => {
      playDrumRoll();
    }, 100);

    // Create a scrolling/spinning effect for all wheels simultaneously
    let scrollSpeed = 50;
    let currentScroll = 0;
    const maxScroll = 2000;
    const deceleration = 0.95;

    const spinInterval = setInterval(() => {
      currentScroll += scrollSpeed;
      scrollSpeed *= deceleration;

      // Apply scrolling to all wheels
      arrangedRows.forEach(row => {
        const wheelElement = row.wheelRef.current;
        if (wheelElement) {
          wheelElement.style.transition = 'none';
          wheelElement.style.transform = `translateY(${-currentScroll}px)`;
        }
      });

      // Stop when speed is very slow
      if (scrollSpeed < 0.5 || currentScroll >= maxScroll) {
        clearInterval(spinInterval);
        clearInterval(drumRollInterval);

        // Final positioning - snap to winner position
        arrangedRows.forEach(row => {
          const wheelElement = row.wheelRef.current;
          if (wheelElement) {
            const CARD_HEIGHT = 80;
            const WINNER_ZONE_TOP = 260; // Top position of winner zone
            // Position 4th card (index 3) exactly at the winner zone
            const finalPosition = -(3 * CARD_HEIGHT - WINNER_ZONE_TOP);

            wheelElement.style.transition = 'transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
            wheelElement.style.transform = `translateY(${finalPosition}px)`;
          }
        });
      }
    }, 20);

    // Wait for scrolling to complete
    await new Promise(resolve => setTimeout(resolve, 3000));

    // Play winner sound
    playWinnerSound();

    // Collect all winners
    const winnersToReveal: { row: SpinRow, winner: Voucher }[] = [];
    arrangedRows.forEach(row => {
      const winner = row.vouchers.find(v => v.is_winner);
      if (winner) {
        winnersToReveal.push({ row, winner });
      }
    });

    // Update all winners at once with highlighting
    const allWinnerNumbers = new Set<number>();
    const historyEntries: WinnerHistory[] = [];

    winnersToReveal.forEach(({ row, winner }) => {
      allWinnerNumbers.add(row.rowNumber);
      historyEntries.push({
        rowNumber: row.rowNumber,
        winner: winner,
        timestamp: new Date()
      });
    });

    // Update state to highlight winners
    setRevealedWinners(allWinnerNumbers);

    setSpinRows(prev => prev.map(r => {
      const winnerInfo = winnersToReveal.find(w => w.row.id === r.id);
      if (winnerInfo) {
        return {
          ...r,
          winner: winnerInfo.winner,
          selectedWinner: winnerInfo.winner
        };
      }
      return r;
    }));

    setWinnersHistory(prev => [...prev, ...historyEntries]);

    setIsRevealingWinners(false);
  };

  const performDramaticSpin = (row: SpinRow, isSequential: boolean = false) => {
    const wheelElement = row.wheelRef.current;
    if (!wheelElement) return;

    const winner = row.vouchers.find(v => v.is_winner);
    if (!winner) {
      console.error('No winner found in vouchers');
      return;
    }

    const CARD_HEIGHT = 80;
    const WINNER_ZONE_TOP = 260; // Top position of winner zone

    // Shuffle the display vouchers to create more dramatic effect
    const shuffledVouchers = shuffleArray([...row.vouchers]);
    const winnerIndex = shuffledVouchers.findIndex(v => v.voucher_code === winner.voucher_code);

    // Update display vouchers with shuffled order
    setSpinRows(prev => prev.map(r =>
      r.id === row.id ? { ...r, displayVouchers: shuffledVouchers } : r
    ));

    wheelElement.style.transition = 'none';
    wheelElement.style.transform = 'translateY(0px)';
    wheelElement.offsetHeight;

    setTimeout(() => {
      // More dramatic spinning with multiple phases
      const minSpins = 15;
      const maxSpins = 25;
      const spins = minSpins + Math.random() * (maxSpins - minSpins);
      const totalItems = shuffledVouchers.length;

      const totalRotations = Math.floor(spins);
      const baseScrollDistance = totalRotations * totalItems * CARD_HEIGHT;
      const winnerScrollPosition = winnerIndex * CARD_HEIGHT;
      const finalPosition = -(baseScrollDistance + winnerScrollPosition) + WINNER_ZONE_TOP;

      const distance = Math.abs(finalPosition);
      const baseDuration = 4000; // Longer base duration
      const maxDuration = 7000; // Longer max duration
      const duration = Math.min(baseDuration + (distance / 8000) * 2000, maxDuration);

      // Phase 1: Fast initial spin
      const phase1Duration = duration * 0.3;
      const phase1Distance = finalPosition * 0.7;

      wheelElement.style.transform = `translateY(${phase1Distance}px)`;
      wheelElement.style.transition = `transform ${phase1Duration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94)`;

      // Phase 2: Slower approach to final position
      setTimeout(() => {
        wheelElement.style.transform = `translateY(${finalPosition}px)`;
        wheelElement.style.transition = `transform ${duration - phase1Duration}ms cubic-bezier(0.17, 0.67, 0.12, 0.99)`;
      }, phase1Duration);

      startTickSound(row.id, duration);

      setTimeout(() => {
        const interval = tickIntervalRefs.current.get(row.id);
        if (interval) {
          clearTimeout(interval);
          tickIntervalRefs.current.delete(row.id);
        }

        playWinnerSound();

        setSpinRows(prev => prev.map(r =>
          r.id === row.id
            ? { ...r, isSpinning: false, winner: winner, selectedWinner: winner }
            : r
        ));

        setWinnersHistory(prev => [...prev, {
          rowNumber: row.rowNumber,
          winner: winner,
          timestamp: new Date()
        }]);

        // If this is sequential spinning, trigger next row
        if (isSequential) {
          const nextRowIndex = spinRows.findIndex(r => r.id === row.id) + 1;
          if (nextRowIndex < spinRows.length) {
            setTimeout(() => {
              spinSequentialRow(nextRowIndex);
            }, 2000); // Wait 2 seconds before next spin
          } else {
            // All rows completed
            setIsSequentialSpinning(false);
            setCurrentSpinningRow(null);
          }
        }

        // Keep the winner in the winner zone - don't reset position
        // The winning card will stay exactly where it landed in the winner zone

      }, duration);
    }, 100);
  };

  const performSpin = (row: SpinRow) => {
    const wheelElement = row.wheelRef.current;
    if (!wheelElement) return;

    const winner = row.vouchers.find(v => v.is_winner);
    if (!winner) {
      console.error('No winner found in vouchers');
      return;
    }

    const CARD_HEIGHT = 80;
    const WINNER_ZONE_TOP = 260; // Top position of winner zone

    // Shuffle the display vouchers to create more dramatic effect
    const shuffledVouchers = shuffleArray([...row.vouchers]);
    const winnerIndex = shuffledVouchers.findIndex(v => v.voucher_code === winner.voucher_code);

    // Update display vouchers with shuffled order
    setSpinRows(prev => prev.map(r =>
      r.id === row.id ? { ...r, displayVouchers: shuffledVouchers } : r
    ));

    wheelElement.style.transition = 'none';
    wheelElement.style.transform = 'translateY(0px)';
    wheelElement.offsetHeight;

    setTimeout(() => {
      // More dramatic spinning with multiple phases
      const minSpins = 15;
      const maxSpins = 25;
      const spins = minSpins + Math.random() * (maxSpins - minSpins);
      const totalItems = shuffledVouchers.length;

      const totalRotations = Math.floor(spins);
      const baseScrollDistance = totalRotations * totalItems * CARD_HEIGHT;
      const winnerScrollPosition = winnerIndex * CARD_HEIGHT;
      const finalPosition = -(baseScrollDistance + winnerScrollPosition) + WINNER_ZONE_TOP;

      const distance = Math.abs(finalPosition);
      const baseDuration = 4000; // Longer base duration
      const maxDuration = 7000; // Longer max duration
      const duration = Math.min(baseDuration + (distance / 8000) * 2000, maxDuration);

      // Phase 1: Fast initial spin
      const phase1Duration = duration * 0.3;
      const phase1Distance = finalPosition * 0.7;

      wheelElement.style.transform = `translateY(${phase1Distance}px)`;
      wheelElement.style.transition = `transform ${phase1Duration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94)`;

      // Phase 2: Slower approach to final position
      setTimeout(() => {
        wheelElement.style.transform = `translateY(${finalPosition}px)`;
        wheelElement.style.transition = `transform ${duration - phase1Duration}ms cubic-bezier(0.17, 0.67, 0.12, 0.99)`;
      }, phase1Duration);

      startTickSound(row.id, duration);

      setTimeout(() => {
        const interval = tickIntervalRefs.current.get(row.id);
        if (interval) {
          clearTimeout(interval);
          tickIntervalRefs.current.delete(row.id);
        }

        playWinnerSound();

        setSpinRows(prev => prev.map(r =>
          r.id === row.id
            ? { ...r, isSpinning: false, winner: winner, selectedWinner: winner }
            : r
        ));

        setWinnersHistory(prev => [...prev, {
          rowNumber: row.rowNumber,
          winner: winner,
          timestamp: new Date()
        }]);

        // Keep the winner in the winner zone - don't reset position
        // The winning card will stay exactly where it landed in the winner zone

      }, duration);
    }, 100);
  };

  const spinSequentialRow = (rowIndex: number) => {
    if (rowIndex >= spinRows.length) {
      setIsSequentialSpinning(false);
      setCurrentSpinningRow(null);
      return;
    }

    const row = spinRows[rowIndex];
    if (!row || row.isSpinning || row.winner) {
      // Skip this row and go to next
      spinSequentialRow(rowIndex + 1);
      return;
    }

    setCurrentSpinningRow(row.rowNumber);
    setSpinRows(prev => prev.map(r =>
      r.id === row.id ? { ...r, isSpinning: true, selectedWinner: null } : r
    ));

    const wheelElement = row.wheelRef.current;
    if (wheelElement) {
      wheelElement.style.transition = 'none';
      wheelElement.style.transform = 'translateY(0px)';
      wheelElement.offsetHeight;
    }

    performDramaticSpin(row, true);
  };

  const startSequentialSpinning = () => {
    if (spinRows.length === 0) return;

    // Clear any existing results
    setWinnersHistory([]);
    setRevealedWinners(new Set());
    setSpinRows(prev => prev.map(row => ({
      ...row,
      isSpinning: false,
      isShuffling: false,
      winner: null,
      selectedWinner: null,
      displayVouchers: [...row.vouchers]
    })));

    // Reset all wheel positions
    spinRows.forEach(row => {
      const wheelElement = row.wheelRef.current;
      if (wheelElement) {
        wheelElement.style.transition = 'none';
        wheelElement.style.transform = 'translateY(0px)';
      }
    });

    setIsSequentialSpinning(true);
    setCurrentSpinningRow(null);

    // Start with first row after a short delay
    setTimeout(() => {
      spinSequentialRow(0);
    }, 500);
  };

  const spinWheel = (rowId: string) => {
    const row = spinRows.find(r => r.id === rowId);
    if (!row || row.isSpinning || row.winner) return;

    setSpinRows(prev => prev.map(r =>
      r.id === rowId ? { ...r, isSpinning: true, selectedWinner: null } : r
    ));

    const wheelElement = row.wheelRef.current;
    if (wheelElement) {
      wheelElement.style.transition = 'none';
      wheelElement.style.transform = 'translateY(0px)';
      wheelElement.offsetHeight;
    }

    performSpin(row);
  };

  const clearResults = () => {
    tickIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
    shuffleIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
    tickIntervalRefs.current.clear();
    shuffleIntervalRefs.current.clear();

    setWinnersHistory([]);
    setRevealedWinners(new Set());
    setIsSequentialSpinning(false);
    setCurrentSpinningRow(null);
    setSpinRows(prev => prev.map(row => ({
      ...row,
      isSpinning: false,
      isShuffling: false,
      winner: null,
      selectedWinner: null,
      displayVouchers: [...row.vouchers]
    })));

    spinRows.forEach(row => {
      const wheelElement = row.wheelRef.current;
      if (wheelElement) {
        wheelElement.style.transition = 'none';
        wheelElement.style.transform = 'translateY(0px)';
      }
    });
  };

  const refreshData = async () => {
    tickIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
    shuffleIntervalRefs.current.forEach(timeout => clearTimeout(timeout));
    tickIntervalRefs.current.clear();
    shuffleIntervalRefs.current.clear();

    try {
      await refetchVouchers();
      toast.success('Data refreshed successfully');
    } catch (error) {
      toast.error('Failed to refresh data');
    }
  };

  const formatPhoneNumber = (phone: string) => {
    return phone.substring(0, 5) + '****' + phone.substring(phone.length - 2);
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 text-gray-900 p-6">
      <style jsx>{`
        @keyframes bounce-in {
          0% {
            transform: scale(0.3);
            opacity: 0;
          }
          50% {
            transform: scale(1.05);
          }
          70% {
            transform: scale(0.9);
          }
          100% {
            transform: scale(1);
            opacity: 1;
          }
        }

        .animate-bounce-in {
          animation: bounce-in 0.6s ease-out;
        }
      `}</style>

      <div className="max-w-full px-4 mx-auto">
        {/* Header */}
        <div className="text-center mb-8">
          <h1 className="text-5xl font-bold bg-gradient-to-r from-primary to-purple-600 bg-clip-text text-transparent mb-2">
            Voucher Lucky Draw
          </h1>
        </div>

        <div className="space-y-4">
          {/* Controls Section - Compact Layout */}
          <div className="grid grid-cols-1 lg:grid-cols-3 gap-3">
            {/* Configuration Card */}
            <div className="bg-white rounded-lg p-4 border border-gray-200 shadow-sm">
              <h2 className="text-lg font-semibold mb-3 text-gray-900">
                Configuration
              </h2>

                <div className="space-y-3">
                  <div className="grid grid-cols-2 gap-2">
                    <div>
                      <label className="block text-xs font-medium text-gray-700 mb-1">
                        Number of Rows
                      </label>
                      <input
                        type="number"
                        min="1"
                        max="10"
                        value={numberOfRows}
                        onChange={(e) => setNumberOfRows(parseInt(e.target.value) || 1)}
                        className="w-full bg-white border border-gray-300 rounded p-1.5 text-sm text-gray-900 focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20"
                        disabled={isLoadingData}
                      />
                    </div>

                    <div>
                      <label className="block text-xs font-medium text-gray-700 mb-1">
                        Prize Selection
                      </label>
                      <select
                        value={selectedPrize}
                        onChange={(e) => setSelectedPrize(parseInt(e.target.value))}
                        className="w-full bg-white border border-gray-300 rounded p-1.5 text-sm text-gray-900 focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20"
                        disabled={isLoadingData}
                      >
                        <option value={1}>🥇 Emas 0.25 Gram</option>
                        <option value={2}>🥇 Emas 3 Gram</option>
                      </select>
                    </div>
                  </div>

                  <button
                    onClick={refreshData}
                    disabled={isLoadingData}
                    className="w-full px-3 py-1.5 bg-primary hover:bg-primary/90 disabled:bg-gray-400 text-white text-sm font-semibold rounded flex items-center justify-center gap-1 transition-colors"
                  >
                    <RefreshCw size={14} className={isLoadingData ? 'animate-spin' : ''} />
                    {isLoadingData ? 'Loading...' : 'Load Data'}
                  </button>
                </div>

              {spinRows.length > 0 && (
                <div className="mt-3 p-2 bg-gray-50 rounded text-xs text-gray-600">
                  <div>Rows: {spinRows.length} | Vouchers: {spinRows.reduce((acc, row) => acc + row.vouchers.length, 0)}</div>
                </div>
              )}
            </div>

            {/* Actions Card */}
            <div className="bg-white rounded-lg p-4 border border-gray-200 shadow-sm">
              <h2 className="text-lg font-semibold mb-3 text-gray-900">
                Actions
              </h2>

              <div className="space-y-2">
                <button
                  onClick={shuffleAllRows}
                  disabled={isLoadingData || spinRows.some(r => r.isShuffling) || spinRows.length === 0}
                  className="w-full px-3 py-1.5 bg-purple-600 hover:bg-purple-700 disabled:bg-gray-400 text-white text-sm font-semibold rounded flex items-center justify-center gap-1 transition-colors"
                >
                  <Shuffle size={14} className={spinRows.some(r => r.isShuffling) ? 'animate-pulse' : ''} />
                  Shuffle All
                </button>

                <button
                  onClick={startSequentialSpinning}
                  disabled={isSequentialSpinning || spinRows.length === 0}
                  className="w-full px-3 py-1.5 bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 disabled:from-gray-400 disabled:to-gray-500 text-white text-sm font-bold rounded flex items-center justify-center gap-1 transition-all"
                >
                  <Trophy size={14} className={isSequentialSpinning ? 'animate-spin' : ''} />
                  {isSequentialSpinning ? 'Spinning...' : 'Spin for Winner'}
                </button>

                {winnersHistory.length > 0 && (
                  <button
                    onClick={clearResults}
                    className="w-full px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white text-sm font-semibold rounded flex items-center justify-center gap-1 transition-colors"
                  >
                    <Trash2 size={14} />
                    Clear Results
                  </button>
                )}
              </div>
            </div>

            {/* Winners Summary Card */}
            <div className="bg-white rounded-lg p-4 border border-gray-200 shadow-sm">
              <h2 className="text-lg font-semibold mb-3 text-gray-900 flex items-center gap-2">
                <Trophy className="text-yellow-500" size={18} />
                Winners
              </h2>

              {winnersHistory.length > 0 ? (
                <div className="space-y-1 max-h-32 overflow-y-auto">
                  {winnersHistory.map((history) => (
                    <div
                      key={`${history.rowNumber}-${history.timestamp.getTime()}`}
                      className="p-1.5 bg-yellow-50 border border-yellow-200 rounded text-xs"
                    >
                      <div className="font-semibold text-yellow-700">
                        Row {history.rowNumber}: {history.winner.name}
                      </div>
                      <div className="text-xs text-yellow-600">
                        {history.winner.voucher_code}
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <div className="text-center py-2">
                  <Trophy className="mx-auto text-gray-300 mb-1" size={20} />
                  <p className="text-gray-500 text-xs">No winners yet</p>
                </div>
              )}
            </div>
          </div>

          {/* Spin Rows - Display in grid */}
          <div className={`grid gap-4 ${
            spinRows.length === 1 ? 'grid-cols-1' :
            spinRows.length === 2 ? 'grid-cols-1 lg:grid-cols-2' :
            spinRows.length === 3 ? 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3' :
            spinRows.length === 4 ? 'grid-cols-1 md:grid-cols-2 xl:grid-cols-4' :
            spinRows.length === 5 ? 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5' :
            'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
          }`}>
            {spinRows.map((row) => (
              <div key={row.id} className={`bg-white rounded-lg border-2 shadow-sm transition-all ${
                row.isShuffling ? 'border-purple-400 animate-pulse' : 'border-gray-200'
              }`}>
                <div className="p-4 border-b border-gray-200">

                  {row.winner && (
                    <div className="mt-2 p-2 bg-yellow-50 border border-yellow-200 rounded-lg animate-bounce-in">
                      <div className="flex items-center gap-1 text-sm">
                        <Trophy className="text-yellow-500" size={16} />
                        <span className="font-semibold text-yellow-700 truncate">
                          {row.winner.name}
                        </span>
                      </div>
                      <div className="text-xs text-yellow-600 mt-1">
                        {row.winner.voucher_code}
                      </div>
                    </div>
                  )}
                </div>

                {/* Wheel Container */}
                <div
                  className="relative bg-gray-50 overflow-hidden"
                  style={{ height: '600px' }}
                >
                  {/* Subtle Winner Zone Indicator */}
                  <div
                    className="absolute left-0 right-0 z-10 pointer-events-none"
                    style={{
                      top: '260px',
                      height: '80px',
                      background: 'linear-gradient(90deg, transparent 0%, rgba(34, 197, 94, 0.1) 20%, rgba(34, 197, 94, 0.2) 50%, rgba(34, 197, 94, 0.1) 80%, transparent 100%)',
                      borderTop: '2px dashed rgba(34, 197, 94, 0.3)',
                      borderBottom: '2px dashed rgba(34, 197, 94, 0.3)'
                    }}
                  >
                    <div className="absolute right-2 top-1/2 transform -translate-y-1/2">
                      <div className="bg-green-500 text-white px-2 py-1 rounded text-xs font-bold shadow-lg">
                        🏆 WINNER
                      </div>
                    </div>
                  </div>

                  {/* Scrolling Cards */}
                  <div
                    ref={row.wheelRef}
                    className="absolute inset-0"
                    style={{ transform: 'translateY(0px)' }}
                  >
                    {Array.from({ length: 50 }, (_, repeatIndex) =>
                      row.displayVouchers.map((voucher, voucherIndex) => {
                        const isSelectedWinner = row.selectedWinner?.voucher_code === voucher.voucher_code;

                        return (
                            <div
                              key={`${repeatIndex}-${voucherIndex}`}
                              className={`flex items-center px-4 border-b border-gray-300 transition-all duration-300 ${
                                isSelectedWinner
                                  ? 'bg-gradient-to-r from-yellow-100 to-yellow-200 border-yellow-300 shadow-lg'
                                  : voucherIndex % 2 === 0
                                    ? 'bg-white hover:bg-gray-50'
                                    : 'bg-gray-50 hover:bg-gray-100'
                              }`}
                              style={{
                                height: '80px',
                                minHeight: '80px',
                                maxHeight: '80px',
                                boxSizing: 'border-box'
                              }}
                            >
                            <div className="flex-1">
                              <div className={`font-bold text-lg mb-1 ${
                                isSelectedWinner ? 'text-yellow-600' : 'text-gray-900'
                              }`}>
                                {voucher.voucher_code}
                              </div>
                              <div className={`text-sm ${
                                isSelectedWinner ? 'text-yellow-700' : 'text-gray-600'
                              }`}>
                                {voucher.name}
                              </div>
                            </div>

                            <div className="text-right">
                              <div className="text-gray-500 text-xs">
                                {formatPhoneNumber(voucher.phone_number)}
                              </div>
                              {isSelectedWinner && (
                                <Trophy className="inline ml-2 text-yellow-500" size={16} />
                              )}
                            </div>
                          </div>
                        );
                      })
                    )}
                  </div>

                  {/* Gradient Overlays */}
                  <div className="absolute top-0 left-0 right-0 h-32 bg-gradient-to-b from-gray-50 via-gray-50/70 to-transparent pointer-events-none z-40"></div>
                  <div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-gray-50 via-gray-50/70 to-transparent pointer-events-none z-40"></div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

export default RandomDrawApp;
