|
import React, { useState, useMemo } from 'react'; |
|
import { Sparkles, RefreshCw, Target, TrendingUp, Brain, Shuffle } from 'lucide-react'; |
|
|
|
interface SmartNumberGeneratorProps { |
|
className?: string; |
|
onGeneratedNumbers?: (numbers: number[]) => void; |
|
} |
|
|
|
const SmartNumberGenerator: React.FC<SmartNumberGeneratorProps> = ({ |
|
className = '', |
|
onGeneratedNumbers |
|
}) => { |
|
const [strategy, setStrategy] = useState<'hot' | 'cold' | 'balanced' | 'random'>('balanced'); |
|
const [generatedNumbers, setGeneratedNumbers] = useState<number[]>([]); |
|
const [isGenerating, setIsGenerating] = useState(false); |
|
|
|
|
|
const numberStatistics = useMemo(() => { |
|
return { |
|
|
|
hot: [0, 5, 23, 32, 44, 67, 78, 89, 12, 56, 34, 45, 66, 77, 88, 11, 22, 33, 55, 99], |
|
|
|
|
|
cold: [3, 17, 29, 41, 53, 65, 77, 83, 91, 97, 4, 16, 28, 40, 52, 64, 76, 84, 92, 96], |
|
|
|
|
|
columnPatterns: { |
|
1: { hot: [1, 21, 31, 51, 71], balanced: [11, 41, 61, 81, 91] }, |
|
2: { hot: [2, 22, 32, 42, 72], balanced: [12, 52, 62, 82, 92] }, |
|
3: { hot: [23, 33, 43, 73, 93], balanced: [3, 13, 53, 63, 83] }, |
|
4: { hot: [4, 24, 34, 44, 64], balanced: [14, 54, 74, 84, 94] }, |
|
5: { hot: [5, 25, 35, 45, 75], balanced: [15, 55, 65, 85, 95] }, |
|
6: { hot: [6, 16, 26, 56, 76], balanced: [36, 46, 66, 86, 96] }, |
|
7: { hot: [7, 27, 37, 67, 87], balanced: [17, 47, 57, 77, 97] }, |
|
8: { hot: [8, 18, 28, 68, 78], balanced: [38, 48, 58, 88, 98] }, |
|
9: { hot: [9, 19, 39, 59, 89], balanced: [29, 49, 69, 79, 99] }, |
|
10: { hot: [0, 10, 30, 50, 80], balanced: [20, 40, 60, 70, 90] } |
|
} |
|
}; |
|
}, []); |
|
|
|
const generateNumbers = async () => { |
|
setIsGenerating(true); |
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1500)); |
|
|
|
let numbers: number[] = []; |
|
|
|
switch (strategy) { |
|
case 'hot': |
|
|
|
numbers = generateHotNumbers(); |
|
break; |
|
|
|
case 'cold': |
|
|
|
numbers = generateColdNumbers(); |
|
break; |
|
|
|
case 'balanced': |
|
|
|
numbers = generateBalancedNumbers(); |
|
break; |
|
|
|
case 'random': |
|
|
|
numbers = generateRandomNumbers(); |
|
break; |
|
} |
|
|
|
setGeneratedNumbers(numbers); |
|
onGeneratedNumbers?.(numbers); |
|
setIsGenerating(false); |
|
}; |
|
|
|
const generateHotNumbers = (): number[] => { |
|
const selected: number[] = []; |
|
const hotNumbers = [...numberStatistics.hot]; |
|
|
|
|
|
for (let i = 0; i < 15 && hotNumbers.length > 0; i++) { |
|
const randomIndex = Math.floor(Math.random() * hotNumbers.length); |
|
selected.push(hotNumbers.splice(randomIndex, 1)[0]); |
|
} |
|
|
|
|
|
while (selected.length < 50) { |
|
const num = Math.floor(Math.random() * 100); |
|
if (!selected.includes(num)) { |
|
selected.push(num); |
|
} |
|
} |
|
|
|
return selected.sort((a, b) => a - b); |
|
}; |
|
|
|
const generateColdNumbers = (): number[] => { |
|
const selected: number[] = []; |
|
const coldNumbers = [...numberStatistics.cold]; |
|
|
|
|
|
for (let i = 0; i < 15 && coldNumbers.length > 0; i++) { |
|
const randomIndex = Math.floor(Math.random() * coldNumbers.length); |
|
selected.push(coldNumbers.splice(randomIndex, 1)[0]); |
|
} |
|
|
|
|
|
while (selected.length < 50) { |
|
const num = Math.floor(Math.random() * 100); |
|
if (!selected.includes(num)) { |
|
selected.push(num); |
|
} |
|
} |
|
|
|
return selected.sort((a, b) => a - b); |
|
}; |
|
|
|
const generateBalancedNumbers = (): number[] => { |
|
const selected: number[] = []; |
|
|
|
|
|
Object.values(numberStatistics.columnPatterns).forEach(column => { |
|
const availableNumbers = [...column.hot, ...column.balanced]; |
|
|
|
|
|
for (let i = 0; i < 5 && availableNumbers.length > 0; i++) { |
|
const randomIndex = Math.floor(Math.random() * availableNumbers.length); |
|
const number = availableNumbers.splice(randomIndex, 1)[0]; |
|
if (!selected.includes(number)) { |
|
selected.push(number); |
|
} |
|
} |
|
}); |
|
|
|
return selected.sort((a, b) => a - b); |
|
}; |
|
|
|
const generateRandomNumbers = (): number[] => { |
|
const selected: number[] = []; |
|
|
|
while (selected.length < 50) { |
|
const num = Math.floor(Math.random() * 100); |
|
if (!selected.includes(num)) { |
|
selected.push(num); |
|
} |
|
} |
|
|
|
return selected.sort((a, b) => a - b); |
|
}; |
|
|
|
const getStrategyInfo = () => { |
|
const strategies = { |
|
hot: { |
|
title: '🔥 Números Quentes', |
|
description: 'Foca nos números mais sorteados historicamente', |
|
icon: TrendingUp, |
|
color: 'from-red-500 to-orange-500' |
|
}, |
|
cold: { |
|
title: '❄️ Números Frios', |
|
description: 'Aposta nos números menos sorteados (teoria da compensação)', |
|
icon: Target, |
|
color: 'from-blue-500 to-indigo-500' |
|
}, |
|
balanced: { |
|
title: '⚖️ Estratégia Balanceada', |
|
description: 'Mix inteligente de números quentes e frios por coluna', |
|
icon: Brain, |
|
color: 'from-green-500 to-emerald-500' |
|
}, |
|
random: { |
|
title: '🎲 Totalmente Aleatório', |
|
description: 'Seleção completamente aleatória - cada número tem chance igual', |
|
icon: Shuffle, |
|
color: 'from-purple-500 to-pink-500' |
|
} |
|
}; |
|
|
|
return strategies[strategy]; |
|
}; |
|
|
|
const strategyInfo = getStrategyInfo(); |
|
|
|
return ( |
|
<div className={`bg-white rounded-2xl shadow-xl border border-gray-100 ${className}`}> |
|
{/* Header */} |
|
<div className={`bg-gradient-to-r ${strategyInfo.color} text-white p-6 rounded-t-2xl`}> |
|
<div className="flex items-center space-x-3"> |
|
<Sparkles className="w-8 h-8" /> |
|
<div> |
|
<h2 className="text-2xl font-bold">Gerador Inteligente</h2> |
|
<p className="text-white/90">Baseado em análise estatística real</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div className="p-6"> |
|
{/* Seleção de Estratégia */} |
|
<div className="mb-6"> |
|
<h3 className="text-lg font-semibold text-gray-800 mb-4">Escolha sua Estratégia</h3> |
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
{(['hot', 'cold', 'balanced', 'random'] as const).map((strategyType) => { |
|
const strategies = { |
|
hot: { title: '🔥 Números Quentes', desc: 'Mais sorteados' }, |
|
cold: { title: '❄️ Números Frios', desc: 'Menos sorteados' }, |
|
balanced: { title: '⚖️ Balanceada', desc: 'Mix inteligente' }, |
|
random: { title: '🎲 Aleatório', desc: 'Seleção livre' } |
|
}; |
|
|
|
const strategyData = strategies[strategyType]; |
|
|
|
return ( |
|
<button |
|
key={strategyType} |
|
onClick={() => setStrategy(strategyType)} |
|
className={`p-4 rounded-xl border-2 transition-all duration-200 text-left ${ |
|
strategy === strategyType |
|
? 'border-blue-500 bg-blue-50' |
|
: 'border-gray-200 hover:border-gray-300 bg-gray-50' |
|
}`} |
|
> |
|
<h4 className={`font-semibold ${ |
|
strategy === strategyType ? 'text-blue-800' : 'text-gray-800' |
|
}`}> |
|
{strategyData.title} |
|
</h4> |
|
<p className={`text-sm ${ |
|
strategy === strategyType ? 'text-blue-600' : 'text-gray-600' |
|
}`}> |
|
{strategyData.desc} |
|
</p> |
|
</button> |
|
); |
|
})} |
|
</div> |
|
</div> |
|
|
|
{/* Informações da Estratégia Selecionada */} |
|
<div className="mb-6 bg-gray-50 rounded-xl p-4"> |
|
<div className="flex items-center space-x-3 mb-2"> |
|
<strategyInfo.icon className="w-6 h-6 text-blue-600" /> |
|
<h4 className="font-semibold text-gray-800">{strategyInfo.title}</h4> |
|
</div> |
|
<p className="text-gray-600 text-sm">{strategyInfo.description}</p> |
|
</div> |
|
|
|
{/* Botão de Gerar */} |
|
<div className="text-center mb-6"> |
|
<button |
|
onClick={generateNumbers} |
|
disabled={isGenerating} |
|
className={`px-8 py-4 rounded-xl font-semibold text-white transition-all duration-200 ${ |
|
isGenerating |
|
? 'bg-gray-400 cursor-not-allowed' |
|
: `bg-gradient-to-r ${strategyInfo.color} hover:shadow-lg transform hover:scale-105` |
|
}`} |
|
> |
|
{isGenerating ? ( |
|
<div className="flex items-center space-x-2"> |
|
<RefreshCw className="w-5 h-5 animate-spin" /> |
|
<span>Gerando números...</span> |
|
</div> |
|
) : ( |
|
<div className="flex items-center space-x-2"> |
|
<Sparkles className="w-5 h-5" /> |
|
<span>Gerar 50 Números</span> |
|
</div> |
|
)} |
|
</button> |
|
</div> |
|
|
|
{/* Números Gerados */} |
|
{generatedNumbers.length > 0 && ( |
|
<div> |
|
<h3 className="text-lg font-semibold text-gray-800 mb-4"> |
|
Números Gerados - {strategyInfo.title} |
|
</h3> |
|
|
|
<div className="bg-gray-50 rounded-xl p-4 mb-4"> |
|
<div className="grid grid-cols-10 gap-2"> |
|
{generatedNumbers.map((number, index) => ( |
|
<div |
|
key={index} |
|
className="bg-white text-gray-800 font-bold text-center py-2 px-1 rounded-lg shadow-sm border" |
|
> |
|
{number.toString().padStart(2, '0')} |
|
</div> |
|
))} |
|
</div> |
|
</div> |
|
|
|
{/* Estatísticas dos Números Gerados */} |
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4"> |
|
<div className="bg-red-50 border border-red-200 rounded-lg p-4"> |
|
<h4 className="font-semibold text-red-800 mb-2">🔥 Números Quentes</h4> |
|
<p className="text-2xl font-bold text-red-600"> |
|
{generatedNumbers.filter(num => numberStatistics.hot.includes(num)).length} |
|
</p> |
|
<p className="text-sm text-red-600">de 50 números</p> |
|
</div> |
|
|
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4"> |
|
<h4 className="font-semibold text-blue-800 mb-2">❄️ Números Frios</h4> |
|
<p className="text-2xl font-bold text-blue-600"> |
|
{generatedNumbers.filter(num => numberStatistics.cold.includes(num)).length} |
|
</p> |
|
<p className="text-sm text-blue-600">de 50 números</p> |
|
</div> |
|
|
|
<div className="bg-green-50 border border-green-200 rounded-lg p-4"> |
|
<h4 className="font-semibold text-green-800 mb-2">📊 Distribuição</h4> |
|
<p className="text-2xl font-bold text-green-600"> |
|
{(generatedNumbers.length / 100 * 100).toFixed(0)}% |
|
</p> |
|
<p className="text-sm text-green-600">da cartela</p> |
|
</div> |
|
</div> |
|
|
|
{/* Dicas */} |
|
<div className="mt-4 bg-yellow-50 border border-yellow-200 rounded-lg p-4"> |
|
<h4 className="font-semibold text-yellow-800 mb-2">💡 Dicas para uso:</h4> |
|
<ul className="text-sm text-yellow-700 space-y-1"> |
|
<li>• Use estes números como base para seus jogos</li> |
|
<li>• Combine com sua própria análise e intuição</li> |
|
<li>• Considere jogar frações destes números em múltiplos jogos</li> |
|
<li>• Lembre-se: cada sorteio é independente dos anteriores</li> |
|
</ul> |
|
</div> |
|
</div> |
|
)} |
|
</div> |
|
</div> |
|
); |
|
}; |
|
|
|
export default SmartNumberGenerator; |
|
|