const {SolveCaptcha, TWO_CAPTCHA_CONNECTION_FAILED} = require("./SolveCaptcha");
const ReserveResultPojo = require("../models/ReserveResultPojo");
const BlackListContactPojo = require("../models/BlackListContactPojo");
const appointmentLogger = require("../utiles/LoggerUtils")
const OCRResult = require("../models/OCRResult");
const PublishType = require("../models/PublishType");
const puppeteer = require('puppeteer');
const GeoCaptchaSolver = require("./GeoCaptchaSolver");
const SlidingCaptchaSolver = require("./SlidingCaptchaSolver");
const OCRChecker = require("./OCRChecker");
const {disconnect} = require("mongoose");
const {execSync} = require("child_process");
// const RDV_URL = "http://192.168.0.44:8000/test_appointment.html"
const RDV_URL = "https://rendezvousparis.hermes.com/client/register";
const BLANK_URL = "about:blank"
const ERROR_CAPTCHA_UNSOLVABLE = "ERROR_CAPTCHA_UNSOLVABLE";

const COUNTRY_ID = "#phone_country"
const PHONE_NUMBER = "#phone_number"
const EMAIL_ID = "#email"
const PREFER_STORE = "#prefer"
const LAST_NAME = "#surname"
const FIRST_NAME = "#name"
const CGU_ID = "#cgu"
const PROCESSING_ID = "#processing"
const PASSPORT_ID = "#passport_id"
const CAPTCHA_CONTAINER = "#captcha-container";

const TIME_OUT = 60 * 1000 * 4//4 mins

const EMPTY_RESPONSE_ERROR = "ERR_EMPTY_RESPONSE"
const MESSAGE_URL_VALIDATION_FR = "Nous avons envoyé un lien par e-mail."
const MESSAGE_URL_VALIDATION_EN = "Please click on the link we sent by email"
const REGEX_RDV_URL = "https:\/\/rendezvousparis\.hermes\.com\/client\/register\/[A-Z0-9]+"
const DEFAULT_STORE = 'faubourg';

const searchTexts = ['hermes+rdv+online+paris', 'hermes+rdv+enligne+paris', 'hermes+rdv+en+ligne+paris', 'hermes+rendezvous+en+ligne+paris', 'hermes+appointment+online+paris', 'hermes+appointment+online+paris', 'appointment+hermes+paris+on+line', 'hermes+rendez+vous+online+paris', 'hermes+rendez+vous+paris+en+ligne', 'hermes+rendez+vous+paris+enligne', 'hermes+rendez+vous+paris+online', 'online+appointment+hermes+paris', 'hermes+online+appointment+paris', 'paris+hermes+online+appointment']

function delay(delayInMs) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(2);
        }, delayInMs);
    });
}

function getRandom() {
    return Math.floor(Math.random() * 3);
}

function getRandomWaitTime() {
    return getRandom() * 1000
}

function log(message) {
    appointmentLogger.log({level: "info", message: message})
}

function logWithDevice(message, device) {
    appointmentLogger.log({level: "info", message: device.model() + ":" + message})
}

class CommandorPage {
    constructor(contact, device, mongoManager, selectedStore = DEFAULT_STORE, audioAnalyse = false, alertBeep = false, port = 9000) {
        this.contact = contact;
        this.device = device;
        this.mongoManager = mongoManager;
        this.selectedStore = selectedStore;
        this.choosedStore = selectedStore;
        this.port = port;
        this.ocrChecker = new OCRChecker(this.device, this.contact);
        // this.browserPackageName = "com.brave.browser";
        this.browserPackageName = "com.android.chrome";
        this.isFillingFields = false;
        this.isTerminated = false;
        this.cguChecked = false;
        this.isNameInput = false;
        this.isEmailFilled = false;
        this.isCountryChoosen = false;
        this.isPhoneInput = false;
        this.firstStart = true;
    }


