src/hooks/useCalculator.ts (view raw)
1// src/hooks/useCalculator.ts
2import { useState, useEffect } from "react";
3import {
4 calculateMinimumProfit,
5 calculateRepetitions,
6 calculateStake,
7 RepetitionResult,
8} from "../utils/calculatorFunctions";
9
10interface CalculatorState {
11 percentage: number;
12 max: number;
13 odd1: number;
14 odd2: number;
15 stake: number;
16 refund: number;
17 repetitions: number;
18 results: RepetitionResult[];
19 minimumProfit: number;
20}
21
22export const useCalculator = () => {
23 const [state, setState] = useState<CalculatorState>({
24 percentage: 10,
25 max: 10,
26 odd1: 2.0,
27 odd2: 1.95,
28 stake: 750,
29 refund: 10,
30 repetitions: 2,
31 results: [],
32 minimumProfit: 0,
33 });
34
35 // Update stake based on percentage and max
36 useEffect(() => {
37 const newStake = calculateStake(state.percentage, state.max);
38 setState((prev) => ({
39 ...prev,
40 stake: newStake,
41 refund: state.max,
42 }));
43 }, [state.percentage, state.max]);
44
45 // Calculate results whenever relevant values change
46 useEffect(() => {
47 const results = calculateRepetitions(
48 state.stake,
49 state.refund,
50 state.odd1,
51 state.odd2,
52 state.repetitions,
53 );
54
55 const minimumProfit =
56 results.length > 0 ? calculateMinimumProfit(results) : 0;
57
58 setState((prev) => ({
59 ...prev,
60 results,
61 minimumProfit,
62 }));
63 }, [state.stake, state.refund, state.odd1, state.odd2, state.repetitions]);
64
65 // Handle input changes
66 const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
67 const { id, value } = e.target;
68 const numValue = parseFloat(value);
69
70 if (id === "inputRepetitions") {
71 setState((prev) => ({ ...prev, repetitions: numValue }));
72 return;
73 }
74
75 setState((prev) => {
76 const newState = { ...prev };
77 if (id === "inputPercentage") {
78 newState.percentage = numValue;
79 } else if (id === "inputMax") {
80 newState.max = numValue;
81 } else if (id === "inputOdd1") {
82 newState.odd1 = numValue;
83 } else if (id === "inputOdd2") {
84 newState.odd2 = numValue;
85 } else if (id === "inputStake") {
86 newState.stake = numValue;
87 } else if (id === "inputRefund") {
88 newState.refund = numValue;
89 }
90
91 if (id === "inputPercentage" || id === "inputMax") {
92 newState.stake = calculateStake(
93 id === "inputPercentage" ? numValue : newState.percentage,
94 id === "inputMax" ? numValue : newState.max,
95 );
96 newState.refund = id === "inputMax" ? numValue : newState.max;
97 }
98
99 let bestRep = 1;
100 let bestMin = -Infinity;
101 let bestResults: RepetitionResult[] = [];
102 for (let rip = 1; rip <= 5; rip++) {
103 const results = calculateRepetitions(
104 newState.stake,
105 newState.refund,
106 newState.odd1,
107 newState.odd2,
108 rip,
109 );
110 const min =
111 results.length > 0 ? calculateMinimumProfit(results) : -Infinity;
112 // Prefer larger rip if min is equal
113 if (min > bestMin || (min === bestMin && rip > bestRep)) {
114 bestMin = min;
115 bestRep = rip;
116 bestResults = results;
117 }
118 }
119
120 newState.repetitions = bestRep;
121 newState.results = bestResults;
122 newState.minimumProfit = bestMin;
123 return newState;
124 });
125 };
126
127 // Swap odds
128 const swapOdds = () => {
129 setState((prev) => ({
130 ...prev,
131 odd1: prev.odd2,
132 odd2: prev.odd1,
133 }));
134 };
135
136 return {
137 state,
138 handleInputChange,
139 swapOdds,
140 };
141};