import { Records } from "./records.js";
import { calcFullSelector } from "../utils/calcFullSelector.js";

class Recorder {
    private element: HTMLElement;

    private records: Records;

    public constructor(element: HTMLElement) {
        this.element = element;
        this.records = new Records();
    }

    public restart() {
        this.records = new Records();
        this.toggle(true);
    }

    public createReplay() {
        this.toggle(false);
        return this.records.createReplay();
    }

    public interactionScroll = (e: Event) => {
        const target = e.target as HTMLElement;

        // We never need to capture `body` and `document` as this package is supposed to record specific
        // HTML elements, not whole websites.
        if ([document, document.body].indexOf(target) > -1) {
            return;
        }

        const selector = calcFullSelector(target, this.element);
        if (selector) {
            this.records.addScroll(selector, target.scrollTop);
        }
    };

    public interactionClick = (e: Event) => {
        const target = e.target as HTMLElement;
        const selector = calcFullSelector(target, this.element);
        if (selector) {
            this.records.addClick(selector);
        }
    };

    public interactionFocusIn = (e: Event) => {
        const target = e.target as HTMLElement;
        const selector = calcFullSelector(target, this.element);
        if (selector) {
            this.records.addFocusIn(selector);
        }
    };

    public interactionResize = () => {
        const { innerWidth, innerHeight } = window;
        this.records.addResize(innerWidth, innerHeight);
    };

    public toggle(state: boolean) {
        const {
            element: { addEventListener, removeEventListener },
            records,
        } = this;
        records.toggle(state);

        if (state) {
            setTimeout(() => this.interactionResize(), 0);
            addEventListener("scroll", this.interactionScroll, true);
            addEventListener("click", this.interactionClick, true);
            addEventListener("touch", this.interactionClick, true);
            addEventListener("resize", this.interactionResize, true);
            addEventListener("focusin", this.interactionFocusIn, true);
        } else {
            removeEventListener("scroll", this.interactionScroll, true);
            removeEventListener("click", this.interactionClick, true);
            removeEventListener("touch", this.interactionClick, true);
            removeEventListener("resize", this.interactionResize, true);
            removeEventListener("focusin", this.interactionFocusIn, true);
        }
    }

    public getRecords() {
        return this.records;
    }
}

export { Recorder };