    async connect_to_browser(ocrResult) {
        console.log("connect_to_browser() called");
        console.log("browser.isConnected: " + this.browser.isConnected());
        if (!this.browser.isConnected()) {
            this.browser = await puppeteer.connect({
                browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
                headless: false, defaultViewport: null
            })
        }
        let pages = await this.browser.pages();
        // 0 is the last page
        pages.forEach((currentPage) => {
            let url = currentPage.url()
            if (url.includes(RDV_URL)) {
                this.page = currentPage
            }
        })
        // this.page = pages[pages.length - 1];
        // this.page = pages[0];
        logWithDevice("pageUrl is " + this.page.url(), this.device)
        // this.page = pages[pages.length - 1];
        switch (ocrResult) {
            case OCRResult.SUCCESS:
                //         get url and push to server
                await this.push_message_to_queue(PublishType.SUCCESS)
                break;
            case OCRResult.TO_REFRESH:
                logWithDevice("will reload page", this.device)
                // if (this.browser.isConnected()) {
                //     await this.page.reload();
                //     await this.checkIfSuccessful()
                // } else {
                // await delay(10000);
                // if (!await this.checkIfSuccessful()) {
                let cmd = "input swipe 382 682 382 1682"
                logWithDevice("will send cmd:" + cmd, this.device)
                this.device.shell(cmd);
                await delay(3000);
                await this.clickOnConfirmBtn();
                await this.checkResultWithOcr();
                // }
                // }
                break;
        }
    }

    async checkIfSuccessful() {
        let content = await this.page.content();
        if (content.includes(MESSAGE_URL_VALIDATION_FR) || content.includes(MESSAGE_URL_VALIDATION_EN)) {
            log("successful");
            await this.push_message_to_queue(PublishType.SUCCESS);
            return true;
        } else {
            return false
        }
    }

    async loadPage() {
        this.device.shell("am start -n com.android.chrome/com.google.android.apps.chrome.Main")
        await delay(5 * 1000);
        // Connect to the device.
        logWithDevice("loadPage() called, with port:" + this.port, this.device);
        if (this.browser) {
            logWithDevice("browser.isConnected is " + this.browser.isConnected(), this.device);
        }
        try {
            logWithDevice("connecting to browser:" + this.port, this.device);
            while (this.browser === undefined || !this.browser.isConnected()) {
                this.browser = await puppeteer.connect({
                    browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
                    headless: false, defaultViewport: null
                })
                // let pages = await this.browser.pages();
                // this.page =  pages[0];
                this.page = await this.browser.newPage();

                this.page.on("load", (loadedPage) => {
                    this.onPageLoad(loadedPage);
                })

                this.page.on("response", (response) => {
                    this.onResponse(response)
                })
                await delay(3 * 1000);
            }
        } catch (e) {
            await this.checkResultWithOcr()
            console.log(e)
            // this.isTerminated = true
        }
        if (this.page !== undefined) {
            try {
                logWithDevice("will open google", this.device)
                if (!this.isTerminated) {
                    const item = searchTexts[Math.floor(Math.random() * searchTexts.length)];
                    await this.page.goto("https://www.google.com/search?q=" + item + "&lr=lang_en", {timeout: 30 * 1000});
                }
                // await this.page.goto(RDV_URL, {timeout: 90 * 1000});
            } catch (e) {
                log(e)
                this.isTerminated = true
            }
            await this.acceptCookies();
            await this.enableDisableAirPlanMode();
            await delay(10 * 1000);
            await this.clickOnlineAppointment();
            // await delay(2000);
            // if (!this.isTerminated)
            //     await this.clickOnlineAppointment();
        } else {
            this.isTerminated = true;
        }

        let cancel
        const intervalTask = setInterval(() => {
            if (this.isTerminated) {
                log(this.device.model() + ":request terminated, send cancel()");
                // this.resetBrowser();
                this.disconnectBrowser();
                clearInterval(intervalTask)
                cancel()
            } else {
            }
        }, 10 * 1000)//interval of 10 seconds

        await new Promise(function (fulfill, reject) {
            cancel = function () {
                fulfill(Promise.resolve())
            }
            setTimeout(fulfill, TIME_OUT, 5)
        }).then(log)
    }

    async clickOnlineAppointment() {
        try {
            logWithDevice("will click on rdv link", this.device);
            await this.connectBrowserIfNecessary();
            const [button] = await this.page.$x("//a[contains(., 'rendezvousparis')]");
            console.log("button is " + button)
            if (button) {
                console.log("will click on the button")
                try {
                    await button.click();
                    if (this.firstStart) {
                        this.disconnectBrowser()
                    }
                } catch (e) {
                    console.log(e)
                }
            }

            // if (this.page.url() === RDV_URL) {
            //     if (!this.isFillingFields)
            //         await this.fillFields(this.page, false);
            // }
        } catch (e) {
            log(e)
            await this.checkResultWithOcr();
        }
    }

