import {useTea} from "@/lib/tea.js";
import {provide, reactive, watch} from "vue";
import PopupStates from "@/utils/popup_states.js";
import useUtils from "@/utils/utils.js";
import "@/langs/base.js"

/**
 * initialize context
 *
 * @param {Object} target
 */
export default function initCtx(target) {
	const popupStates = new PopupStates()
	const isPopup = popupStates.length > 0
	const utils = useUtils()

	let Tea = null
	if (isPopup) {
		Tea = useTea({
			popup: true,
			popupState: popupStates.last()
		})
	} else {
		Tea = useTea({
			popup: false
		})
	}

	provide("$Tea", Tea)
	provide("$utils", utils)

	target.$Tea = Tea
	target.$utils = useUtils()
	target.$delay = Tea.delay
	target.$get = (action) => {
		return Tea.action(action).get()
	}
	target.$post = (action) => {
		return Tea.action(action).post()
	}
	target.$go = Tea.go
	target.$url = Tea.url
	target.$find = Tea.element
	target.$NotifyPopup = utils.popupFinish
	target.$NotifyReloadSuccess = function (message) {
		return function () {
			utils.success(message, function () {
				if (isPopup) {
					Tea.reloadViewData(popupStates.last().url)
				} else {
					Tea.reload()
				}
			})
		}
	}
	if (isPopup) {
		target.success = utils.popupFinish
	}
	target.$NotifySuccess = function (message, url, params) {
		if (typeof (url) == "string" && url.length > 0) {
			if (url[0] != "/") {
				url = Tea.url(url, params);
			}
		}
		return function () {
			utils.success(message, function () {
				if (isPopup) {
					utils.closePopup()
				} else {
					window.location = url
				}
			})
		}
	}

	if (isPopup) {
		const popupState = popupStates.last()
		for (let k in popupState.data) {
			target[k] = popupState.data[k]
		}
	} else {
		for (let k in window.X_VIEW_DATA) {
			target[k] = window.X_VIEW_DATA[k]
		}
	}

	const targetRef = reactive(target)
	Tea.CurrentContext = targetRef
	target.$ref = targetRef
	if (isPopup) {
		const popupState = popupStates.last()
		popupState.ctx = targetRef
	} else {
		if (window.X_VIEW_CTX) {
			targetRef.$parent = window.X_VIEW_CTX
		}
		window.X_VIEW_CTX = targetRef
	}

	target.$watch = (value, callback) => {
		// $watch("a.b.c")
		if (typeof value === "string") {
			const valueCopy = value
			value = () => {
				const expr = "this." + valueCopy
				return (function () {
					return eval(expr)
				}).call(targetRef)
			}
		}

		// $watch(() => this.a.b.c)
		watch(value, (...allArgs) => {
			callback.call(targetRef, ...allArgs)
		})
	}

	target.LANG = function (code) {
		if (window.LANG_MESSAGES != null) {
			let message = window.LANG_MESSAGES[code]
			if (typeof message == "string") {
				return message
			}
		}
		if (window.LANG_MESSAGES_BASE != null) {
			let message = window.LANG_MESSAGES_BASE[code]
			if (typeof message == "string") {
				return message
			}
		}
		return "{{ LANG('" + code + "') }}"
	}

	return {utils, Tea}
}
