package main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import object.ArbResults;
import parser.BWinParser;
import parser.BetHard;
import parser.BetSafeParser;
import parser.ExpektParser;
import parser.NordicBetParser;

public class ArbChecker {

    private List<ArbResults> nordicBetMatches = new ArrayList<>();
    private List<ArbResults> expektResults = new ArrayList<>();
    private List<ArbResults> betSafeResults = new ArrayList<>();
    private List<ArbResults> betHardResults = new ArrayList<>();
    private List<ArbResults> bWinResults = new ArrayList<>();

    public ArbChecker() {
        NordicBetParser nbp = new NordicBetParser();
        nordicBetMatches.addAll(nbp.parseSoccerMatches().stream().map(m -> new ArbResults(m, "NordicBet")).toList());
        printResultsToArrayFile(nordicBetMatches, "NordicBet.csv");

        ExpektParser ep = new ExpektParser();
        expektResults.addAll(ep.seleniumParseSoccerMatches().stream().map(m -> new ArbResults(m, "Expekt")).toList());
        printResultsToArrayFile(expektResults, "Expekt.csv");

        BetSafeParser bsp = new BetSafeParser();
        betSafeResults.addAll(bsp.seleniumPaseSoccerMatches().stream().map(m -> new ArbResults(m, "BetSafe")).toList());
        printResultsToArrayFile(betSafeResults, "BetSafe.csv");

        BetHard bh = new BetHard();
        betHardResults.addAll(bh.seleniumParseMatches().stream().map(m -> new ArbResults(m, "BetHard")).toList());
        printResultsToArrayFile(betHardResults, "BetHard.csv");

        BWinParser bwin = new BWinParser();
        bWinResults.addAll(bwin.parseSoccerMatches().stream().map(m -> new ArbResults(m, BWinParser.BOOKIE)).toList());
        printResultsToArrayFile(bWinResults, BWinParser.BOOKIE + ".csv");

        getResultsFromFile("NordicBet.csv", nordicBetMatches, "NordicBet");
        getResultsFromFile("Expekt.csv", expektResults, "Expekt");
        getResultsFromFile("BetSafe.csv", betSafeResults, "BetSafe");
        getResultsFromFile("BetHard.csv", betHardResults, "BetHard");
        getResultsFromFile(BWinParser.BOOKIE + ".csv", bWinResults, BWinParser.BOOKIE);

        List<SimpleEntry<String, List<ArbResults>>> resultLists = new ArrayList<>();
        SimpleEntry<String, List<ArbResults>> entryNordicBet = new SimpleEntry<>("NordicBet", this.nordicBetMatches);
        SimpleEntry<String, List<ArbResults>> betSafe = new SimpleEntry<>("BetSafe", this.betSafeResults);
        SimpleEntry<String, List<ArbResults>> betHard = new SimpleEntry<>("BetHard", this.betHardResults);
        SimpleEntry<String, List<ArbResults>> expekt = new SimpleEntry<>("Expekt", this.expektResults);
        SimpleEntry<String, List<ArbResults>> bwinEntries = new SimpleEntry<>(BWinParser.BOOKIE, this.bWinResults);

        resultLists.add(expekt);
        resultLists.add(entryNordicBet);
        resultLists.add(betSafe);
        resultLists.add(betHard);
        resultLists.add(bwinEntries);
        checkForArbs(resultLists);

    }