    async acceptCookies() {
        logWithDevice("will accept Cookies", this.device);
        if (this.browser.isConnected()) {
            try {
                await this.page.evaluate(() => {
                    let buttons = document.getElementsByTagName('button');
                    for (let i = 0; i < buttons.length; i++) {
                        let button = buttons[i];
                        let txt = button.textContent || button.innerText;
                        if (txt.includes("Tout accepter")) {
                            button.click()
                        }
                        console.log(txt);
                    }
                })
            } catch (e) {
                console.log(e)
            }

        }
    }

    async chooseCountry(page) {
        if (this.browser.isConnected()) {
            try {
                if (!this.isCountryChoosen) {
                    await page.focus(COUNTRY_ID);
                    await delay(getRandomWaitTime())
                    await page.click(COUNTRY_ID);
                    await delay(getRandomWaitTime())
                    await page.select(COUNTRY_ID, 'FR');
                    await delay(getRandomWaitTime())
                    this.isCountryChoosen = true;
                }
            } catch (e) {
                log(e);
                this.isTerminated = true;
            }
        }
    }

    async fillEmail(page) {
        try {
            if (this.browser.isConnected()) {
                if (!this.isEmailFilled) {
                    await page.focus(EMAIL_ID);
                    await delay(getRandomWaitTime())
                    console.log("will clear email field");
                    await page.evaluate(() => {
                        let field = document.getElementById("email");
                        if (field) {
                            field.value = ""
                        }
                    })
                    await delay(1000);
                    await page.keyboard.type(this.contact.mail);
                    this.isEmailFilled = true;
                }
            }
        } catch (e) {
            log(e)
        }
    }

    async inputPhoneNumber(page) {
        try {
            if (this.browser.isConnected()) {
                if (!this.isPhoneInput) {
                    await page.focus(PHONE_NUMBER);
                    console.log("will clear phone_number field");
                    await page.evaluate(() => {
                        let field = document.getElementById("phone_number");
                        if (field) {
                            field.value = ""
                        }
                    })
                    await delay(1000);
                    await page.keyboard.type("0" + this.contact.phoneNumber);
                    this.isPhoneInput = true;
                }
            }
        } catch (e) {
            log(e);
            this.isTerminated = true;
        }

    }

    async inputName(page) {
        try {
            logWithDevice("input name called with this.browser.isConnected=" + this.browser.isConnected(), this.device)
            logWithDevice("input name called with this.isNameInput=" + this.isNameInput, this.device)
            if (this.browser.isConnected()) {
                if (!this.isNameInput) {
                    await page.focus(LAST_NAME);
                    await delay(getRandomWaitTime());
                    console.log("will clear surname field");
                    await page.evaluate(() => {
                        let field = document.getElementById("surname");
                        if (field) {
                            field.value = ""
                        }
                    })
                    await delay(1000);
                    await page.keyboard.type(this.contact.lastName);
                    await page.focus(FIRST_NAME);
                    await delay(getRandomWaitTime());
                    console.log("will clear name field");
                    await page.evaluate(() => {
                        let field = document.getElementById("name");
                        if (field) {
                            field.value = ""
                        }
                    })
                    await page.keyboard.type(this.contact.firstName);
                    this.isNameInput = true;
                }
            }
        } catch (e) {
            log(e);
            this.isTerminated = true
        }
    }

    async inputPassportId(page) {
        try {
            if (this.browser.isConnected()) {
                if (!this.isPasspordInput) {
                    await page.focus(PASSPORT_ID);
                    await delay(getRandomWaitTime());
                    console.log("will clear passport_id field");
                    await page.evaluate(() => {
                        let field = document.getElementById("passport_id");
                        if (field) {
                            field.value = ""
                        }
                    })
                    await delay(1000);
                    await page.keyboard.type(this.contact.passportNumber.toString());
                    this.isPasspordInput = true;
                }
            }
        } catch (e) {
            log(e);
            this.isTerminated = true;
        }

    }

    async checkCGU(page) {
        try {
            if (this.browser.isConnected()) {
                if (!this.cguChecked) {
                    await page.focus(CGU_ID);
                    await page.evaluate(() => {
                        if (!document.querySelector("#cgu").checked) {
                            document.querySelector("#cgu").checked = true
                        }
                    });
                    // await page.click(CGU_ID);
                    await delay(getRandomWaitTime());
                    await page.focus(PROCESSING_ID);
                    // await page.click(PROCESSING_ID)
                    await page.evaluate(() => {
                        if (!document.querySelector("#processing").checked) {
                            document.querySelector("#processing").checked = true
                        }
                    });
                    this.cguChecked = true;
                }
            }
        } catch (e) {
            log(e);
            this.isTerminated = true;
        }
    }

