package ru.kovbasa.pages;

import com.microsoft.playwright.Locator;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.options.AriaRole;
import ru.kovbasa.playwright.TestConfig;

public class SubscriptionPage extends BasePage {

    public SubscriptionPage(Page page, TestConfig config) {
        super(page, config);
    }

    public void open() {
        openPath("/subscription");
    }

    public Locator getSubscriptionTiles() {
        Locator section = page.locator("section, div").filter(
                new Locator.FilterOptions().setHasText("подписк")
        ).first();
        if (section.count() > 0) {
            section.scrollIntoViewIfNeeded();
        }
        Locator tiles = section.locator("[data-qa*='tariff'], [class*='tariff'],"
                + " [class*='subscription'], [class*='card']");
        if (tiles.count() == 0) {
            tiles = section.locator("div, article, li").filter(
                    new Locator.FilterOptions().setHasText("Купить")
            );
        }
        if (tiles.count() == 0) {
            tiles = page.locator("div, article, li").filter(
                    new Locator.FilterOptions().setHasText("Купить")
            );
        }
        return tiles;
    }

    public void expandDetails(Locator tile) {
        Locator toggle = tile.getByRole(AriaRole.LINK,
                new Locator.GetByRoleOptions().setName("Подробнее")).first();
        if (toggle.count() == 0) {
            toggle = tile.getByText("Подробнее").first();
        }
        toggle.click();
    }

    public void collapseDetails(Locator tile) {
        Locator toggle = tile.getByRole(AriaRole.LINK,
                new Locator.GetByRoleOptions().setName("Свернуть")).first();
        if (toggle.count() == 0) {
            toggle = tile.getByText("Свернуть").first();
        }
        toggle.click();
    }

    public boolean isDetailsExpanded(Locator tile) {
        return tile.getByText("Свернуть").first().isVisible();
    }

    public Locator getTrialCard() {
        Locator trialText = page.getByText("Trial").first();
        Locator trial = trialText.locator("xpath=ancestor::*[self::div or self::section or self::article][1]");
        if (trial.count() == 0) {
            trial = page.locator("div, section, article, li")
                    .filter(new Locator.FilterOptions().setHasText("Trial"))
                    .first();
        }
        return trial;
    }

    public String getPriceFromCard(Locator card) {
        String text = card.innerText();
        java.util.regex.Matcher matcher = java.util.regex.Pattern
                .compile("\\d+[\\d\\s\\u00A0]*\\s*(₽|руб)")
                .matcher(text);
        if (matcher.find()) {
            return matcher.group().trim();
        }
        matcher = java.util.regex.Pattern.compile("\\d+[\\d\\s\\u00A0]*").matcher(text);
        if (matcher.find()) {
            return matcher.group().trim();
        }
        return "";
    }

    public String getDurationFromCard(Locator card) {
        String text = card.innerText();
        java.util.regex.Matcher matcher = java.util.regex.Pattern
                .compile("(\\d+)\\s+месяц")
                .matcher(text);
        if (matcher.find()) {
            return matcher.group().trim();
        }
        return "";
    }

    public void selectTrialOnSubscription(Locator trialCard) {
        Locator button = trialCard.locator("a:visible:has-text('Оформить подписку'),"
                + " button:visible:has-text('Оформить подписку')").first();
        if (button.count() == 0) {
            button = trialCard.getByText("Trial").first();
        }
        button.click(new Locator.ClickOptions().setForce(true));
    }

    public Page clickBuy(Locator tile) {
        Page popup;
        tile.scrollIntoViewIfNeeded();
        Locator buy = tile.locator("a:visible:has-text('Купить'), button:visible:has-text('Купить')")
                .first();
        if (buy.count() == 0) {
            buy = tile.locator("a:visible[href*='pay'], a:visible[href*='checkout'],"
                    + " a:visible[href*='order'], a:visible[href*='subscribe'],"
                    + " button:visible[href*='pay']").first();
        }
        if (buy.count() == 0) {
            buy = page.locator("a:visible:has-text('Купить'), button:visible:has-text('Купить')")
                    .first();
        }
        Page result = clickWithNavigation(buy);
        if (!result.url().contains("/subscription")) {
            return result;
        }

        Locator trial = page.locator("section, div").filter(
                new Locator.FilterOptions().setHasText("Trial")
        ).first();
        Locator trialButton = trial.locator("a:visible:has-text('Оформить подписку'),"
                + " button:visible:has-text('Оформить подписку')").first();
        if (trialButton.count() > 0) {
            result = clickWithNavigation(trialButton);
        }
        return result;
    }

    private Page clickWithNavigation(Locator button) {
        Page popup;
        try {
            popup = page.waitForPopup(
                    new Page.WaitForPopupOptions().setTimeout(3000),
                    button::click
            );
        } catch (RuntimeException ex) {
            popup = null;
        }
        if (popup != null) {
            popup.waitForLoadState();
            return popup;
        }
        String before = page.url();
        try {
            button.click(new Locator.ClickOptions().setForce(true).setTimeout(5000));
        } catch (RuntimeException ex) {
            button.click(new Locator.ClickOptions().setForce(true).setTimeout(5000));
        }
        for (int i = 0; i < 8; i++) {
            if (!page.url().equals(before)) {
                page.waitForLoadState();
                return page;
            }
            page.waitForTimeout(1000);
        }
        return page;
    }
}
