import {getGlobal} from "../../../../source/types/global.mjs";
import * as chai from 'chai';
import {chaiDom} from "../../../util/chai-dom.mjs";
import {initJSDOM} from "../../../util/jsdom.mjs";
import {ResizeObserverMock} from "../../../util/resize-observer.mjs";

let expect = chai.expect;
chai.use(chaiDom);

const global = getGlobal();

let BuyBox;

const html = `
    <monster-buy-box id="buy-box"></monster-buy-box>
`;

describe('BuyBox', function () {

    before(function (done) {
        initJSDOM().then(() => {
            import("element-internals-polyfill").catch(e => done(e));

            if (!global.ResizeObserver) {
                global.ResizeObserver = ResizeObserverMock;
            }

            import("../../../../source/components/form/buy-box.mjs").then((m) => {
                BuyBox = m['BuyBox'];
                done();
            }).catch(e => done(e));
        });
    });

    afterEach(() => {
        let mocks = document.getElementById('mocks');
        mocks.innerHTML = "";
    });

    it('requires variant price when any variant has pricing', function (done) {
        const mocks = document.getElementById('mocks');
        mocks.innerHTML = html;

        setTimeout(() => {
            try {
                const box = document.getElementById('buy-box');
                expect(box).is.instanceof(BuyBox);

                box.setOption("product", { sku: "BASE", currency: "EUR" });
                box.setOption("pricing", { price: 10 });
                box.setOption("quantity", { min: 1, max: 10, value: 1 });
                box.setOption("variants", {
                    dimensions: [
                        { key: "color", label: "Color" },
                        { key: "size", label: "Size" }
                    ],
                    data: [
                        { id: "SKU-RED-S", color: "Red", size: "S", price: 12 },
                        { id: "SKU-BLU-M", color: "Blue", size: "M" }
                    ]
                });
                box.refresh();

                const onChange = (event) => {
                    const msg = box.shadowRoot
                        .querySelector("[data-monster-role=message]")
                        .textContent
                        .trim();
                    expect(msg).to.equal("Price unavailable.");
                    expect(event.detail.priceAvailable).to.equal(false);
                    box.removeEventListener("monster-buy-box-change", onChange);
                    done();
                };
                box.addEventListener("monster-buy-box-change", onChange);

                setTimeout(() => {
                    const variants = box.shadowRoot.querySelector("monster-variant-select");
                    variants.setOption("selection", { color: "Blue", size: "M" });
                    variants.refresh();
                    variants.dispatchEvent(new CustomEvent("monster-variant-select-change"));
                }, 0);

            } catch (e) {
                return done(e);
            }
        }, 0);
    });

    it('uses base pricing when no variant pricing is provided', function (done) {
        const mocks = document.getElementById('mocks');
        mocks.innerHTML = html;

        setTimeout(() => {
            try {
                const box = document.getElementById('buy-box');
                expect(box).is.instanceof(BuyBox);

                box.setOption("product", { sku: "BASE", currency: "EUR" });
                box.setOption("pricing", { price: 10 });
                box.setOption("quantity", { min: 1, max: 10, value: 1 });
                box.setOption("variants", {
                    dimensions: [
                        { key: "color", label: "Color" },
                        { key: "size", label: "Size" }
                    ],
                    data: [
                        { id: "SKU-RED-S", color: "Red", size: "S" },
                        { id: "SKU-BLU-M", color: "Blue", size: "M" }
                    ]
                });
                box.refresh();

                const onChange = (event) => {
                    const msg = box.shadowRoot
                        .querySelector("[data-monster-role=message]")
                        .textContent
                        .trim();
                    expect(msg).to.equal("");
                    expect(event.detail.priceAvailable).to.equal(true);
                    expect(event.detail.pricing.price).to.equal(10);
                    box.removeEventListener("monster-buy-box-change", onChange);
                    done();
                };
                box.addEventListener("monster-buy-box-change", onChange);

                setTimeout(() => {
                    const variants = box.shadowRoot.querySelector("monster-variant-select");
                    variants.setOption("selection", { color: "Blue", size: "M" });
                    variants.refresh();
                    variants.dispatchEvent(new CustomEvent("monster-variant-select-change"));
                }, 0);

            } catch (e) {
                return done(e);
            }
        }, 0);
    });

    it('applies tier pricing based on quantity', function (done) {
        const mocks = document.getElementById('mocks');
        mocks.innerHTML = html;

        setTimeout(() => {
            try {
                const box = document.getElementById('buy-box');
                expect(box).is.instanceof(BuyBox);

                box.setOption("product", { sku: "BASE", currency: "EUR" });
                box.setOption("pricing", {
                    price: 6,
                    tiers: [
                        { min: 1, price: 6 },
                        { min: 5, price: 5.5 },
                        { min: 10, price: 5 }
                    ]
                });
                box.setOption("quantity", { min: 1, max: 20, value: 4 });
                box.refresh();

                let lastDetail = null;
                box.addEventListener("monster-buy-box-change", (event) => {
                    lastDetail = event.detail;
                });

                setTimeout(() => {
                    const quantity = box.shadowRoot.querySelector("monster-quantity");
                    quantity.value = 10;
                    quantity.dispatchEvent(new CustomEvent("monster-quantity-change"));

                    setTimeout(() => {
                        expect(lastDetail.pricing.price).to.equal(5);
                        done();
                    }, 0);
                }, 0);

            } catch (e) {
                return done(e);
            }
        }, 0);
    });
});