    async chooseStore(page) {
        try {
            if (this.browser.isConnected()) {
                if (this.selectedStore !== "random") {
                    page.focus(PREFER_STORE);
                    await delay(1000)
                    page.click(PREFER_STORE);
                    let stores = this.selectedStore.split(":")
                    this.choosedStore = stores[Math.floor(Math.random() * stores.length)]
                    await page.select(PREFER_STORE, this.choosedStore);
                }
            }
        } catch (e) {
            log(e);
            // this.isTerminated = true;
        }
    }


    async fillFields(page, airePlanMode) {
        log("fillFields called for contact: " + this.contact.mail)
        log("this.isFillingFields: " + this.isFillingFields);
        if (!this.isFillingFields) {
            this.isFillingFields = true;
            if (airePlanMode) {
                // await this.enableDisableAirPlanMode();
            }
            await this.chooseStore(page);
            await this.inputName(page);
            await this.chooseCountry(page);
            await this.inputPhoneNumber(page)
            await this.fillEmail(page)
            await this.inputPassportId(page)
            await this.checkCGU(page)
            await this.resolveCaptcha(page)
            await delay(10 * 1000)
            this.isFillingFields = false
        }
    }

    async clickValid() {
        logWithDevice("clickValid() called.", this.device);
        await delay(getRandomWaitTime())
        try {
            if (!this.page.isClosed()) {
                this.page.evaluate(() => {
                    let element = document.getElementsByClassName("btn")[0];
                    if (typeof element !== 'undefined')
                        document.getElementsByClassName("btn")[0].focus();
                })
                await delay(getRandomWaitTime())
                if (!this.page.isClosed()) {
                    try {
                        // remove debug flag
                        // const validElement = await page.$('.btn');
                        console.log("will click on valid button");
                        await this.page.evaluate(() => {
                            document.getElementsByClassName("btn")[0].click();
                        })
                        if (this.firstStart) {
                            this.disconnectBrowser();
                            await this.checkResultWithOcr();
                        }
                    } catch (e) {
                        log(e);
                    }
                }
            }
        } catch (e) {
            log(e)
        }
    }

    async resolveCaptcha(page) {
        if (RDV_URL.includes("192")) {
            // await this.push_message_to_queue(PublishType.SUCCESS)
            await delay(100000)
            return
        }
        //check whether there is captcha
        let pageContent = await page.content()
        let hasCaptcha = pageContent.includes("g-recaptcha-response")
        if (hasCaptcha) {
            // await this.clickCheckbox()
            await delay(1000)
            this.captchaSolver = new SolveCaptcha(page);
            await this.captchaSolver.start((solution) => {
                logWithDevice("solution is: " + solution, this.device);
                if (solution !== ERROR_CAPTCHA_UNSOLVABLE && solution !== TWO_CAPTCHA_CONNECTION_FAILED) {
                    try {
                        if (!page.isClosed()) {
                            if (this.browser.isConnected()) {
                                page.evaluate((solution) => {
                                    let element = document.getElementById("g-recaptcha-response");
                                    if (element != null)
                                        document.getElementById("g-recaptcha-response").innerHTML = solution;
                                }, solution)
                                this.clickValid();
                            }
                        }
                    } catch (e) {
                        log(e)
                        this.isTerminated = true;
                    }
                } else {
                    this.isTerminated = true;
                }
            })
        } else {
            await this.clickValid();
        }
    }

