"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRemoveUnit = exports.updateValue = exports.maybeJSONPointerToLocator = exports.filterUUIDs = exports.mockImageMetadata = exports.DemoPageForm = exports.Form = exports.getFocusedId = exports.getFocusedElement = exports.lajiFormLocate = exports.lajiFormLocator = exports.navigateToForm = exports.emptyForm = void 0;
exports.createForm = createForm;
const path = __importStar(require("path"));
const test_utils_1 = require("@luomus/laji-map/test-export/test-utils");
const emptyForm = (page_1, ...args_1) => __awaiter(void 0, [page_1, ...args_1], void 0, function* (page, params = "") { return page.goto(`/?test=true&settings=false&mockApi=true&${params}`); });
exports.emptyForm = emptyForm;
const navigateToForm = (page_1, formID_1, ...args_1) => __awaiter(void 0, [page_1, formID_1, ...args_1], void 0, function* (page, formID, params = "") { return page.goto(`/?id=${formID}&local=true&settings=false&mockApi=true${params}`); });
exports.navigateToForm = navigateToForm;
const lajiFormLocator = (path) => `#_laji-form_root${typeof path === "string" && path.length ? `_${path.replace(/\./g, "_")}` : ""}`;
exports.lajiFormLocator = lajiFormLocator;
const lajiFormLocate = (page, str) => page.locator((0, exports.lajiFormLocator)(str));
exports.lajiFormLocate = lajiFormLocate;
const getFocusedElement = (page) => page.locator("*:focus");
exports.getFocusedElement = getFocusedElement;
const getFocusedId = (page) => (0, exports.getFocusedElement)(page).getAttribute("id");
exports.getFocusedId = getFocusedId;
function getEnumWidgetForContainer($container) {
    return {
        $container,
        openEnums: () => $container.click(),
        $enumContainer: $container.locator(".lajii-form-dropdown"),
        $$enums: $container.locator(".laji-form-dropdown-item"),
        $input: $container.locator("input")
    };
}
class Form {
    constructor(page, $locator = page.locator(".laji-form")) {
        this.page = page;
        this.$locator = $locator;
        this.$form = this.$locator.locator(".rjsf");
        this.getMockStr = (path, query) => `window.mockResponses[window.getMockQueryKey(${JSON.stringify(path)}, ${JSON.stringify(query)})]`;
        this.createValidatorPO = (type) => ({
            $$all: this.$locator.locator(`.laji-form-error-list:not(.laji-form-failed-jobs-list) .${type}-panel .list-group button`),
            $panel: this.$locator.locator(`.laji-form-error-list:not(.laji-form-failed-jobs-list) .${type}-panel`)
        });
        this.errors = this.createValidatorPO("error");
        this.warnings = this.createValidatorPO("warning");
        this.failedJobs = {
            $container: this.$locator.locator(".laji-form-failed-jobs-list"),
            $$errors: this.$locator.locator(".laji-form-failed-jobs-list .list-group-item")
        };
        this.$runningJobs = this.$locator.locator(".running-jobs");
        this.$acknowledgeWarnings = this.$locator.locator(".laji-form-warning-list .panel-footer button");
        this.$blocker = this.page.locator(".laji-form.blocking-loader");
        this.$mapFieldFullscreenMap = this.$locator.locator(".laji-form.fullscreen .laji-form-map");
        this.getImageArrayField = (lajiFormLocator) => {
            const $container = this.$locate(lajiFormLocator).locator(".laji-form-medias");
            const $imgContainers = this.$locate(lajiFormLocator).locator(".media-container");
            const $modal = this.page.locator(".laji-form.media-modal");
            const $addModal = this.page.locator(".laji-form.media-add-modal");
            return {
                $container,
                $imgContainers,
                $$imgs: $imgContainers.locator("img"),
                $$imgLoading: $imgContainers.locator(".react-spinner"),
                $$imgRemoves: $imgContainers.locator(".button-corner"),
                $imgRemoveConfirmButton: (id) => this.$locateAddition(id, "delete-confirm-yes", true),
                $dropzone: this.$locate(lajiFormLocator).locator(".laji-form-drop-zone"),
                $modal,
                $addModal,
                $modalClose: $modal.locator(".modal-header .close"),
                $addModalCancel: $addModal.locator(".cancel")
            };
        };
        this.getAutosuggestWidget = (lajiFormLocator) => {
            return {
                $input: this.$locate(lajiFormLocator).locator("input"),
                $suggestionsContainer: this.$locate(lajiFormLocator).locator(".rw-list"),
                $suggestions: this.$locate(lajiFormLocator).locator(".rw-list-option"),
                $loadingSpinner: this.$locate(lajiFormLocator).locator(".react-spinner"),
            };
        };
        this.getTaxonAutosuggestWidget = (lajiFormLocator) => {
            const autosuggest = this.getAutosuggestWidget(lajiFormLocator);
            return Object.assign(Object.assign({}, autosuggest), { $powerUserButton: this.$locator.locator(".power-user-addon"), $suggestedGlyph: this.$locate(lajiFormLocator).locator(".glyphicon-ok"), $nonsuggestedGlyph: this.$locate(lajiFormLocator).locator(".glyphicon-warning-sign") });
        };
        this.getPersonAutosuggestWidget = (lajiFormLocator) => {
            const autosuggest = this.getAutosuggestWidget(lajiFormLocator);
            return Object.assign(Object.assign({}, autosuggest), { $suggestedGlyph: this.$locate(lajiFormLocator).locator(".glyphicon-user") });
        };
        this.getScopeField = (lajiFormLocator) => ({
            $button: this.$locateButton(lajiFormLocator, "additionals"),
            $$listItems: this.$locate(lajiFormLocator).locator(".dropdown.open li a"),
            modal: {
                $container: this.page.locator(".scope-field-modal"),
                $close: this.page.locator(".scope-field-modal .close"),
                $$loadingGroups: this.page.locator(".scope-field-modal .list-group .react-spinner"),
                $$groupTitles: this.page.locator(".scope-field-modal .list-group .list-group-item strong"),
                $$listItems: this.page.locator(".scope-field-modal .list-group-item"),
            }
        });
        this.getLocationChooser = (lajiFormLocator) => {
            const $peeker = this.$locateButton(lajiFormLocator, "location-peeker", true);
            return {
                $button: this.$locateButton(lajiFormLocator, "location"),
                modal: {
                    $container: this.page.locator(".map-dialog"),
                    map: new test_utils_1.MapPageObject(this.page, this.page.locator(".map-dialog .laji-map"))
                },
                peeker: {
                    $popover: $peeker,
                    $map: $peeker.locator(".laji-map"),
                    $$markers: $peeker.locator(".vector-marker path"),
                }
            };
        };
        this.getUnitListShorthandArrayField = (lajiFormLocator) => ({
            $button: this.$locateButton(lajiFormLocator, "addUnitList"),
            modal: {
                $input: this.page.locator(".unit-list-shorthand-modal input"),
                $addButton: this.page.locator(".unit-list-shorthand-modal button")
            }
        });
        this.$getShortHandWidget = (lajiFormLocator) => this.$locateAddition(lajiFormLocator, "shortHandText");
        this.getGeocoder = (lajiFormLocator = "") => ({
            $btn: this.$locate(lajiFormLocator).locator(".geocoder-btn"),
            $spinner: this.$locate(lajiFormLocator).locator(".geocoder-btn .react-spinner")
        });
        this.getNamedPlaceChooser = () => {
            const $namedPlaceChooserModal = this.page.locator(".named-place-chooser-modal");
            const $mapPopupContainer = this.page.locator(".named-place-popup");
            return {
                select: getEnumWidgetForContainer($namedPlaceChooserModal.locator(".laji-form-dropdown-container")),
                mapPopup: {
                    $container: $mapPopupContainer,
                    $useBtn: $mapPopupContainer.locator(".btn-default")
                },
                $alert: $namedPlaceChooserModal.locator(".alert"),
                $close: $namedPlaceChooserModal.locator(".close")
            };
        };
    }
    $locate(path) {
        return this.$locator.locator((0, exports.lajiFormLocator)(path));
    }
    $locateButton(path, selector, locateFromBody = false) {
        return (locateFromBody ? this.page : this.$locator).locator(`#root${typeof path === "string" && path.length > 0 ? `_${path.replace(/\./g, "_")}` : ""}-${selector}`);
    }
    $locateAddition(path, selector, locateFromBody = false) {
        return this.$locateButton(path, selector, locateFromBody);
    }
    setMockResponse(path, query) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.page.evaluate(`window.setMockResponse(${JSON.stringify(path)}, ${JSON.stringify(query)})`);
            const mock = (method, response, raw) => this.page.evaluate(`${this.getMockStr(path, query)}.${method}(${JSON.stringify(response)}, ${JSON.stringify(raw)})`);
            return {
                resolve: (response, raw) => mock("resolve", response, raw),
                reject: (response, raw) => mock("reject", response, raw),
                remove: () => mock("remove")
            };
        });
    }
    createMockResponseQueue(path, query) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.page.evaluate(`window.createMockResponseQueue(${JSON.stringify(path)}, ${JSON.stringify(query)})`);
            const queueStr = `window.mockQueues[window.getMockQueryKey(${JSON.stringify(path)}, ${JSON.stringify(query)})]`;
            const mock = (method, response, raw, pointer) => {
                return this.page.evaluate(`${this.getMockStr(path, query)}[${pointer}].${method}(${JSON.stringify(response)}, ${JSON.stringify(raw)})`);
            };
            let pointer = 0;
            return {
                create: () => __awaiter(this, void 0, void 0, function* () {
                    yield this.page.evaluate(`${queueStr}.create()`);
                    const _pointer = pointer;
                    pointer = pointer + 1;
                    return {
                        resolve: (response, raw) => mock("resolve", response, raw, _pointer),
                        reject: (response, raw) => mock("reject", response, raw, _pointer),
                    };
                }),
                remove: () => this.page.evaluate(`${queueStr}.remove()`)
            };
        });
    }
    getBooleanWidget(str) {
        const $container = this.$locate(str).locator(".checkbox-container");
        return {
            $container,
            $true: $container.locator("input").nth(0), // eslint-disable-line  protractor/use-first-last
            $false: $container.locator("input").nth(1),
            $undefined: this.$locate(str).locator("input").nth(2),
            $active: $container.locator("input[checked]"),
            $nonactive: $container.locator("input:not([checked])").first()
        };
    }
    $getInputWidget(str) {
        return this.$locate(str).locator("input");
    }
    $getTextareaWidget(str) {
        return this.$locate(str).locator("textarea");
    }
    $getEnumWidget(str) {
        const $container = this.$locate(str).locator(".laji-form-dropdown-container");
        return getEnumWidgetForContainer($container);
    }
    getDateWidget(str) {
        const $widget = this.$locate(str).locator(".date-widget");
        return {
            $container: $widget,
            $input: $widget.locator("input"),
            buttons: {
                $today: $widget.locator(".today"),
                $yesterday: $widget.locator(".yesterday"),
                $same: $widget.locator(".same"),
                $date: $widget.locator(".rw-i-calendar"),
                $time: $widget.locator(".rw-i-clock-o"),
                $plusSixMonths: $widget.locator(".plus-six-months"),
                $plusYear: $widget.locator(".plus-year"),
            },
            calendar: {
                $today: $widget.locator(".rw-calendar-footer button"),
            },
            clock: {
                "$00:00": $widget.locator(".rw-list li").nth(0),
                "$01:00": $widget.locator(".rw-list li").nth(2),
            }
        };
    }
    $getFieldErrors(str) {
        return this.$locate(str).locator(".laji-form-error-container li");
    }
    /** Draws a marker to the center of a laji-map rendered to the given locator. The locator defaults to "gatherings" */
    putMarkerToMap() {
        return __awaiter(this, arguments, void 0, function* (lajiFormLocator = "gatherings") {
            const $map = this.$locate(lajiFormLocator).locator(".laji-map");
            yield $map.scrollIntoViewIfNeeded();
            const map = new test_utils_1.MapPageObject(this.page, $map);
            yield map.drawMarker();
        });
    }
}
exports.Form = Form;
class DemoPageForm extends Form {
    constructor(page, props) {
        super(page);
        this.props = props;
        this.mockImageUpload = (lajiFormLocator) => __awaiter(this, void 0, void 0, function* () {
            const filePath = path.resolve(__dirname, "./mock/pixel.png");
            const imageResponse = [{ name: "data", filename: "pixel.png", id: "mock", expires: 1575979685 }];
            const { resolve, remove } = yield this.setMockResponse("/images", false);
            const mdResponse = exports.mockImageMetadata;
            const { resolve: mdResolve, remove: mdRemove } = yield this.setMockResponse("/images/mock", false);
            yield this.getImageArrayField(lajiFormLocator).$dropzone.locator("input").setInputFiles(filePath);
            return {
                resolve: () => __awaiter(this, void 0, void 0, function* () {
                    yield resolve(imageResponse);
                    yield mdResolve(mdResponse);
                }),
                remove: () => __awaiter(this, void 0, void 0, function* () {
                    yield remove();
                    yield mdRemove();
                })
            };
        });
    }
    initialize(beforeInit) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            const query = (params) => Object.keys(params).reduce((q, key) => `${q}&${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`, "");
            if ((_a = this.props) === null || _a === void 0 ? void 0 : _a.id) {
                const _b = this.props, { id } = _b, _props = __rest(_b, ["id"]);
                yield (0, exports.navigateToForm)(this.page, id, query(_props));
            }
            else {
                yield (0, exports.emptyForm)(this.page);
            }
            beforeInit && (yield beforeInit(this));
            yield this.setState(this.props);
        });
    }
    e(path) {
        return this.page.evaluate(`window.lajiForm.${path}`);
    }
    setState(state) {
        return this.page.evaluate((state) => {
            // @ts-ignore
            const onSubmit = function (data) { window.submittedData = data.formData; };
            // @ts-ignore
            const onChange = function (formData) { window.changedData = formData; };
            return window.lajiForm.setState(Object.assign({ onSubmit,
                onChange }, (state || {})));
        }, state);
    }
    getState() {
        return this.page.evaluate(() => {
            const { formData } = window.lajiForm.lajiForm.state;
            return { formData };
        });
    }
    getProps() {
        return this.page.evaluate(() => {
            const { schema, uiSchema } = window.lajiForm.lajiForm.props;
            return { schema, uiSchema };
        });
    }
    submit() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.e("submit()");
        });
    }
    startSubmit() {
        this.e("submit()");
    }
    submitOnlySchemaValidations() {
        return this.e("submitOnlySchemaValidations()");
    }
    getSubmittedData() {
        return this.page.evaluate("window.submittedData");
    }
    getChangedData() {
        return this.page.evaluate("window.changedData");
    }
    getPropsData() {
        return this.e("lajiForm.props.formData");
    }
}
exports.DemoPageForm = DemoPageForm;
function createForm(page, props, beforeInit) {
    return __awaiter(this, void 0, void 0, function* () {
        const form = new DemoPageForm(page, props);
        yield form.initialize(beforeInit);
        return form;
    });
}
exports.mockImageMetadata = {
    "id": "mock",
    "capturerVerbatim": [
        "mock"
    ],
    "intellectualOwner": "mock",
    "intellectualRights": "MZ.intellectualRightsCC-BY-SA-4.0",
    "fullURL": "https://imagetest.laji.fi/MM.97056/pixel_full.jpg",
    "largeURL": "https://imagetest.laji.fi/MM.97056/pixel_large.jpg",
    "squareThumbnailURL": "https://imagetest.laji.fi/MM.97056/pixel_square.jpg",
    "thumbnailURL": "https://imagetest.laji.fi/MM.97056/pixel_thumb.jpg",
    "originalURL": "https://imagetest.laji.fi/MM.97056/pixel.png",
    "uploadedBy": "MA.308",
    "@context": "http://schema.laji.fi/context/image-en.jsonld"
};
const filterUUIDs = (any) => {
    if (typeof any === "object" && !Array.isArray(any) && any !== null) {
        return Object.keys(any).filter(key => key !== "_lajiFormId").reduce((_any, key) => (Object.assign(Object.assign({}, _any), { [key]: (0, exports.filterUUIDs)(any[key]) })), {});
    }
    else if (Array.isArray(any)) {
        return any.map(exports.filterUUIDs);
    }
    return any;
};
exports.filterUUIDs = filterUUIDs;
const maybeJSONPointerToLocator = (pointer) => pointer[0] === "/" ? pointer.slice(1).replace(/\//g, "_") : pointer;
exports.maybeJSONPointerToLocator = maybeJSONPointerToLocator;
/** Fills value into given input and presses tab to unfocus it. Useful for inputs with debounce */
const updateValue = ($input, value) => __awaiter(void 0, void 0, void 0, function* () {
    yield $input.fill(value);
    yield $input.press("Tab");
});
exports.updateValue = updateValue;
const getRemoveUnit = (page) => (gatheringIdx, unitIdx) => __awaiter(void 0, void 0, void 0, function* () {
    yield page.locator(`#root_gatherings_${gatheringIdx}_units_${unitIdx}-delete`).click();
    return page.locator(`#root_gatherings_${gatheringIdx}_units_${unitIdx}-delete-confirm-yes`).click();
});
exports.getRemoveUnit = getRemoveUnit;
