import Cache from '../cache'
import $Qs from 'qs'
import $Enums from './Enums'
import $nothing from './nothing.js'
import $store from '../store'
import {
	mapGetters,
	mapActions
} from 'vuex'

const initEnv = {
	initConfig: ({
		store
	}) => {},
	initCacheData: ({
		store
	}) => {
		store.dispatch('setAppUser', Cache.getSync(Cache.$Keys.app.APP_USER));
		store.dispatch('setWxInfo', Cache.getSync(Cache.$Keys.app.WX_INFO));
		store.dispatch('setUserInfo', Cache.getSync(Cache.$Keys.app.USER_INFO));
	}
}

const $AppContext = {
	_initStatus: false, // 初始化状态
	$vm: null, // 当前页面VM对象
	$router: null,
	$store: null,
	$cache: Cache,
	$Qs,
	$Enums,
	/**
	 * 导航对象(不可直接使用，使用getNavigate获取页面级导航对象)
	 */
	$Navigate: {
		path: null,
		params: null,
		isTab: false,
		isBack: false,
		isCancel: false,
		reLaunch: false,
		from: null
	},
	/**
	 * 获取当前页面导航对象
	 */
	getNavigate: () => Object.assign(this.$AppContext.getCurrentPage().data.$Navigate || {}, {
		/**
		 * 返回并且非取消(系统按键返回)
		 */
		isBackNoCancel: () => (this.$AppContext.getCurrentPage().data.$Navigate || {}).isBack && !(this.$AppContext.getCurrentPage()
			.data.$Navigate || {}).isCancel
	}),
	/**
	 * 获取当前页面对象
	 */
	getCurrentPage: () => getCurrentPages()._last(),
	/**
	 * 获取前一个页面对象
	 */
	getPreviousPage: () => getCurrentPages()[getCurrentPages().length - 2] || {},
	/**
	 * 获取当前页面参数
	 */
	getParams: () => this.$AppContext.getNavigate().params || {},
	/**
	 * 设置导航栏颜色
	 */
	setNavigationBarColor: ({
		frontColor,
		backgroundColor
	} = {}) => {
		frontColor = $nothing._ifNull(frontColor, '#ffffff')
		backgroundColor = $nothing._ifNull(backgroundColor, '#5cadff')
		wx.setNavigationBarColor({
			frontColor,
			backgroundColor
		})
		Cache.setSync(Cache.$Keys.app.NAVIGATION_BAR_FRONT_COLOR, frontColor)
		Cache.setSync(Cache.$Keys.app.NAVIGATION_BAR_BACKGROUND_COLOR, backgroundColor)
	},
	showTabBarRedDot: (params = {}) => {
		wx.showTabBarRedDot(params)
	},
	hideTabBarRedDot: (params = {}) => {
		wx.hideTabBarRedDot(params)
	},
	setTabBarBadge: (params = {}) => {
		wx.setTabBarBadge(params)
	},
	removeTabBarBadge: (params = {}) => {
		wx.removeTabBarBadge(params)
	},
	/**
	 * 获取缓存的导航栏颜色
	 */
	getCacheNavigationBarColor: () => {
		let frontColor = Cache.getSync(Cache.$Keys.app.NAVIGATION_BAR_FRONT_COLOR)
		let backgroundColor = Cache.getSync(Cache.$Keys.app.NAVIGATION_BAR_BACKGROUND_COLOR)
		return {
			frontColor,
			backgroundColor
		}
	},
	/**
	 * main.js vue实例化的 created 中 使用 AppContext.use(vue) 初始化 $vm、$router、$store
	 * @param vm
	 */
	use: (vm) => {
		vm.$AppContext.$router = vm.$router
		vm.$AppContext.$store = vm.$store
		vm.$AppContext.$store.mapGetters = mapGetters
		vm.$AppContext.$store.mapActions = mapActions
	},
	/**
	 * main.js vue实例化的 created 中调用
	 * @param vm
	 */
	initialize: (vm) => {
		if (!vm.$AppContext._initStatus) {
			vm.$AppContext._initStatus = true
			vm.$AppContext.use(vm)
			initEnv.initConfig({ store: vm.$AppContext.$store })
			initEnv.initCacheData({ store: vm.$AppContext.$store })
		}
	},
	checkLogin: () => {
		if (!$store.getters.appUser.currentTime || $nothing._isNull($store.getters.appUser.token)
			|| ($store.getters.appUser.currentTime && new Date().getTime() - $store.getters.appUser.currentTime >= 86400000)) return false
		else return true
		// return false
	},
	logout: (vm) => {
		vm.$AppContext.$store.dispatch('resetAppUser')
		vm.$AppContext.$store.dispatch('setWxInfo', {})
		vm.$AppContext.$store.dispatch('resetAppUser')
		Cache.removeSync(Cache.$Keys.app.APP_USER)
		Cache.removeSync(Cache.$Keys.app.WX_INFO)
		Cache.removeSync(Cache.$Keys.app.USER_INFO)
	},
	/**
	 * 导航跳转页面
	 * @param {*} options
	 */
	navigateTo: ({
		path = null,
		isTab = false,
		reLaunch = false,
		params = {},
		onComplete = (res) => {},
		onAbort = (res) => {},
		onSuccess = (res) => {},
		userCallBack = (res) => {}
	} = {}) => {
		this.$AppContext.$Navigate = {
			path,
			params,
			isTab,
			isBack: false,
			isCancel: false,
			reLaunch,
			from: this.$AppContext.getCurrentPage().route,
			userCallBack
		}
		//console.log('### navigateTo: ' + this.$AppContext.$Navigate.from)
		//console.warn($nothing._copy(this.$AppContext.$Navigate))
		this.$AppContext.$router.push({
			path,
			isTab,
			reLaunch
		}, onComplete, onAbort, onSuccess)
	},
	/**
	 * 导航跳转Tab页
	 * @param {*} options
	 */
	navigateToTab: ({
		path = null,
		reLaunch = false,
		params = {},
		onComplete = (res) => {},
		onAbort = (res) => {},
		onSuccess = (res) => {},
		userCallBack = (res) => {}
	} = {}) => {
		this.$AppContext.navigateTo({
			path,
			isTab: true,
			reLaunch,
			params,
			onComplete,
			onAbort,
			onSuccess,
			userCallBack
		})
	},
	/**
	 * 导航替换
	 * @param {*} options
	 */
	replaceTo: ({
		path = null,
		params = null,
		onComplete = (res) => {},
		onAbort = (res) => {},
		onSuccess = (res) => {},
		userCallBack = (res) => {}
	} = {}) => {
		this.$AppContext.$Navigate = {
			path,
			params,
			isTab: false,
			isBack: true,
			isReplace: true,
			isCancel: false,
			reLaunch: false,
			// from: this.$AppContext.getCurrentPage().route,
			from: this.$AppContext.getPreviousPage().route,
			userCallBack
		}
		//console.log('### replaceTo: ' + this.$AppContext.$Navigate.from)
		//console.warn($nothing._copy(this.$AppContext.$Navigate))
		this.$AppContext.$router.replace({
			path
		}, onComplete, onAbort, onSuccess)
	},
	/**
	 * 导航返回
	 * @param {*} options
	 */
	navigateBack: ({
		params = null,
		isTab = false
	} = {}) => {
		this.$AppContext.$Navigate = {
			path: this.$AppContext.getPreviousPage().route,
			params,
			isTab,
			isBack: true,
			isCancel: false,
			reLaunch: false,
			from: getCurrentPages()[getCurrentPages().length - 3] ? getCurrentPages()[getCurrentPages().length - 3].route : null,
			backFrom: this.$AppContext.getCurrentPage().route
		}
		console.log('### navigateBack: ' + this.$AppContext.$Navigate.backFrom)
		console.warn($nothing._copy(this.$AppContext.$Navigate))
		this.$AppContext.$router.back()
	},
	navigateGo: ({
		params = null,
		isTab = false
	} = {}) => {
		this.$AppContext.$Navigate = {
			path: this.$AppContext.getPreviousPage().route,
			params,
			isTab,
			isBack: true,
			isCancel: false,
			reLaunch: false,
			from: getCurrentPages()[getCurrentPages().length - 3] ? getCurrentPages()[getCurrentPages().length - 3].route : null,
			backFrom: this.$AppContext.getCurrentPage().route
		}
		console.log('### navigateGo: ' + this.$AppContext.$Navigate.backFrom)
		console.warn($nothing._copy(this.$AppContext.$Navigate))
		this.$AppContext.$router.back()
	},
	/**
	 * 页面显示处理
	 * @param vm
	 */
	pageOnShow: (vm) => {
		this.$AppContext.$vm = vm
		// 将导航对象设置到当前页对象
		this.$AppContext.getCurrentPage().setData({
			$Navigate: $nothing._copy(this.$AppContext.$Navigate)
		})
		// 还原导航对象
		this.$AppContext.$Navigate = {
			path: null,
			params: null,
			isTab: false,
			isBack: false,
			isCancel: false,
			reLaunch: false,
			from: null
		}
		// BACK后跳转处理
		if (this.$AppContext.getNavigate().isBack && this.$AppContext.getNavigate().backNavigate) {
			let backNavigate = this.$AppContext.getNavigate().backNavigate
			if (backNavigate.type === 'BACK') {
				this.$AppContext.navigateBack(backNavigate.options)
			} else if (backNavigate.type === 'REPLACE') {
				this.$AppContext.replaceTo(backNavigate.options)
			} else if (backNavigate.type === 'TAB') {
				this.$AppContext.navigateToTab(backNavigate.options)
			} else {
				this.$AppContext.navigateTo(backNavigate.options)
			}
		}
	},
	/**
	 * 页面卸载处理
	 */
	pageOnUnload: ({
		backNavigate = null,
		params = null
	} = {}) => {
		// 是否取消操作(系统按键返回)
		if (!this.$AppContext.$Navigate.isBack) {
			this.$AppContext.$Navigate = {
				path: this.$AppContext.getPreviousPage().route,
				params: null,
				isTab: false,
				isBack: true,
				isCancel: true,
				reLaunch: false,
				from: getCurrentPages()[getCurrentPages().length - 3] ? getCurrentPages()[getCurrentPages().length - 3].route : null,
				backFrom: this.$AppContext.getCurrentPage().route
			}
			console.log('### sysBack: ' + this.$AppContext.$Navigate.backFrom)
			console.warn($nothing._copy(this.$AppContext.$Navigate))
		}
		// 如传递参数，则进行合并
		if (params) {
			if (this.$AppContext.$Navigate.params) {
				Object.assign(this.$AppContext.$Navigate.params, params)
			} else this.$AppContext.$Navigate.params = params
		}
		this.$AppContext.$Navigate.backNavigate = backNavigate
	}
}

if (typeof wx !== 'undefined' && !wx.miniProgram) {
  // 小程序环境
  wx.$AppContext = $AppContext
} else {
  window.$AppContext = $AppContext
  Object.assign(window, $AppContext)
}

export default $AppContext