    async onPageLoad(currentPage) {
        logWithDevice("onPageLoad called with url " + this.page.url(), this.device)
        try {
            let content = await this.page.content();
            let captcha_url = "geo.captcha-delivery.com/captcha";
            if (content.toString().includes(captcha_url)) {
                await this.checkResultWithOcr()
                logWithDevice("发现datadome", this.device);
            } else if (content.includes("502 Bad Gateway")) {
                logWithDevice("502 Bad Gateway found", this.device)
                await this.page.reload()
            } else if (this.page.url().includes("sorry")) {
                await this.resetBrowser()
            } else if (content.includes("PROXY_CONNECTION_FAILED")) {
                logWithDevice("PROXY_CONNECTION_FAILED, will reload page", this.device);
                await delay(2000)
                await this.page.reload()
            } else if (content.includes("ERR_NETWORK_CHANGED")) {
                logWithDevice("ERR_NETWORK_CHANGED, will reload page", this.device);
                await delay(2000)
                await this.page.reload()
            } else if (content.includes("ERR_TIMED_OUT")) {
                logWithDevice("ERR_TIMED_OUT, will reload page", this.device);
                await delay(2000)
                await this.page.reload()
            } else if (content.includes("408 Request Time-out")) {
                logWithDevice("Request Time-out, will reload page", this.device);
                await delay(2000)
                await this.page.reload()
            } else {
                if (this.page.url() === RDV_URL) {
                    await this.fillFields(this.page, true);
                    // if (this.isFillingFields)
                    //     await this.getErrors()
                } else {
                    if (content.includes(MESSAGE_URL_VALIDATION_FR) || content.includes(MESSAGE_URL_VALIDATION_EN)) {
                        log("successful");
                        await this.push_message_to_queue(PublishType.SUCCESS);
                    } else if (content.includes(EMPTY_RESPONSE_ERROR)) {
                        log("EMPTY_RESPONSE_ERROR error received, will quit")
                        this.isTerminated = true
                    } else {
                        //    try to get errors
                        await this.getErrors()
                    }
                }
            }
        } catch (e) {
            log(e)
        }
    }


    async slidingCaptcha(onResult) {
        logWithDevice("slidingCaptcha", this.device);
        let slidingCaptchaSolver = new SlidingCaptchaSolver(this.device);
        await slidingCaptchaSolver.solve(this.page, async (isSuccessful) => {
            console.log("check isAlwaysBlocked")
            onResult(isSuccessful)
        })
    }

    async onResponse(response) {
        let rex = new RegExp(REGEX_RDV_URL)
        // log("onResponse with url:" + response.url())
        // log("onResponse with url:" + response.body())
        if (rex.test(response.url())) {
            logWithDevice("rdv url found:" + response.url(), this.device)
            // save cookies
            await this.push_message_to_db(PublishType.SUCCESS, response.url())
        }
    }

    async push_message_to_queue(publishType) {
        let url = this.page.url();
        logWithDevice("successful url is " + url, this.device)
        await this.push_message_to_db(publishType, url)
        // this.firstStart = false;
    }

    async push_message_to_db(publishType, url) {
        let splitedUrl = url.split("/");
        let id = splitedUrl[splitedUrl.length - 1];
        if (id === "register") {
            id = this.contact.mail;
        }
        if (url === "https://rendezvousparis.hermes.com/client/welcome") {
            return
        }
        //    save to mongoDb
        let reserve = ReserveResultPojo.create_from_contact(this.contact, id, url, this.choosedStore, publishType);
        reserve.source_from = this.device.model();
        await this.mongoManager.saveReserveToDb(reserve.to_mongo_dict())
        await this.page.close();
        // await this.deleteFromBlackList()
        // await this.resetBrowser()
        this.isTerminated = true
    }

    async deleteFromBlackList() {
        await this.mongoManager.removeFromBlackList(this.contact)
    }

    async getErrors() {
        logWithDevice("getErrors", this.device);
        await this.checkResultWithOcr();
        if (this.page.url() === BLANK_URL) {
            this.isTerminated = true;
        } else {
            try {
                // let errorItem = this.page.locator("div.alert");
                // if (errorItem) {
                //     let errorContent = await errorItem.innerHTML();
                //     await this.handleError(errorContent);
                // }
            } catch (e) {
                log(e);
            }
        }
    }

    async clickCheckbox() {
        logWithDevice("clickCheckbox", this.device);

        try {
            // let errorItem = await this.page.click("#recaptcha-anchor > div.recaptcha-checkbox-border")
            await this.page.waitForSelector("iframe")
            let elementHandle = await this.page.$('[title="reCAPTCHA"]')
            const iframe = await elementHandle.contentFrame()
            await iframe.click("#recaptcha-anchor > div.recaptcha-checkbox-border")
        } catch (e) {
            log(e);
        }
    }

    async removeDebugFlag() {
        await delay(1000)
        await this.device.shell("am clear-debug-app --persistent com.android.chrome")
        await delay(1000)
    }

