package parser;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.gargoylesoftware.htmlunit.ElementNotFoundException;

import object.ResultDTO;

public class NordicBetParser extends ParserBase {

    List<ResultDTO> parsedMatches = new ArrayList<>();

    public List<ResultDTO> parseSoccerMatches() {
        String url = "https://d-cf.ndbplayground.net/stc--187551415/stc--187551415/fotboll";
        ChromeDriver driver = getSeleniumDriver();

        driver.manage().deleteAllCookies();
        driver.get(url);
        JavascriptExecutor js = driver;
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions
                .numberOfElementsToBeMoreThan(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"), 0));

        List<WebElement> matchDivs = driver
                .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));

        List<WebElement> expandableDivs = driver
                .findElements(By.xpath(
                        "//div[contains(@class, 'obg-m-events-master-detail-header') and not(contains(@class, 'expanded'))]"));

        // leta upp child span med text "kommande idag" och kanske "imorgon"
        // Behöver också kolla om det finns mer att ladda obg-show-more-less-button
        // ng-star-inserted
        // Kontrollera att det inte står "Show less" då den minimerar igen
        for (WebElement element : expandableDivs) {
            try {
                String xpath = ".//span[text()='Live']";
                if (checkIfElementExists(element, xpath)) {
                    element.click();
                    wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                            "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                    Thread.sleep(200);
                    matchDivs = driver
                            .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                    scrollElementIntoView(driver, element);
                }

                xpath = ".//span[text()='Kommande idag']";
                if (checkIfElementExists(element, xpath)) {
                    element.click();
                    wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                            "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                    Thread.sleep(200);
                    matchDivs = driver
                            .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                    scrollElementIntoView(driver, element);

                }

                xpath = ".//span[text()='Imorgon']";
                if (checkIfElementExists(element, xpath)) {
                    element.click();
                    wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                            "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                    Thread.sleep(200);
                    matchDivs = driver
                            .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                    scrollElementIntoView(driver, element);
                }

            } catch (ElementNotFoundException | InterruptedException e) {
                // Empty by design, no more matches today
            }
        }

        expandAllMatches(driver, wait, matchDivs);

        matchDivs = driver
                .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));

        js.executeScript("window.stop;");
        for (WebElement match : matchDivs) {
            scrollElementIntoViewCenter(driver, match);
            parseMatch(driver, match);
        }
        System.out.println("found " + matchDivs.size() + " matches");

        driver.close();
        return parsedMatches;
    }

    private void expandAllMatches(ChromeDriver driver, WebDriverWait wait, List<WebElement> matchDivs) {
        List<WebElement> buttons = driver
                .findElements(By.xpath("//button[contains(@class,'obg-show-more-less-button')]"));

        for (WebElement button : buttons) {
            WebElement findElement = button.findElement(By.xpath(".//span"));
            while (!findElement.getText().contains("less")) {
                button.click();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                findElement = button.findElement(By.xpath(".//span"));
            }

        }

        if (buttons.size() > 0) {
            wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                    "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
        }
    }

    private void parseMatch(ChromeDriver driver, WebElement match) {
        // teams div, two div children with hometeam awayTeam
        // "class obg-event-info-participant obg-event-info-participant-default-layout"
        try {
            List<WebElement> participants = match
                    .findElements(By.xpath(".//div[@class='obg-event-info-participant-label ng-star-inserted']"));

            String homeTeamName = participants.get(0).getAttribute("title");
            String awayTeamName = participants.get(1).getAttribute("title");

            List<WebElement> oddsContainers = match.findElements(By.xpath(".//obg-event-row-market-container"));

            Optional<WebElement> matchOddsContainer = oddsContainers.stream()
                    .filter(p -> checkIfElementExists(p, ".//header//div//span")
                            ? p.findElement(By.xpath(".//header/div/span"))
                                    .getText().equals("Matchresultat")
                            : Boolean.FALSE)
                    .findFirst();

            float odds1 = -1f;
            float oddsX = -1f;
            float odds2 = -1f;
            if (matchOddsContainer.isPresent()) {
                List<WebElement> oddsValueContainers = matchOddsContainer.get()
                        .findElements(By.xpath(".//section//span[@test-id='odds']"));

                if (!oddsValueContainers.isEmpty()) {
                    odds1 = formatFloat(oddsValueContainers.get(0).getText());
                    oddsX = formatFloat(oddsValueContainers.get(1).getText());
                    odds2 = formatFloat(oddsValueContainers.get(2).getText());
                }

            }

            float oddsOver25 = -1f;
            float oddsUnder25 = -1f;

            Optional<WebElement> numberOfGoalsContainer = oddsContainers.stream()
                    .filter(p -> checkIfElementExists(p, ".//header/div/span")
                            ? p.findElement(By.xpath(".//header/div/span"))
                                    .getText().toLowerCase().trim().contains("antal mål")
                            : Boolean.FALSE)
                    .findFirst();

            if (numberOfGoalsContainer.isPresent()) {
                List<WebElement> overUnderElements = numberOfGoalsContainer.get()
                        .findElements(By.xpath(".//section//span[contains(@class, 'obg-selection-content-label')]"));

                for (WebElement element : overUnderElements) {
                    WebElement oddsElement = element.findElement(By.xpath(".//..//..//span[@test-id='odds']"));
                    if (element.getText().trim().equals("över 2.5")) {
                        oddsOver25 = formatFloat(oddsElement.getText());
                    } else if (element.getText().trim().equals("under 2.5")) {
                        oddsUnder25 = formatFloat(oddsElement.getText());
                    }
                }
            }

            parsedMatches.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2, oddsOver25, oddsUnder25));
            System.out.println(homeTeamName + "-" + awayTeamName + " odds (" + odds1 + "," + oddsX + "," + odds2 + ")"
                    + " overUnder: " + oddsOver25 + "/" + oddsUnder25);
        } catch (StaleElementReferenceException e) {
//            System.out.println("Stale element, refreshing");
//            driver.navigate().refresh();
//            parseMatch(driver, match);
        }
    }
}
