"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dom_util_1 = require("@mablhq-internal/mablscript-find/dom-util");
const domUtils_1 = require("../../sharedUtils/domUtils");
const actions_1 = require("../actions");
const domTools_1 = require("../domTools");
const BaseContentEventHandler_1 = require("./BaseContentEventHandler");
const util_1 = require("./util");
const walkthrough_1 = require("../../sharedUtils/walkthrough");
const keyUtils_1 = require("../../sharedUtils/keyUtils");
const SNAPSHOT_DEBOUNCE_MS = 2_000;
class KeyPressEventHandler extends BaseContentEventHandler_1.BaseContentEventHandler {
    constructor(mouseHoverEventHandler, store, selectorCache) {
        super('keydown', 'Keypress Event Handler', store, selectorCache);
        this.formControlKeys = [
            'ArrowUp',
            'ArrowDown',
            'ArrowLeft',
            'ArrowRight',
            'Enter',
            'Tab',
        ];
        this.mouseHoverEventHandler = mouseHoverEventHandler;
        this.handle = this.handle.bind(this);
    }
    shouldSendSnapshot(target) {
        const now = Date.now();
        const timeSinceLastSnapshot = this.lastSnapshotTime
            ? now - this.lastSnapshotTime
            : Infinity;
        if (target !== this.lastSnapshotTarget ||
            timeSinceLastSnapshot >= SNAPSHOT_DEBOUNCE_MS) {
            this.lastSnapshotTarget = target;
            this.lastSnapshotTime = now;
            return true;
        }
        return false;
    }
    async handle(event) {
        if (!(0, util_1.shouldListenForTrainedStepInRecording)(this.store.getState()) ||
            !(0, util_1.isTrustedEvent)(event)) {
            return;
        }
        const { path, target } = (0, domUtils_1.adjustTarget)(event.target, (0, util_1.getPathOnEvent)(event));
        if (target && this.shouldSendSnapshot(target)) {
            (0, actions_1.sendSnapshotMessage)();
        }
        const isInWalkthrough = this.store.getState().walkthrough.isInProgress;
        if (isInWalkthrough) {
            if (event.key === 'Tab' ||
                event.key === 'Enter' ||
                event.ctrlKey ||
                event.metaKey) {
                event.preventDefault();
                event.stopPropagation();
                return;
            }
            const isInTrainerContext = this.store.getState().walkthrough.activeContext ===
                walkthrough_1.ActiveWalkthroughContext.TRAINER;
            if (isInTrainerContext || !(0, util_1.isWalkthroughTarget)(target)) {
                return;
            }
        }
        if (!(0, keyUtils_1.keyIsSupported)(event.key) ||
            this.isHandledByInputEventHandler(target, event.key)) {
            return;
        }
        this.mouseHoverEventHandler.recordHovers();
        const xPath = (0, dom_util_1.createXpathFromPathArray)(path);
        const eventMessage = await (0, domTools_1.createEventMessageWithShadowParents)(target, 'record', 'keypress', xPath, event.timeStamp);
        eventMessage.inputData = event.data;
        eventMessage.inputType = event.inputType;
        const keyPressInfo = {
            key: event.key,
            altKey: event.altKey,
            ctrlKey: event.ctrlKey,
            metaKey: event.metaKey,
            shiftKey: this.shouldRecordShiftKey(event),
        };
        eventMessage.keyInfoArray = [keyPressInfo];
        void (0, actions_1.sendEventMessage)(eventMessage);
    }
    isHandledByInputEventHandler(target, key) {
        const isFormControlKey = this.formControlKeys.includes(key);
        const isInputTag = target.tagName?.toLowerCase() === 'input';
        const isEscapeKey = key === keyUtils_1.ESCAPE_KEY;
        return ((0, dom_util_1.isTextField)(target) &&
            !(isInputTag && isFormControlKey) &&
            !isEscapeKey);
    }
    shouldRecordShiftKey(event) {
        const hasOtherModifiers = event.altKey || event.ctrlKey || event.metaKey;
        return event.shiftKey && (hasOtherModifiers || (0, keyUtils_1.keyIsSpecial)(event.key));
    }
}
exports.default = KeyPressEventHandler;
