package ru.otus.mobile.page;

import com.codeborne.selenide.CollectionCondition;
import com.codeborne.selenide.Condition;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.WebDriverRunner;
import com.codeborne.selenide.appium.SelenideAppiumCollection;
import io.appium.java_client.AppiumBy;
import ru.otus.mobile.config.MobileConfig;

import static com.codeborne.selenide.appium.SelenideAppium.$$;
import static com.codeborne.selenide.appium.SelenideAppium.$;

public abstract class AbsPageObject {
    private final MobileConfig config;

    protected AbsPageObject(MobileConfig config) {
        this.config = config;
    }

    protected SelenideElement byId(String id) {
        return $(AppiumBy.id(fullId(id)));
    }

    protected SelenideAppiumCollection allById(String id) {
        return $$(AppiumBy.id(fullId(id)));
    }

    protected SelenideElement byText(String text) {
        return $(AppiumBy.androidUIAutomator("new UiSelector().text(\"" + escape(text) + "\")"));
    }

    protected SelenideElement byTextContains(String text) {
        return $(AppiumBy.androidUIAutomator("new UiSelector().textContains(\"" + escape(text) + "\")"));
    }

    protected SelenideElement byUiAutomator(String selector) {
        return $(AppiumBy.androidUIAutomator(selector));
    }

    protected SelenideElement byXpath(String xpath) {
        return $(AppiumBy.xpath(xpath));
    }

    protected void type(String id, String value) {
        SelenideElement input = byId(id).shouldBe(Condition.visible);
        input.click();
        input.clear();
        input.sendKeys(value);
    }

    protected void tap(String id) {
        byId(id).shouldBe(Condition.visible).click();
    }

    protected boolean exists(String id) {
        return byId(id).exists();
    }

    protected void shouldHaveItems(String id) {
        allById(id).shouldHave(CollectionCondition.sizeGreaterThan(0));
    }

    protected SelenideElement scrollToText(String text) {
        String selector = "new UiScrollable(new UiSelector().scrollable(true))"
                + ".scrollIntoView(new UiSelector().textContains(\"" + escape(text) + "\"))";
        return $(AppiumBy.androidUIAutomator(selector));
    }

    protected void back() {
        WebDriverRunner.getWebDriver().navigate().back();
    }

    protected String xpathLiteral(String value) {
        if (!value.contains("\"")) {
            return "\"" + value + "\"";
        }
        if (!value.contains("'")) {
            return "'" + value + "'";
        }
        String[] parts = value.split("\"");
        StringBuilder builder = new StringBuilder("concat(");
        for (int i = 0; i < parts.length; i++) {
            if (i > 0) {
                builder.append(", '\"', ");
            }
            builder.append("\"").append(parts[i]).append("\"");
        }
        builder.append(")");
        return builder.toString();
    }

    private String fullId(String id) {
        if (id.contains(":")) {
            return id;
        }
        return config.appPackage() + ":id/" + id;
    }

    private String escape(String value) {
        return value.replace("\"", "\\\"");
    }
}