    async resetBrowser() {
        logWithDevice("resetBrowser", this.device);
        this.isFillingFields = false;
        this.cguChecked = false;
        this.isNameInput = false;
        this.isEmailFilled = false;
        this.isCountryChoosen = false;
        this.isPhoneInput = false;
        this.isPasspordInput = false;
        // this.disconnectBrowser();
        await this.device.shell("pm clear " + this.browserPackageName)
        await delay(1000)
        // await this.device.shell("am start -n " + this.browserPackageName + "/com.google.android.apps.chrome.Main")
        // await delay(2000);
        this.isTerminated = true;
        // await this.checkResultWithOcr();
    }


    disconnectBrowser() {
        try {
            logWithDevice("will disconnect browser", this.device);
            if (this.browser !== undefined) {
                this.browser.disconnect();
            }
        } catch (e) {
            console.log(e)
        }
    }

    async connectBrowserIfNecessary() {
        if (!this.browser.isConnected()) {
            try {
                this.browser = await puppeteer.connect({
                    browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
                    headless: false, defaultViewport: null
                })
            } catch (e) {
                console.log(e)
                this.isTerminated = true;
            }
        }
    }

    async checkResultWithOcr() {
        console.log("checkResultWithOcr() called.")
        await delay(2000);
        let checkResult = await this.ocrChecker.get_result();
        console.log(checkResult);
        while (checkResult === OCRResult.RECHECK) {
            logWithDevice("will recheck OCR", this.device)
            await delay(4000)
            logWithDevice("will recheck OCR", this.device)
            checkResult = await this.ocrChecker.get_result();
        }
        while (checkResult === OCRResult.SLIDING_CAPTCHA) {
            await this.slidingCaptcha(async (isSuccessful) => {
                if (isSuccessful) {
                    checkResult = await this.ocrChecker.get_result();
                } else {
                    this.isTerminated = true
                }
                // await this.checkResultWithOcr()
            })
            await delay(10 * 1000)
        }
        switch (checkResult) {
            case OCRResult.TERMINAED:
                this.isTerminated = true;
                break;
            case OCRResult.FILL_FIELD:
                // console.log("browser.isConnected: " + this.browser.isConnected());
                if (this.browser === undefined || !this.browser.isConnected()) {
                    logWithDevice("trying to connect to browser", this.device)
                    try {
                        this.browser = await puppeteer.connect({
                            browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
                            headless: false, defaultViewport: null
                        })
                        logWithDevice("get pages", this.device)

                        let pages = await this.browser.pages();
                        pages.forEach((currentPage) => {
                            if (currentPage.url() === RDV_URL) {
                                this.page = currentPage;
                            }
                        })
                        logWithDevice("this.page.bringToFront();", this.device)

                        await this.page.bringToFront();
                        // this.page = pages;
                        // this.page.await
                        await this.fillFields(this.page)
                        await delay(2 * 1000);
                    } catch (e) {
                        console.log(e)
                        this.isTerminated = true
                    }
                } else {
                    logWithDevice("this.browser.isConnected() is " + this.browser.isConnected(), this.device)
                    try {
                        if (this.browser.isConnected()) {
                            logWithDevice("get pages", this.device)
                            let pages = await this.browser.pages();
                            logWithDevice("get current page", this.device)
                            pages.forEach((currentPage) => {
                                if (currentPage.url() === RDV_URL) {
                                    this.page = currentPage;
                                }
                            })
                            logWithDevice("this.page.bringToFront();", this.device)
                            await this.page.bringToFront();
                            // this.page = pages;
                            // this.page.await
                            await this.fillFields(this.page)
                            await delay(2 * 1000);
                        }
                    } catch
                        (e) {
                        console.log(e)
                        this.isTerminated = true
                    }
                }

                break;
            case
            OCRResult.SUCCESS:
                //         reconnect to page and get url
                if (!this.isTerminated) {
                    await this.connect_to_browser(OCRResult.SUCCESS)
                    // if (!this.isTerminated) {
                    //     logWithDevice("will save success appointment", this.device)
                    //     await this.push_message_to_queue(PublishType.SUCCESS);
                    //     await this.closePage()
                    // }
                }
                break;
            case
            OCRResult.RECAPTCHA_ERROR
            :
                this.isTerminated = true;
                break;
            case
            OCRResult.TO_SKIP
            :
                logWithDevice("TO_SKIP", this.device)
                this.device.shell("input tap " + 488 + " " + 1848)
                await delay(2000);
                break;
            case
            OCRResult.TO_REFRESH
            :
                await this.connect_to_browser(OCRResult.TO_REFRESH)
                break;
            case
            OCRResult.BLOCKED
            :
                await this.resetBrowser();
                break;
            case
            OCRResult.ONLINE_APPOINTMENT
            :
                await this.clickOnlineAppointment();
                break;
            case
            OCRResult.CONFIRM_RESEND_FORM
            :
                // logWithDevice("CONFIRM_RESEND_FORM", this.device)
                // await this.checkResultWithOcr();
                break;
            case
            OCRResult.PAGE_OPTIMIZATION
            :
                logWithDevice("PAGE_OPTIMIZATION", this.device)
                await this.skipOptimizationPage();
                await this.checkResultWithOcr();
                break;
            case
            OCRResult.GOOGLE_DISCONNECT
            :
                logWithDevice("GOOGLE_DISCONNECT", this.device)
                this.device.shell("input tap " + 411 + " " + 2100)
                await delay(2000);
                await this.checkResultWithOcr();
                break
            case
            OCRResult.NEED_TO_CLICK_LATE_BTN
            :
                await this.tapLaterBtn()
                this.firstStart = true;
                await this.loadPage()
                break;
            case
            OCRResult.CLOSED
            :
                await this.closePage();
                // this.isTerminated = true;
                break;
            default:
                await delay(5000);
                checkResult = this.ocrChecker.get_result();
        }

        if (checkResult

            ===
            undefined
        ) {
            await

                delay(
                    5000
                )
            ;
            checkResult = this.ocrChecker.get_result();
        }
    }


