import {createStore} from 'redux';

let stores = {};
let currentElementId = -1;

export class ReduxStoreElement extends HTMLElement {
    constructor() {
        super();

        this._rootReducer = null;
        this._storeName = 'DEFAULT_STORE';
        this.elementId = `redux-store-element-${++currentElementId}`;
    }

    static get observedAttributes() {
        return [
            'root-reducer',
            'store-name',
            'action'
        ];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        switch (name) {
            case 'root-reducer': {
                this.rootReducer = newValue;
                break;
            }
            case 'store-name': {
                this.storeName = newValue;
                break;
            }
            case 'action': {
                this.action = newValue;
                break;
            }
        }
    }

    set rootReducer(val) {
        this._rootReducer = val;
        if (this._rootReducer && this._storeName) {
            this.createTheStore();
        }
    }

    get rootReducer() {
        return this._rootReducer;
    }

    set storeName(val) {
        this._storeName = val;
        if (this._rootReducer && this._storeName) {
            this.createTheStore();
        }
    }

    get storeName() {
        return this._storeName;
    }

    set action(val) {
        stores[this._storeName].store.dispatch(val);
    }

    connectedCallback() {
        if (!stores[this._storeName]) {
            setTimeout(() => {
                this.connectedCallback();
            });
            return;
        }

        this.unsubscribe = stores[this._storeName].store.subscribe(() => {
            this.dispatchEvent(new CustomEvent('statechange', {
                detail: {
                    state: stores[this._storeName].store.getState()
                },
                bubbles: false
            }));
        });
    }

    getState() {
        return stores[this._storeName].store.getState();
    }

    getStores() {
        return stores;
    }

    createTheStore() {
        if (stores[this._storeName]) return; // I think it is safe to presume that a store should only be created once. Whithout this check there are some problems when a root reducer is set multiple times for one store

        stores[this._storeName] = {
            store: createStore(this._rootReducer),
            rootReducer: this._rootReducer
        };
    }
}

window.customElements.define('redux-store', ReduxStoreElement);

@@ -242,16 +242,45 @@
 STORE';%0A
+        this._action = null;%0A
         
@@ -420,68 +420,18 @@
    '
-root-reducer',%0A            'store-name',%0A            'action
+store-name
 '%0A  
@@ -549,351 +549,173 @@
 se '
-root-reducer': %7B%0A                this.rootReducer = newValue;%0A                break;%0A            %7D%0A            case 'store-name': %7B%0A                this.storeName = newValue;%0A                break;%0A            %7D%0A            case 'action': %7B%0A                this.action = newValue;%0A                break;%0A            %7D%0A        %7D%0A    %7D%0A%0A    set 
+store-name': %7B%0A                this.storeName = newValue;%0A                break;%0A            %7D%0A        %7D%0A    %7D%0A%0A    set rootReducer(val) %7B%0A        if (val !== this._
 root
@@ -717,32 +717,32 @@
 _rootReducer
-(val
 ) %7B%0A
+    
         this
@@ -754,32 +754,36 @@
 tReducer = val;%0A
+    
         if (this
@@ -810,32 +810,36 @@
 s._storeName) %7B%0A
+    
             this
@@ -849,32 +849,46 @@
 eateTheStore();%0A
+            %7D%0A
         %7D%0A    %7D%0A
@@ -970,32 +970,75 @@
 toreName(val) %7B%0A
+        if (val !== this._storeName) %7B%0A    
         this._st
@@ -1044,32 +1044,36 @@
 toreName = val;%0A
+    
         if (this
@@ -1112,32 +1112,36 @@
 ) %7B%0A            
+    
 this.createTheSt
@@ -1139,32 +1139,46 @@
 eateTheStore();%0A
+            %7D%0A
         %7D%0A    %7D%0A
@@ -1253,32 +1253,104 @@
 t action(val) %7B%0A
+        if (val !== this._action) %7B%0A            this._action = val;%0A    
         stores%5Bt
@@ -1384,13 +1384,32 @@
 tch(
-val);
+this._action);%0A        %7D
 %0A   
@@ -2065,24 +2065,334 @@
 heStore() %7B%0A
+        //TODO I think we can get rid of this check because the setters for storeName and rootReducer do reference equality checking. If a user sets the rootReducer or storeName and the reference is different, then a new store should be created.%0A        //TODO I am not sure though, so keep this check for now%0A
         if (

add reference equality checking for all properties