/* eslint-disable no-unused-vars */
/* eslint-disable jsx-a11y/label-has-associated-control */
/* eslint-disable no-restricted-globals */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable array-callback-return */
/* eslint-disable no-return-assign */
import React, { useRef, useState, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import keygen from 'gatsby-core-theme/src/helpers/keygen';
import Button from 'gatsby-core-theme/src/components/atoms/button/button';
import useTranslate from '~hooks/useTranslate/useTranslate';

import {
  getSelectionOddsAndOutcomes,
  doTheCalculations,
  getTheOutputResult,
  calculateForUnionJack,
  calculateForAlphabet,
  calculateFoldOptions,
} from '../../../helpers/horse-racing-calculator';
import Select from '../../atoms/select';

import { applyBookmakerBonuses } from '../../../helpers/horse-racing-calculator/bookmaker-bonus.js';

import {
  betType,
  deafultFoldTableRows,
  placeOddsoptions,
  ruleFourOptions,
  outcomeOptions,
} from '../../../constants/horse-racing-calculator';
import styles from './horse-calculator.module.scss';

const HorseCalculator = ({ mainTitle = 'Bet Calculator', tooltipMinWidth = 20 }) => {
  const numSelection = 20;

  const outcomesTableRefs = useRef([]);
  const deadHeatRefs = useRef([]);
  const stakeTypeRef = useRef('1');
  const foldOptionRef = useRef(null);
  const foldTableRefs = useRef([]);
  const oneLoserBonusRef = useRef(0);
  const bookmakerBonusRef = useRef(0);
  const oneWinnerConsolationRef = useRef('1');
  const totalOutlayRef = useRef(null);
  const totalReturnRef = useRef(null);
  const totalProfitRef = useRef(null);
  const numSelectionRef = useRef(null);
  const betTypeRef = useRef(null);
  const stakeRef = useRef(null);

  const [activeBetType, setBetType] = useState(betType[0]);
  const [eachWay, setEachWay] = useState('No');
  const [ruleFour, setRuleFour] = useState('No');
  const [addNotes, setAddNotes] = useState('No');
  const [foldOption, setFoldOption] = useState('1');
  const [stake, setStake] = useState(0);
  const [multipleOptions, setMultipleOption] = useState('1');
  const [numSelections, setNumSelections] = useState(null);
  const [foldTableRows, setFoldTableRows] = useState(deafultFoldTableRows);
  const [outcomeSelection, setOutcomeSelection] = useState(
    [...Array(numSelections ? parseInt(numSelections) : activeBetType.num_of_rows)].map(
      () => 'winner'
    )
  );

  const resetOutcomeRows = (outcomeSelect) => {
    outcomesTableRefs.current.map((item) => {
      if (item) {
        if (outcomeSelect) {
          item.children[1].children[0].children[0].value = 'winner';
        }
        item.children[2].children[0].value = 2;
      }
    });
  };

  const handleBetTypeChange = (e) => {
    setBetType({ ...betType[e.target.value] });
    setNumSelections(null);
    setOutcomeSelection([...Array(betType[e.target.value].num_of_rows)].map(() => 'winner'));

    if (numSelectionRef.current) {
      numSelectionRef.current.value = betType[e.target.value].num_of_rows;
    }

    resetOutcomeRows();
  };

  const handleFoldOption = (e) => setFoldOption(e.target.value);
  const handleRuleFourChange = (e) => setRuleFour(e.target.value);
  const handleEachWayChange = (e) => setEachWay(e.target.value);
  const handleMultipleOption = (e) => setMultipleOption(e.target.value);
  const handleStakeChange = (e) => setStake(parseInt(e.target.value));
  const handleOutcomeSelection = (e, index) => {
    const outcomeSelectionClone = outcomeSelection;
    outcomeSelectionClone[index] = e.target.value;
    setOutcomeSelection([...outcomeSelectionClone]);
  };

  const handleNumSelectionChange = (e) => {
    setNumSelections(e.target.value);

    if (outcomeSelection.length + 1 > e.target.value) {
      setOutcomeSelection(outcomeSelection.slice(0, e.target.value));
    } else {
      const arrDifference = parseInt(e.target.value) - outcomeSelection.length;
      setOutcomeSelection([...outcomeSelection, ...[...Array(arrDifference)].map(() => 'winner')]);
    }

    if (parseInt(e.target.value) > 3) {
      const foldDynamicFields = [...Array(parseInt(e.target.value) - 3)].map((item, index) => ({
        name: `${index + 4}-Fold`,
        type: 'decimal',
      }));

      setFoldTableRows([...foldTableRows, ...foldDynamicFields]);
    }
  };

  const resetCalculation = () => {
    handleBetTypeChange({ target: { value: 0 } });
    setStake(parseInt(0));
    stakeRef.current.value = null;
    if (betTypeRef.current) {
      betTypeRef.current.value = 0;
    }
  };

  const getColspan = () => {
    if (ruleFour === 'Yes' && eachWay === 'Yes') {
      return 4;
    }
    if ((ruleFour === 'Yes' && eachWay === 'No') || (ruleFour === 'No' && eachWay === 'Yes')) {
      return 3;
    }
    return 2;
  };

  const updateTotals = (totals) => {
    const [outlay, totReturn, profit] = totals;
    totalOutlayRef.current.innerText = !isNaN(totReturn) ? outlay : '-';
    totalReturnRef.current.innerText = !isNaN(totReturn) ? totReturn : '-';
    totalProfitRef.current.innerText = !isNaN(totReturn) ? profit : '-';
  };

  const updateFoldTotals = (totals) => {
    totals.map((total, index) => {
      const [totalOutlayOutput, totalReturnOutput, profitOutput] = total;
      foldTableRefs.current[index].children[2].innerText = totalOutlayOutput;
      foldTableRefs.current[index].children[3].innerText = totalReturnOutput;
      foldTableRefs.current[index].children[4].innerText = profitOutput;
    });
  };

  useEffect(() => {
    resetOutcomeRows(true);
  }, [activeBetType]);

  useEffect(() => {
    resetOutcomeRows(false);
  }, [outcomeSelection]);

  const calculateTotalBet = useCallback(() => {
    let totalReturn = 0;
    let betCount = 0;

    const [selectionsOdds, outcomes] = getSelectionOddsAndOutcomes(
      outcomesTableRefs.current,
      deadHeatRefs.current,
      ruleFour,
      eachWay,
      addNotes === 'Yes'
    );

    // eslint-disable-next-line eqeqeq
    if (activeBetType.name === 'Accumulator' && foldOption == 2) {
      const output = calculateFoldOptions(
        selectionsOdds,
        foldTableRefs.current,
        activeBetType.name,
        eachWay,
        multipleOptions,
        stakeTypeRef.current.value
      );

      updateFoldTotals(output[0]);
      updateTotals(output[1]);

      return;
    }

    let returnAndBetCount = [];

    if (activeBetType.name === 'Alphabet') {
      returnAndBetCount = calculateForAlphabet(
        stake,
        selectionsOdds,
        betType,
        eachWay,
        multipleOptions
      );
    } else if (activeBetType.name.startsWith('Unionjack')) {
      returnAndBetCount = calculateForUnionJack(
        stake,
        selectionsOdds,
        activeBetType,
        eachWay,
        multipleOptions
      );
    } else {
      returnAndBetCount = doTheCalculations(
        activeBetType.name,
        activeBetType.types,
        eachWay,
        multipleOptions,
        selectionsOdds,
        stake
      );
    }

    totalReturn += returnAndBetCount[0];
    betCount += returnAndBetCount[1];

    if (eachWay === 'No') {
      totalReturn = applyBookmakerBonuses(
        activeBetType,
        outcomes,
        stake,
        totalReturn,
        bookmakerBonusRef.current ? bookmakerBonusRef.current.value : 0,
        oneWinnerConsolationRef.current ? oneWinnerConsolationRef.current.value : '1',
        oneLoserBonusRef.current ? oneLoserBonusRef.current.value : 0
      );
    }

    const [totalReturnOutput, totalOutlayOutput, profitOutput] = getTheOutputResult(
      stake,
      stakeTypeRef.current.value,
      totalReturn,
      betCount
    );

    updateTotals([totalOutlayOutput, totalReturnOutput, profitOutput]);
  });

  useEffect(() => {
    calculateTotalBet(parseInt(stake));
  }, [
    activeBetType,
    eachWay,
    ruleFour,
    multipleOptions,
    stake,
    outcomeSelection,
    calculateTotalBet,
  ]);

  return (
    <div className={styles?.container || ''}>
      <div className={styles.innerContainer || ''}>
        <h2>{useTranslate('horsecalc_main_title', mainTitle)}</h2>
        <div>
          <div>
            <div className={styles.selectes}>
              <Select
                id="bettype"
                label="Bet type:"
                tooltip="Bet Calculator - All Types & Options"
                onChangeFunc={handleBetTypeChange}
                options={betType.map((type, index) => (
                  <option key={keygen()} value={index}>
                    {type.name}
                  </option>
                ))}
                refObj={betTypeRef}
                tooltipMinWidth={tooltipMinWidth}
                customClass={styles.selectesSelect}
              />

              <Select
                id="eachway"
                label="Each way?"
                tooltip="Whether you are calculating an each way bet. Two individual bets of equal amount, one placed on the selection to win and the other on the same selection to place."
                onChangeFunc={handleEachWayChange}
                options={[
                  <option value="Yes">{useTranslate('yes', 'Yes')}</option>,
                  <option selected value="No">
                    {useTranslate('no', 'No')}
                  </option>,
                ]}
                tooltipMinWidth={tooltipMinWidth}
                customClass={styles.selectesSelect}
              />

              {eachWay === 'Yes' && activeBetType.multiple_options && (
                <Select
                  id="multiple_options"
                  label="Multiple Options:"
                  tooltip="Various bet combinations"
                  onChangeFunc={handleMultipleOption}
                  options={[
                    <option value="1">
                      {useTranslate(
                        'horsecalc_multioptions_default',
                        'Default - Win-to-Win, Place-to-Place'
                      )}
                    </option>,
                    <option value="2">
                      {useTranslate(
                        'horsecalc_multioptions_advanced',
                        'Advanced - Equally Divided (All EW)'
                      )}
                    </option>,
                  ]}
                  tooltipMinWidth={tooltipMinWidth}
                  customClass={styles.selectesSelect}
                />
              )}

              {activeBetType.show_num_selection && (
                <Select
                  id="num_of_selection"
                  label="Number of selections:"
                  tooltip="Pick how many horses you want to track below!"
                  onChangeFunc={handleNumSelectionChange}
                  options={[...Array(numSelection)].map((e, i) => (
                    <option key={keygen()} value={i + 1}>
                      {i + 1}
                    </option>
                  ))}
                  refObj={numSelectionRef}
                  tooltipMinWidth={tooltipMinWidth}
                  customClass={styles.selectesSelect}
                />
              )}

              <Select
                id="rulefour"
                label="Show rule 4?"
                tooltip="Used in horse racing to adjust winnings when runners are withdrawn before the race."
                onChangeFunc={handleRuleFourChange}
                options={[
                  <option value="Yes">{useTranslate('yes', 'Yes')}</option>,
                  <option selected value="No">
                    {useTranslate('no', 'No')}
                  </option>,
                ]}
                tooltipMinWidth={tooltipMinWidth}
                customClass={styles.selectesSelect}
              />
            </div>
            <div className={styles.stakeType}>
              <Select
                id="stake_type"
                label="Stake Type:"
                refObj={stakeTypeRef}
                options={[
                  <option value="1" selected>
                    {useTranslate('horsecalc_staketype_stakeperbet', 'Stake per Bet')}
                  </option>,
                  <option value="2">
                    {useTranslate('horsecalc_staketype_totalcombinedstake', 'Total Combined Stake')}
                  </option>,
                ]}
                tooltipMinWidth={tooltipMinWidth}
                customClass={styles.stakeTypeSelect}
              />
              {!(activeBetType.name === 'Accumulator' && foldOption === '2') && (
                <label htmlFor="stake">
                  {useTranslate('stake', 'Stake:')}
                  <div
                    data-curr-symbol={useTranslate('horse_racing_currency', '')}
                    className={styles?.currencyInput || ''}
                  >
                    <input
                      ref={stakeRef}
                      placeholder="0.00"
                      type="number"
                      onChange={handleStakeChange}
                    />
                  </div>
                </label>
              )}
            </div>
          </div>

          <table className={styles?.overflowTable || ''}>
            <tbody>
              {activeBetType &&
                [
                  ...Array(
                    activeBetType.num_of_rows !== outcomeSelection.length
                      ? outcomeSelection.length
                      : activeBetType.num_of_rows
                  ),
                ].map((item, index) => (
                  <React.Fragment key={keygen()}>
                    <tr
                      className={`${
                        outcomeSelection[index] === 'dead_heat' ? styles.deadHeatEnabled || '' : ''
                      } ${addNotes === 'Yes' ? styles.selectionNotesEnabled || '' : ''}`}
                      ref={(el) => (outcomesTableRefs.current[index] = el)}
                    >
                      {addNotes === 'No' && <td>{index + 1}</td>}
                      <td
                        aria-label={useTranslate('ariaLabel-outcome', 'outcome')}
                        className={`${styles.outComing} ${styles.cells}`}
                      >
                        <Select
                          // label="Outcome:"
                          id={`outcome-${index}`}
                          onChangeFunc={handleOutcomeSelection}
                          options={outcomeOptions.map((option) => (
                            <option key={keygen()} value={option.value}>
                              {option.name}
                            </option>
                          ))}
                          index={index}
                          tooltipMinWidth={tooltipMinWidth}
                          customClass={styles.overflowTableSelect}
                        />
                      </td>
                      <td
                        aria-label={useTranslate('ariaLabel-odds', 'odds')}
                        className={`${styles.cells} ${styles.odds}${
                          outcomeSelection[index] === 'lost' || outcomeSelection[index] === 'void'
                            ? styles.displayNone || ''
                            : ''
                        }`}
                      >
                        <label>
                          <input
                            onChange={calculateTotalBet}
                            className={
                              outcomeSelection[index] === 'lost' ||
                              outcomeSelection[index] === 'void'
                                ? styles.displayNone || ''
                                : ''
                            }
                            type="number"
                            placeholder={2}
                          />
                        </label>
                      </td>
                      {eachWay === 'Yes' && (
                        <td
                          aria-label={useTranslate('ariaLabel-placeOdds', 'place odds')}
                          className={`${styles?.placeOdds} ${styles.cells} ${styles.placeOdds}`}
                        >
                          <Select
                            id="place_odds"
                            onChangeFunc={calculateTotalBet}
                            options={placeOddsoptions.map((option) => (
                              <option key={keygen()} value={option}>
                                {option}
                              </option>
                            ))}
                            tooltipMinWidth={tooltipMinWidth}
                            customClass={styles.overflowTableSelect}
                          />
                        </td>
                      )}
                      {ruleFour === 'Yes' && (
                        <td
                          aria-label={useTranslate('ariaLabel-ruleFour', 'rule four')}
                          className={`${styles.cells} ${styles.ruleFour}`}
                        >
                          <Select
                            id="rule_four"
                            onChangeFunc={calculateTotalBet}
                            options={ruleFourOptions.map((option) => (
                              <option key={keygen()} value={option}>
                                {option}
                              </option>
                            ))}
                            tooltipMinWidth={tooltipMinWidth}
                            customClass={styles.overflowTableSelect}
                          />
                        </td>
                      )}
                    </tr>
                    <tr
                      className={`${styles?.deadHeatRow || ''} ${
                        outcomeSelection[index] !== 'dead_heat' && styles.displayNone
                      }`}
                      ref={(el) => (deadHeatRefs.current[index] = el)}
                    >
                      {outcomeSelection[index] === 'dead_heat' && (
                        <>
                          <td aria-label={useTranslate('ariaLabel-hidden', 'hidden')} />
                          <td colSpan={getColspan()}>
                            <div className={styles?.deadHeat || ''}>
                              <Select
                                id="tiedposition"
                                label="Tied position"
                                onChangeFunc={calculateTotalBet}
                                options={[...Array(16)].map((e, i) => (
                                  <option key={keygen()} value={i + 1}>
                                    {i + 1}
                                  </option>
                                ))}
                                tooltipMinWidth={tooltipMinWidth}
                                customClass={styles.overflowTableSelect}
                              />
                              <Select
                                id="deadheatrunners"
                                onChangeFunc={calculateTotalBet}
                                label="Number of runnners in dead heat:"
                                options={[...Array(16)].map((e, i) => (
                                  <option key={keygen()} value={i + 1}>
                                    {i + 1}
                                  </option>
                                ))}
                                tooltipMinWidth={tooltipMinWidth}
                                customClass={styles.overflowTableSelect}
                              />
                              <Select
                                id="placesoffered"
                                label="Places Offered"
                                onChangeFunc={calculateTotalBet}
                                options={[...Array(16)].map((e, i) => (
                                  <option key={keygen()} value={i + 1}>
                                    {i + 1}
                                  </option>
                                ))}
                                tooltipMinWidth={tooltipMinWidth}
                                customClass={styles.overflowTableSelect}
                              />
                            </div>
                          </td>
                        </>
                      )}
                    </tr>
                  </React.Fragment>
                ))}
            </tbody>
          </table>

          {activeBetType.name === 'Accumulator' && (
            <>
              <div className={styles?.fullWidth || ''}>
                <Select
                  id="fold_option"
                  label="Fold options:"
                  refObj={foldOptionRef}
                  tooltip="Accumulator - A Single Bet on up to 20 Selections"
                  onChangeFunc={handleFoldOption}
                  options={[
                    <option value="1">{useTranslate('disabled', 'Disabled')}</option>,
                    <option value="2">{useTranslate('enabled', 'Enabled')}</option>,
                  ]}
                  tooltipMinWidth={tooltipMinWidth}
                />
              </div>
              {foldOption === '2' && (
                <div className={styles.scrollTable}>
                  <table className={styles?.foldTable || ''}>
                    <thead>
                      <tr>
                        <th>{useTranslate('horsecalc_fold', 'Fold')}</th>
                        <th>{useTranslate('horsecalc_stake', 'Stake')}</th>
                        <th>{useTranslate('horsecalc_outlay', 'Outlay')}</th>
                        <th>{useTranslate('horsecalc_return', 'Return')}</th>
                        <th>{useTranslate('horsecalc_profit', 'Profit')}</th>
                      </tr>
                    </thead>
                    <tbody>
                      {foldTableRows.map((row, index) => (
                        <tr key={keygen()} ref={(el) => (foldTableRefs.current[index] = el)}>
                          <td>{row.name}</td>
                          <td aria-label={useTranslate(`ariaLabel-${row.name}`, row.name)}>
                            <input
                              type="number"
                              onChange={calculateTotalBet}
                              step={row.type === 'decimal' ? 0.01 : 0}
                            />
                          </td>
                          <td>-</td>
                          <td>-</td>
                          <td>-</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </>
          )}
          {activeBetType.bookmakerBonus && (
            <>
              <div className={styles.extraFields}>
                <label htmlFor="bookmaker_bonus">
                  {useTranslate('bookmaker_bonuses', 'Bookmaker bonuses:')}
                  <input type="number" ref={bookmakerBonusRef} id="bookmaker_bonus" />
                </label>
                {activeBetType.oneLoserBonus && (
                  <label htmlFor="one_loser_bonus">
                    {useTranslate('looser_bonuses', 'One loser bonus %:')}
                    <input type="number" ref={oneLoserBonusRef} id="one_loser_bonus" />
                  </label>
                )}
              </div>
              {activeBetType.oneWinnerConsolation && (
                <div className={styles?.fullWidth || ''}>
                  <Select
                    id="one_winner_consolation"
                    label="One Winner Consolation:"
                    refObj={oneWinnerConsolationRef}
                    onChangeFunc={handleFoldOption}
                    options={[
                      <option value="0" selected="">
                        {useTranslate('horsecalc_none', 'None')}
                      </option>,
                      <option value="2">
                        {useTranslate('horsecalc_double_odds', 'Double Odds')}
                      </option>,
                      <option value="3">
                        {useTranslate('horsecalc_triple_odds', 'Triple Odds')}
                      </option>,
                      <option value="4">
                        {useTranslate('horsecalc_quadruple_odds', 'Quadruple Odds')}
                      </option>,
                      <option value="5">
                        {useTranslate('horsecalc_quintuple_odds', 'Quintuple Odds')}
                      </option>,
                    ]}
                    tooltipMinWidth={tooltipMinWidth}
                  />
                </div>
              )}
            </>
          )}

          <div className={styles.outcomeTable || ''}>
            <div>
              <p>{useTranslate('horsecalc_total_outlay', 'Total Outlay')}</p>
              <span ref={totalOutlayRef}>-</span>
            </div>
            <div>
              <p>{useTranslate('horsecalc_total_return', 'Total Return')}</p>
              <span ref={totalReturnRef}>-</span>
            </div>
            <div>
              <p>{useTranslate('horsecalc_total_profit', 'Total Profit')}</p>
              <span ref={totalProfitRef}>-</span>
            </div>
          </div>
        </div>
        <div className={styles?.ctaContainer || ''}>
          <Button
            onClick={() => resetCalculation()}
            btnText={useTranslate('reset-calculation', 'Reset Calculation')}
            isInternalLink={false}
            buttonType="tertiary"
            buttonSize="m"
            icon={null}
          />
        </div>
      </div>
    </div>
  );
};

export default HorseCalculator;

HorseCalculator.propTypes = {
  mainTitle: PropTypes.string,
  tooltipMinWidth: PropTypes.number,
};