    async clickOnConfirmBtn() {
        if (this.device.model() === "CPH2219") {
            this.device.shell("input tap " + 900 + " " + 1532)
        } else
            this.device.shell("input tap " + 933 + " " + 1538)
        await delay(2000);
    }

    async closePage() {
        await this.resetBrowser();
        // while (!this.browser.isConnected()) {
        //     logWithDevice("trying to connect to browser", this.device)
        //     this.browser = await puppeteer.connect({
        //         browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
        //         headless: false, defaultViewport: null
        //     })
        //     await delay(2 * 1000);
        // }
        // console.log("will close all pages");
        // let pages = await this.browser.pages();
        // await pages[0].close()
        // console.log("page closed");
        // pages.forEach((currentPage) => {
        //     currentPage.close();
        // })
        // await this.browser.close();
    }

    async skipOptimizationPage() {
        logWithDevice("skipOptimizationPage", this.device)
        let model = this.device.model();
        if (model === "ASUS_X00QD") {
            this.device.shell("input tap " + 800 + " " + 2100)
            await delay(2000);
            this.device.shell("input tap " + 800 + " " + 2100)
            await delay(1000);
        } else if (model === "ONEPLUS A6000") {
            this.device.shell("input tap " + 818 + " " + 2140)
            await delay(2000);
            this.device.shell("input tap " + 818 + " " + 2140)
            await delay(1000);
        } else {
            this.device.shell("input tap " + 800 + " " + 2215)
            await delay(2000);
            this.device.shell("input tap " + 800 + " " + 2215)
            await delay(1000);
        }
    }

    async tapLaterBtn() {
        logWithDevice("tapLaterBtn", this.device)
        let model = this.device.model();
        log("model is " + model);
        if (model === "CPH2219") {
            this.device.shell("input tap " + 385 + " " + 1930)
        } else if (model === "ASUS_X00QD") {
            this.device.shell("input tap " + 490 + " " + 1910)
        } else if (model === "Mi Note 10") {
            this.device.shell("input tap " + 550 + " " + 1920)
        } else if (model === "ONEPLUS A6000") {
            this.device.shell("input tap " + 535 + " " + 1945)
        } else
            this.device.shell("input tap " + 385 + " " + 2050)
        await delay(2000);
    }

    async enableDisableAirPlanMode() {
        logWithDevice("will enable airplane mode", this.device)
        await this.device.shell("cmd connectivity airplane-mode enable")
        await this.device.shell("adb shell settings put global airplane_mode_on 1")
        await delay(1000)
        await this.device.shell("adb shell settings put global airplane_mode_on 0")
        await this.device.shell("cmd connectivity airplane-mode disable")
    }
}

module
    .exports = CommandorPage