import { h, Host } from "@stencil/core";
import ArrowUpward from "./assets/ArrowUpward.svg";
import { onComponentPropUndefinedChange, onComponentRequiredPropUndefined, } from "../../utils/helpers";
const backToTopLabel = "Back to top";
export class BackToTop {
    constructor() {
        this.topObserver = null;
        this.bannerOffset = false;
        this.footerVisible = false;
        this.targetElVisible = true;
        /**
         * The horizontal position of the element.
         */
        this.position = "right";
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        /**
         * The variant of the button to render
         */
        this.variant = "default";
        this.getObservedEl = () => {
            return document.querySelector("#ic-back-to-top-target");
        };
        this.setTargetElVisible = (visible) => {
            this.targetElVisible = visible;
        };
        this.setFooterVisible = (visible) => {
            this.checkForClassificationBanner();
            this.footerVisible =
                typeof window !== "undefined" && window.scrollY === 0 ? false : visible;
        };
        this.targetElObserverCallback = (entries) => {
            this.setTargetElVisible(entries[0].isIntersecting);
        };
        this.footerObserverCallback = (entries) => {
            this.setFooterVisible(entries[0].isIntersecting);
        };
        this.findTargetEl = (target) => {
            let targetElement = null;
            if (target === null || target === undefined) {
                console.log("Error: No target ID specified for back to top component - defaulting to top of page");
            }
            else {
                targetElement = document.querySelector(`${target.startsWith("#") ? "" : "#"}${target}`);
                if (targetElement === null) {
                    console.log(`Error: Back to top target element '${target}' not found - defaulting to top of page`);
                }
            }
            return targetElement;
        };
        this.createTopObserver = (target) => {
            this.targetEl = this.findTargetEl(target);
            let objParent;
            //remove old element & observer
            if (this.topObserver !== null) {
                const observedEl = this.getObservedEl();
                if (observedEl !== null) {
                    this.topObserver.unobserve(observedEl);
                    observedEl.remove();
                }
            }
            if (this.targetEl === null) {
                objParent = document.body;
                this.targetEl = objParent.firstElementChild;
                this.isTargetElNull = true;
            }
            else {
                objParent = this.targetEl.parentNode;
                this.isTargetElNull = false;
            }
            //insert a new 0px height element before specified target that can be used to determine when page is scrolled
            const objBackToTopTargetEl = document.createElement("div");
            objBackToTopTargetEl.setAttribute("id", "ic-back-to-top-target");
            objBackToTopTargetEl.setAttribute("tabindex", "-1"); // Needed for virtual cursor behaviour to work
            objParent.insertBefore(objBackToTopTargetEl, this.targetEl);
            // resize observer needs to factor in any top margin on the target el
            const marginTop = this.targetEl
                ? getComputedStyle(this.targetEl).marginTop
                : 0;
            this.topObserver = new IntersectionObserver(this.targetElObserverCallback, {
                threshold: [0],
                rootMargin: `${marginTop} 0px 0px 0px`,
            });
            this.topObserver.observe(objBackToTopTargetEl);
        };
        this.handleClick = () => {
            var _a;
            if (this.isTargetElNull) {
                window.scrollTo(0, 0);
            }
            else {
                (_a = this.targetEl) === null || _a === void 0 ? void 0 : _a.scrollIntoView();
            }
            // Get virtual cursor to move
            this.getObservedEl().focus();
        };
        this.checkForClassificationBanner = () => {
            //adjust position for classification banner at bottom
            const banners = document.querySelectorAll("ic-classification-banner:not([inline='true'])");
            this.bannerOffset = banners.length > 0;
        };
    }
    watchPropHandler(newValue, oldValue) {
        //added for gatsby rehydration issue where prop is initially undefined but then changes to actual value
        onComponentPropUndefinedChange(oldValue, newValue, () => {
            this.createTopObserver(newValue);
        });
    }
    componentWillLoad() {
        this.createTopObserver(this.target);
        this.checkForClassificationBanner();
        //observer for when footer scrolls into view
        let footers = document.querySelectorAll("ic-footer");
        if (footers.length === 0) {
            footers = document.querySelectorAll("footer");
        }
        if (footers.length) {
            const footerEl = footers[footers.length - 1];
            const threshold = this.bannerOffset ? 0.15 : 0;
            const footerObserver = new IntersectionObserver(this.footerObserverCallback, { threshold: [threshold] });
            footerObserver.observe(footerEl);
        }
    }
    componentDidLoad() {
        onComponentRequiredPropUndefined([{ prop: this.target, propName: "target" }], "Back to Top");
    }
    render() {
        const { variant, bannerOffset, targetElVisible, footerVisible } = this;
        const btnVariant = variant === "icon" ? "icon-secondary" : "secondary";
        const size = variant === "icon" ? "large" : "medium";
        const label = variant === "icon" ? "" : backToTopLabel;
        return (h(Host, { key: '849c28a0432db633c5f6cc18e93ab184ef2366b3', class: {
                [`ic-theme-${this.theme}`]: this.theme !== "inherit",
                [`ic-back-to-top-${this.position}`]: true,
                [`ic-back-to-top-variant-icon`]: variant === "icon",
            } }, h("ic-button", { key: '847930311aa52347cabcc2c8cc13a8806524722e', "aria-label": backToTopLabel, variant: btnVariant, size: size, onClick: this.handleClick, class: {
                ["offset-banner"]: bannerOffset,
                ["show"]: !targetElVisible,
                ["by-footer"]: footerVisible,
                ["icon-only"]: variant === "icon",
            }, theme: this.theme }, h("span", { key: 'a8f92084d51b98b034ebb0379c291a169f42f88b', class: "ic-back-to-top-icon", innerHTML: ArrowUpward }), label)));
    }
    static get is() { return "ic-back-to-top"; }
    static get encapsulation() { return "shadow"; }
    static get delegatesFocus() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-back-to-top.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-back-to-top.css"]
        };
    }
    static get properties() {
        return {
            "position": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcBackToTopPositions",
                    "resolved": "\"center\" | \"left\" | \"right\" | undefined",
                    "references": {
                        "IcBackToTopPositions": {
                            "location": "import",
                            "path": "./ic-back-to-top.types",
                            "id": "src/components/ic-back-to-top/ic-back-to-top.types.ts::IcBackToTopPositions"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The horizontal position of the element."
                },
                "getter": false,
                "setter": false,
                "attribute": "position",
                "reflect": false,
                "defaultValue": "\"right\""
            },
            "target": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The ID of the element to jump back to when the link is clicked."
                },
                "getter": false,
                "setter": false,
                "attribute": "target",
                "reflect": false
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            },
            "variant": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcBackToTopVariants",
                    "resolved": "\"default\" | \"icon\" | undefined",
                    "references": {
                        "IcBackToTopVariants": {
                            "location": "import",
                            "path": "./ic-back-to-top.types",
                            "id": "src/components/ic-back-to-top/ic-back-to-top.types.ts::IcBackToTopVariants"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The variant of the button to render"
                },
                "getter": false,
                "setter": false,
                "attribute": "variant",
                "reflect": false,
                "defaultValue": "\"default\""
            }
        };
    }
    static get states() {
        return {
            "bannerOffset": {},
            "footerVisible": {},
            "targetElVisible": {}
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "target",
                "methodName": "watchPropHandler"
            }];
    }
}
//# sourceMappingURL=ic-back-to-top.js.map
