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";

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

const global = getGlobal();

let html1 = `
    <div id="test1">
    </div>
`;

let html2 = `
    <div id="test2">
    <monster-tree-select
                        tabindex="0"
                        data-monster-bind="path:values.checkbox"
                        data-monster-options='{
  "url": "mock-data.json",
  "mapping": {
    "valueTemplate": "\${first_name} \${last_name}",
    "labelTemplate": "id",
    "selector": "*"
  },
      "type":"checkbox"

}'></monster-tree-select>
    </div>
`;

let TreeSelect, fetchReference;

describe('Treeselect', function () {

    before(function (done) {
        initJSDOM().then(() => {
            import("element-internals-polyfill").catch(e => done(e));
            fetchReference = global['fetch'];

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


        });
    })

    describe('With fetch', function () {

        beforeEach(() => {
            let mocks = document.getElementById('mocks');
            mocks.innerHTML = html1;

            global['fetch'] = function (url, options) {

                let headers = new Map;
                headers.set('content-type', 'application/json');

                return new Promise((resolve, reject) => {
                    resolve({
                        headers: headers,
                        ok:true,
                        status:200,
                        text: function () {
                            return new Promise((resolve2, reject2) => {

                                let json = JSON.parse(`[
                                          {
                                            "id": 1,
                                            "first_name": "Alexia",
                                            "last_name": "Oughtright",
                                            "email": "aoughtright0@exblog.jp",
                                            "gender": "Agender",
                                            "country": "mn" ,
                                            "parent": "0"
                                          },
                                          {
                                            "id": 2,
                                            "first_name": "Beth",
                                            "last_name": "Boddington",
                                            "email": "bboddington1@statcounter.com",
                                            "gender": "Non-binary",
                                            "country": "sy",
                                            "parent": "0"
                                          },
                                          {
                                            "id": 3,
                                            "first_name": "Shelli",
                                            "last_name": "A'Barrow",
                                            "email": "sabarrow2@google.co.uk",
                                            "gender": "Polygender",
                                            "country": "no",
                                            "parent": "0"
                                          } ]`);

                                resolve2(JSON.stringify(json))
                            })
                        }
                    });
                })
            };
        })

        afterEach(() => {
            let mocks = document.getElementById('mocks');
            mocks.innerHTML = "";
            global['fetch'] = fetchReference;
        })

        describe('create from template', function () {
            beforeEach(() => {
                let mocks = document.getElementById('mocks');
                mocks.innerHTML = html2;
            });

            afterEach(() => {
                let mocks = document.getElementById('mocks');
                mocks.innerHTML = "";
                global['fetch'] = fetchReference;
            })

            describe('create from template', function () {
                it('should contains monster-tree-select', function () {
                    expect(document.getElementById('test2')).contain.html('<monster-tree-select');
                });
            });

        });

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

            it('should have options', function (done) {

                let mocks = document.getElementById('mocks');
                const treeselect = document.createElement('monster-tree-select');
                treeselect.setOption('url', 'https://monsterjs.org/assets/examples/countries.json');

                treeselect.setOption('mapping.selector', '*');
                treeselect.setOption('mapping.labelTemplate', '${id}')
                treeselect.setOption('mapping.valueTemplate', '${id}')
                treeselect.addEventListener('monster-options-set', (e) => {
                    setTimeout(() => {

                        try {
                            const options = treeselect.shadowRoot.querySelectorAll('[data-monster-role=option]');

                            // 3 options (see fetch above)
                            expect(options.length).is.equal(3);


                            const optionHtml = treeselect.shadowRoot.querySelector('[data-monster-role=options]');
                            expect(optionHtml).contain.html('data-monster-insert-reference="options-0"');
                            expect(optionHtml).contain.html('data-monster-insert-reference="options-1"');
                            expect(optionHtml).contain.html('data-monster-insert-reference="options-2"');
                            expect(optionHtml).contain.not.html('data-monster-insert-reference="options-3"');
                            done();

                        } catch (e) {
                            done(e)
                        }



                    }, 100)
                })
                
                
                mocks.appendChild(treeselect);

            


            });

        });

    });

    describe('document.createElement()', function () {

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

        it('should have no options', function (done) {

            let mocks = document.getElementById('mocks');
            const select = document.createElement('monster-tree-select');
            mocks.appendChild(select);

            setTimeout(() => {
                try {
                    const options = select.shadowRoot.querySelector('[data-monster-role=options]');

                    expect(options).is.instanceof(HTMLDivElement);
                    expect(options.hasChildNodes()).to.be.false;
                } catch (e) {
                    return done(e);
                }

                done();
            }, 0)


        });

        it('should expose styling parts for container and popper filter control', function (done) {

            let mocks = document.getElementById('mocks');
            const select = document.createElement('monster-tree-select');
            mocks.appendChild(select);

            setTimeout(() => {
                try {
                    const container = select.shadowRoot.querySelector('[data-monster-role=container]');
                    const popperFilterControl = select.shadowRoot.querySelector('.option-filter-control');

                    expect(container.getAttribute('part')).to.equal('container');
                    expect(popperFilterControl.getAttribute('part')).to.equal('popper-filter-control');
                } catch (e) {
                    return done(e);
                }

                done();
            }, 0)
        });

    });


});