    private void checkForArbs(List<SimpleEntry<String, List<ArbResults>>> resultLists) {
        ArrayList<ArbResults> addedMatches = new ArrayList<>();

        String replaceParentecesRegEx = "\\(.*\\)| [A-Za-z]{2} |Club|club|II|FC|NK|AL|Al";

        for (SimpleEntry<String, List<ArbResults>> list : resultLists) {
            for (ArbResults match : list.getValue()) {

                List<String> homeTeamParts =
                        Arrays.asList(match.getHomeTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));
                List<String> awayTeamParts =
                        Arrays.asList(match.getAwayTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));

                List<ArbResults> homeTeamFound =
                        addedMatches.stream().filter(p -> p.getHomeTeam().replaceAll(replaceParentecesRegEx, "").trim().equals(match.getHomeTeam().replaceAll(replaceParentecesRegEx, "").trim())).toList();

                List<ArbResults> awayTeamFound =
                        addedMatches.stream().filter(p -> p.getAwayTeam().replaceAll(replaceParentecesRegEx, "").trim().equals(match.getAwayTeam().replaceAll(replaceParentecesRegEx, "").trim())).toList();

                if (homeTeamFound.isEmpty() || awayTeamFound.isEmpty()) {
                    addedMatches.add(new ArbResults(match.getHomeTeam(), match.getAwayTeam(), match.getOdds1(),
                            match.getOddsX(), match.getOdds2(), list.getKey()));
                } else if (homeTeamFound.size() == 1) {
                    homeTeamFound.get(0).addOdds1(list.getKey(), match.getOdds1());
                    homeTeamFound.get(0).addOddsX(list.getKey(), match.getOddsX());
                    homeTeamFound.get(0).addOdds2(list.getKey(), match.getOdds2());

                    homeTeamFound.get(0).addOver25Odds(list.getKey(), match.getOver25());
                    homeTeamFound.get(0).addUnder25Odds(list.getKey(), match.getUnder25());
                } else if (awayTeamFound.size() == 1) {
                    awayTeamFound.get(0).addOdds1(list.getKey(), match.getOdds1());
                    awayTeamFound.get(0).addOddsX(list.getKey(), match.getOddsX());
                    awayTeamFound.get(0).addOdds2(list.getKey(), match.getOdds2());

                    awayTeamFound.get(0).addOver25Odds(list.getKey(), match.getOver25());
                    awayTeamFound.get(0).addUnder25Odds(list.getKey(), match.getUnder25());
                } else if (homeTeamFound.size() > 1) {
                    for (ArbResults htf : homeTeamFound) {
                        Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(),
                                this.getClass().getEnclosingMethod().getName(), "Multiple " + "found home " + htf);
                    }
                } else if (awayTeamFound.size() > 1) {
                    for (ArbResults atf : awayTeamFound) {
                        Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(),
                                this.getClass().getEnclosingMethod().getName(), "Multiple found away " + atf);
                    }
                }
            }
        }

        List<ArbResults> GOGOList = new ArrayList<>();
        for (ArbResults match : addedMatches) {
            if (match.multipleOddsExist()) {
                if (calculateArbValue3Part(match) < 1.0f || match.getArbValueOverUnder() > 0f && match.getArbValueOverUnder() < 1.0f) {
                    GOGOList.add(match);
                } else {
                    System.out.println("Result " + match.toStringWithExtra() + " arb value " + calculateArbValue3Part(match) + " OverUnderVal " + match.getArbValueOverUnder());
                }
            }
        }
        for (ArbResults match : GOGOList) {
            System.out.println("GOGOGOGOGOGO Result " + match.toStringWithExtra() + " arb value " + calculateArbValue3Part(match) + " Over Under arb value" + match.getArbValueOverUnder());
        }
    }

    private float calculateArbValue3Part(ArbResults res) {
        return (1 / res.getMaxOdds1().getOdds()) + (1 / res.getMaxOddsX().getOdds()) + (1 / res.getMaxOdds2().getOdds());
    }

    private void printResultsToArrayFile(List<ArbResults> results, String fileName) {
        try (BufferedWriter bw =
                     new BufferedWriter(new FileWriter(System.getProperty("user.dir") + File.separator + fileName))) {
            StringBuilder sb = new StringBuilder();

            for (ArbResults r : results) {
                sb.append(r.toString());
                sb.append(System.lineSeparator());
            }

            bw.write(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void getResultsFromFile(String fileName, List<ArbResults> resultsList, String bookie) {
        try (BufferedReader br =
                     new BufferedReader(new FileReader(System.getProperty("user.dir") + File.separator + fileName))) {

            String line;
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                resultsList.add(new ArbResults(values[0], values[1], Float.parseFloat(values[2]),
                        Float.parseFloat(values[3]), Float.parseFloat(values[4]), Float.parseFloat(values[5]),
                        Float.parseFloat(values[6]), bookie));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
