/**
 * Created by rockyl on 2019-09-19.
 *
 * 环境
 */

import Vue from "vue";
import {editorApi, envApi} from "../../api";
import {Parser} from "svgaplayerweb";
import db from "../../utils/db-storage";
import events from "@/global-events"

const storeKey = 'code-sync-serve-config';
const svgaParser = new Parser();

export const editorStore = {
	state: {
		initialized: false,
		name: 'Zeroing Editor',
		version: '0.3.0',
		templates: {
			builtin: ['blank'],
			custom: [],
		},
		codeSyncServeConfig: {
			autoLaunch: false,
			ip: 'localhost',
			port: 7788,
		},
		svgaCache: {},
		svgaLoadingQueue: {},
		assetSizeCache: {},
		processEditorWin: null,
	},
	mutations: {
		updateEnv(state, env) {
			Object.assign(state, env);

			state.initialized = true;

			let configStr = localStorage.getItem(storeKey);
			if (configStr) {
				state.codeSyncServeConfig = JSON.parse(configStr);
			}
		},
		saveCodeSyncServeConfig(state, config) {
			state.codeSyncServeConfig = config;
			localStorage.setItem(storeKey, JSON.stringify(state.codeSyncServeConfig));
		},
		updateProcessEditorWin(state, win) {
			state.processEditorWin = win;
		}
	},
	getters: {
		assetSize: state => url => {
			let size = state.assetSizeCache[url];
			if (size) {
				return `${size.width}x${size.height}`
			}
			return '0x0';
		},
		behaviorEditable: state => () => {
			let win = state.processEditorWin;
			return !win || win.closed || !win.editable;
		},
	},
	actions: {
		async updateEnv({state, commit}) {
			if (!state.initialized) {
				const env = await envApi.fetchEnv();
				commit('updateEnv', env);
			}
		},
		loadSvga({state, commit}, url) {
			const {svgaCache, svgaLoadingQueue} = state;
			return new Promise((resolve, reject) => {
				let videoItem = svgaCache[url];
				if (videoItem) {
					resolve(videoItem);
				} else if (svgaLoadingQueue[url]) {
					svgaLoadingQueue[url].push({resolve, reject});
				} else {
					svgaLoadingQueue[url] = [{resolve, reject}];
					svgaParser.load(url, (videoItem) => {
							let queue = svgaLoadingQueue[url];
							svgaCache[url] = videoItem;
							while (queue.length > 0) {
								let item = queue.shift();
								item.resolve(videoItem);
							}
							delete svgaLoadingQueue[url];
						}, (e) => {
							let queue = svgaLoadingQueue[url];
							while (queue.length > 0) {
								let item = queue.shift();
								item.reject(e);
							}
							delete svgaLoadingQueue[url];
						}
					)
				}
			})
		},
		async updateAssetSize({state, commit, dispatch}, url) {
			let size = state.assetSizeCache[url];
			if (!size) {
				let extname = url.substr(url.lastIndexOf('.'));
				switch (extname) {
					case '.svga':
						let data = await dispatch('loadSvga', url);
						Vue.set(state.assetSizeCache, url, data.videoSize);
						break;
					case '.jpg':
					case '.png':
					case '.gif':
					case '.svg':
						await new Promise((resolve, reject) => {
							let img = new Image();
							img.onload = function () {
								let size = {
									width: img.width,
									height: img.height,
								};
								Vue.set(state.assetSizeCache, url, size);
								resolve(size);
							};
							img.onerror = function (e) {
								reject(e);
							};
							img.src = url;
						});
						break;
				}
			}
		},
	}
};

export async function uploadFiles(files) {
	const failedList = [];
	let ps = [];
	for (let file of files) {
		events.$emit('upload-indicator', true);
		ps.push(
			editorApi.uploadFile(file).catch(e => {
				failedList.push(file);
			}).finally(() => {
				events.$emit('upload-indicator', false);
			})
		);
	}
	const result = await Promise.all(ps);

	return {
		failedList,
		result,
	}
}
