import { Map } from "mapbox-gl";

/* Idea from Stack Overflow https://stackoverflow.com/a/51683226  */
export class CustomControl {
    private _className: string;
    private _title: string;
    private _eventHandler: (event: MouseEvent) => void;
    private _btn!: HTMLButtonElement;
    private _container!: HTMLDivElement;
    private _map?: Map;
    private _root: any; // React root for rendering our component

    constructor({
        className = "",
        title = "",
        eventHandler = () => { }
    }: {
        className?: string;
        title?: string;
        eventHandler?: (event: MouseEvent) => void;
    }) {
        this._className = className;
        this._title = title;
        this._eventHandler = eventHandler;
    }

    onAdd(map: Map) {
        this._map = map;
        this._btn = document.createElement("button");
        this._btn.className = "mapboxgl-ctrl-icon" + " " + this._className;
        this._btn.type = "button";
        this._btn.title = this._title;
        this._btn.onclick = this._eventHandler;

        // Apply pointer-events: auto; style dynamically
        this._btn.style.pointerEvents = "auto";

        // Dynamically append the style to the auto-generated className
        const styleSheet = document.styleSheets[0];
        styleSheet.insertRule(
            `.${this._className} { pointer-events: auto; }`,
            styleSheet.cssRules.length
        );

        this._container = document.createElement("div");
        this._container.className = "mapboxgl-ctrl-group mapboxgl-ctrl";
        this._container.appendChild(this._btn);

        return this._container;
    }

    onRemove() {
        if (this._container && this._container.parentNode) {
            this._container.parentNode.removeChild(this._container);
        }

        // Defer unmounting React component to prevent race conditions
        if (this._root) {
            setTimeout(() => {
                this._root.unmount();
            });
        }

        this._map = undefined;
    }
}