
import * as chai from 'chai';
import {chaiDom} from "../../../util/chai-dom.mjs";
import {initJSDOM} from "../../../util/jsdom.mjs";

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

let Pagination;
let EmbeddedPagination;

describe('Pagination', function () {
    this.timeout(10000);

    before(function (done) {
        initJSDOM().then(() => {
            import("../../../../source/components/datatable/pagination.mjs").then((m) => {
                Pagination = m['Pagination'];
                return import("../../../../source/components/datatable/embedded-pagination.mjs");
            }).then((m) => {
                EmbeddedPagination = m['EmbeddedPagination'];
                done();
            }).catch(e => done(e));
        });
    });

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

    it('normalizes NaN and avoids NaN hrefs', function (done) {
        let mocks = document.getElementById('mocks');
        const control = document.createElement('monster-pagination');
        mocks.appendChild(control);

        setTimeout(() => {
            try {
                control.setPaginationState({currentPage: Number.NaN, totalPages: Number.NaN});

                const pagination = control.getOption('pagination');

                expect(pagination.current).to.equal(1);
                expect(pagination.prevHref).to.equal('#');
                expect(pagination.nextHref).to.equal('#');

                const hrefs = [pagination.prevHref, pagination.nextHref, ...pagination.items.map(i => i.href)];
                hrefs.forEach((href) => {
                    expect(href).to.not.contain('NaN');
                    expect(href.startsWith('##')).to.equal(false);
                });
            } catch (e) {
                return done(e);
            }

            done();
        }, 0);
    });

    it('clamps current page and does not double-prefix hash', function (done) {
        let mocks = document.getElementById('mocks');
        const control = document.createElement('monster-pagination');
        mocks.appendChild(control);

        setTimeout(() => {
            try {
                control.setPaginationState({currentPage: 10, totalPages: 3});

                const pagination = control.getOption('pagination');
                expect(pagination.current).to.equal(3);
                expect(pagination.nextHref).to.equal('#');
                expect(pagination.prevHref).to.equal('#page-2');

                setTimeout(() => {
                    try {
                        const prevLink = control.shadowRoot.querySelector(
                            'a[data-monster-role=pagination-prev]'
                        );
                        const nextLink = control.shadowRoot.querySelector(
                            'a[data-monster-role=pagination-next]'
                        );

                        expect(prevLink.getAttribute('href')).to.equal('#page-2');
                        expect(nextLink.getAttribute('href')).to.equal('#');
                    } catch (e) {
                        return done(e);
                    }

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

    it('keeps adaptive pagination visible when the same state is applied again', function (done) {
        const mocks = document.getElementById('mocks');
        const wrapper = document.createElement('div');
        const control = document.createElement('monster-embedded-pagination');

        wrapper.getBoundingClientRect = () => ({
            width: 320,
            height: 40,
            top: 0,
            left: 0,
            right: 320,
            bottom: 40,
            x: 0,
            y: 0
        });

        mocks.appendChild(wrapper);
        wrapper.appendChild(control);

        setTimeout(() => {
            try {
                control.setPaginationState({currentPage: 2, totalPages: 5});

                setTimeout(() => {
                    try {
                        const list = control.shadowRoot.querySelector('.pagination-list');
                        expect(list).to.exist;

                        list.setAttribute('data-monster-adaptive-ready', 'true');
                        control.refreshLayout();
                        list.setAttribute('data-monster-adaptive-ready', 'true');
                        let adaptiveReadyResetCount = 0;
                        const originalSetAttribute = list.setAttribute.bind(list);
                        list.setAttribute = (name, value) => {
                            if (name === 'data-monster-adaptive-ready' && value === 'false') {
                                adaptiveReadyResetCount++;
                            }
                            return originalSetAttribute(name, value);
                        };
                        control.setPaginationState({currentPage: 2, totalPages: 5});

                        expect(list.getAttribute('data-monster-adaptive-ready')).to.equal('true');

                        setTimeout(() => {
                            try {
                                expect(list.getAttribute('data-monster-adaptive-ready')).to.equal('true');
                                expect(adaptiveReadyResetCount).to.equal(0);
                                done();
                            } catch (e) {
                                done(e);
                            }
                        }, 50);
                    } catch (e) {
                        done(e);
                    }
                }, 0);
            } catch (e) {
                done(e);
            }
        }, 0);
    });

    describe('document.createElement', function () {
        it('should instance of Pagination', function () {
            expect(document.createElement('monster-pagination')).is.instanceof(Pagination);
        });

        it('should instance of EmbeddedPagination', function () {
            expect(document.createElement('monster-embedded-pagination')).is.instanceof(EmbeddedPagination);
        });
    });

});
