/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.gwt.elemento.sample.common;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Set;

import com.google.gwt.core.client.Scheduler;
import elemental2.core.Array;
import elemental2.core.Global;
import elemental2.webstorage.Storage;
import elemental2.webstorage.StorageEvent;
import elemental2.webstorage.WebStorageWindow;
import jsinterop.base.Js;

import static elemental2.dom.DomGlobal.console;
import static elemental2.dom.DomGlobal.window;

public class TodoItemRepository {

    private static final String DEFAULT_KEY = "todos-elemento";

    private final String key;
    private final Storage storage;

    public TodoItemRepository() {
        this(DEFAULT_KEY);
    }

    public TodoItemRepository(String key) {
        this.key = key;
        this.storage = WebStorageWindow.of(window).localStorage;
    }

    public TodoItem add(String text) {
        TodoItem item = new TodoItem();
        item.id = UUID.uuid();
        item.text = text;
        item.completed = false;

        LinkedHashMap<String, TodoItem> items = load();
        items.put(item.id, item);
        save(items.values());

        return item;
    }

    public void completeAll(boolean completed) {
        for (TodoItem item : items()) {
            item.completed = completed;
        }
        save(items());
    }

    public void complete(TodoItem item, boolean completed) {
        LinkedHashMap<String, TodoItem> items = load();
        TodoItem existingItem = items.get(item.id);
        if (existingItem != null) {
            existingItem.completed = completed;
            save(items.values());
        }
    }

    public void rename(TodoItem item, String text) {
        LinkedHashMap<String, TodoItem> items = load();
        TodoItem existingItem = items.get(item.id);
        if (existingItem != null) {
            existingItem.text = text;
            save(items.values());
        }
    }

    public Collection<TodoItem> items() {
        return load().values();
    }

    public void remove(TodoItem item) {
        LinkedHashMap<String, TodoItem> items = load();
        items.remove(item.id);
        save(items.values());
    }

    public void removeAll(Set<String> ids) {
        LinkedHashMap<String, TodoItem> items = load();
        for (String id : ids) {
            items.remove(id);
        }
        save(items.values());
    }

    public void onExternalModification(Scheduler.ScheduledCommand command) {
        if (storage != null) {
            WebStorageWindow.of(window).addEventListener("storage", event -> {
                StorageEvent storageEvent = (StorageEvent) event;
                if (key.equals(storageEvent.key)) {
                    Scheduler.get().scheduleDeferred(command);
                }
            }, false);
        }
    }

    private LinkedHashMap<String, TodoItem> load() {
        LinkedHashMap<String, TodoItem> items = new LinkedHashMap<>();
        if (storage != null) {
            String json = storage.getItem(key);
            if (json != null) {
                try {
                    Array<TodoItem> jsonArray = Js.cast(Global.JSON.parse(json));
                    if (jsonArray != null) {
                        for (int i = 0; i < jsonArray.length; i++) {
                            TodoItem todoItem = jsonArray.getAt(i);
                            items.put(todoItem.id, todoItem);
                        }
                    }
                } catch (Exception parseError) {
                    console.error("error parsing stored data", parseError);
                    console.log("discarding stored data", json);
                }
            }
        }
        return items;
    }

    private void save(Collection<TodoItem> items) {
        if (storage != null) {
            TodoItem[] todoItems = items.toArray(new TodoItem[0]);
            storage.setItem(key, Global.JSON.stringify(todoItems));
        }
    }
}

@@ -750,21 +750,22 @@
 l2.core.
-Array
+Global
 ;%0Aimport
@@ -773,38 +773,39 @@
 elemental2.core.
-Global
+JsArray
 ;%0Aimport element
@@ -3650,16 +3650,18 @@
         
+Js
 Array%3CTo

Fix samples after upgrade to Elemental 1.0.0-beta-3