export default function announcementBanner(config = {}) {
    return {
        active: 0,
        count: Number(config.count || 0),
        intervalMs: Number(config.intervalMs || 5000),
        interval: null,
        storageKey: null,

        init() {
            this.storageKey = this.resolveStorageKey();
            this.active = this.readPersistedActive();
            this.persistActive();
            this.start();
            this.setOffset();

            this._resizeHandler = () => this.setOffset();
            this._beforeCacheHandler = () => {
                this.persistActive();
                this.pauseRotation();
            };

            window.addEventListener("resize", this._resizeHandler);
            document.addEventListener("turbo:before-cache", this._beforeCacheHandler);
        },

        destroy() {
            this.persistActive();
            this.pauseRotation();

            if (this._resizeHandler) {
                window.removeEventListener("resize", this._resizeHandler);
            }

            if (this._beforeCacheHandler) {
                document.removeEventListener("turbo:before-cache", this._beforeCacheHandler);
            }
        },

        start() {
            this.setOffset();

            if (this.count > 1 && !this.interval) {
                this.interval = window.setInterval(() => {
                    this.setActive(this.active + 1);
                }, this.intervalMs);
            }
        },

        pauseRotation() {
            if (this.interval) {
                window.clearInterval(this.interval);
                this.interval = null;
            }
        },

        setActive(index) {
            if (this.count <= 0) {
                this.active = 0;
                return;
            }

            this.active = ((index % this.count) + this.count) % this.count;
            this.persistActive();
        },

        persistActive() {
            if (!this.$el) {
                return;
            }

            this.$el.dataset.activeAnnouncement = String(this.active);

            if (!this.storageKey) {
                return;
            }

            window.sessionStorage?.setItem(this.storageKey, String(this.active));
        },

        readPersistedActive() {
            const datasetValue = Number.parseInt(this.$el?.dataset.activeAnnouncement || "", 10);
            if (Number.isInteger(datasetValue) && datasetValue >= 0) {
                return this.normalizeActive(datasetValue);
            }

            if (!this.storageKey) {
                return 0;
            }

            const storedValue = Number.parseInt(window.sessionStorage?.getItem(this.storageKey) || "", 10);
            if (Number.isInteger(storedValue) && storedValue >= 0) {
                return this.normalizeActive(storedValue);
            }

            return 0;
        },

        normalizeActive(index) {
            if (this.count <= 0) {
                return 0;
            }

            return index % this.count;
        },

        resolveStorageKey() {
            const id = this.$el?.id || "announcement-banner";
            return `announcement-banner:${id}:${this.count}`;
        },

        setOffset() {
            if (!this.$el) {
                return;
            }

            document.documentElement.style.setProperty("--announcement-offset", `${this.$el.offsetHeight}px`);
        },
    };
}
