package cn.myapps.runtime.dynaform.view.controller;

import cn.myapps.common.auth.IUser;
import cn.myapps.common.controller.Resource;
import cn.myapps.common.data.ParamsTable;
import cn.myapps.common.model.view.AbstractView;
import cn.myapps.common.model.view.Column;
import cn.myapps.designtime.common.service.DesignTimeServiceManager;
import cn.myapps.designtime.view.column.service.ColumnDesignTimeService;
import cn.myapps.designtime.view.service.ViewDesignTimeService;
import cn.myapps.runtime.common.controller.AbstractRuntimeController;
import cn.myapps.runtime.common.service.RunTimeServiceManager;
import cn.myapps.runtime.dynaform.document.ejb.Document;
import cn.myapps.runtime.dynaform.document.ejb.DocumentProcess;
import cn.myapps.runtime.dynaform.form.ejb.ValidateMessage;
import cn.myapps.runtime.dynaform.view.service.ViewHelperRunTimeService;
import cn.myapps.runtime.macro.runner.IRunner;
import cn.myapps.runtime.macro.runner.JavaScriptFactory;
import cn.myapps.runtime.macro.runner.JsMessage;
import cn.myapps.util.Security;
import cn.myapps.util.StringUtil;
import cn.myapps.common.util.cache.MemoryCacheUtil;
import cn.myapps.util.http.HttpRequestUtil;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.Option;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

import static com.jayway.jsonpath.JsonPath.parse;

/**
 * @author spy
 * 视图工具的接口
 */
@Api
@Component
@RequestMapping(path = "/api/runtime", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class ViewHelperController extends AbstractRuntimeController {

	@Autowired
	private ViewHelperRunTimeService service;

	/**
	 * 执行视图选择框确定回调脚本
	 * @param formId
	 * 		表单id
	 * @param docId
	 * 		文档id
	 * @param fieldId
	 * 		控件id
	 * @return
	 * @throws Exception
	 */
	@PostMapping(path = "/views/selectbox/runViewDialogCallbackScript")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "执行视图选择框确定回调脚本", notes = "执行视图选择框确定回调脚本")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource runViewDialogCallbackscript(@RequestBody String content) throws Exception {
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
		DocumentContext parse = parse(content, configuration);

		String fieldId = parse.read("$.fieldId");
		String docId = parse.read("$.document.id");
		String formId = parse.read("$.document.formId");
		String _selects = parse.read("$._selects");
		String callbackScript = parse.read("$.callbackScript");
		if (!StringUtil.isBlank(callbackScript)) {
			callbackScript = StringUtil.dencodeHTML(callbackScript);
			callbackScript = callbackScript.replaceAll("@123@","#");
		}

		Map<String, Object> items = parse.read("$.document.items");
		if (items == null)items = new HashMap<String, Object>();
		items.put("_selects", _selects);

		ParamsTable params = getParams();
		for (Map.Entry<String, Object> entry : items.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			params.setParameter(key, value);
		}

		com.alibaba.fastjson.JSONObject result = null;
		if (fieldId == null || fieldId.trim().isEmpty()) {
			if (callbackScript != null && !callbackScript.trim().isEmpty()) {
				result = service.runViewDialogCallbackscript(formId, callbackScript, docId, params, getUser());
			}
		} else {
			result = service.runViewDialogCallbackscriptByFieldId(formId, fieldId, docId, params, getUser());
		}

		return success("ok",result);
	}

	/**
	 * 执行视图选择框确定脚本
	 * @param formId
	 * 		表单id
	 * @param docId
	 * 		文档id
	 * @param fieldId
	 * 		控件id
	 * @return
	 * @throws Exception
	 */
	@PostMapping(path = "/views/selectbox/runViewDialogConfirmScript")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "执行视图选择框确定脚本", notes = "执行视图选择框确定脚本")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource runViewDialogConfirmScript(@RequestBody String content) throws Exception {
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
		DocumentContext parse = parse(content, configuration);

		String fieldId = parse.read("$.fieldId");
		String docId = parse.read("$.document.id");
		String formId = parse.read("$.document.formId");
		String _selects = parse.read("$._selects");

		String okScript = parse.read("$.okScript");
		if (!StringUtil.isBlank(okScript)) {
			okScript = StringUtil.dencodeHTML(okScript);
			okScript = okScript.replaceAll("@123@","#");
		}
		Map<String, Object> items = parse.read("$.document.items");
		if (items == null)items = new HashMap<String, Object>();
		items.put("_selects", _selects);

		ParamsTable params = getParams();
		for (Map.Entry<String, Object> entry : items.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			params.setParameter(key, value);
		}


		String result = "";
		if (fieldId == null || fieldId.trim().isEmpty()) {
			if (okScript != null && !okScript.trim().isEmpty()) {
				result = service.runViewDialogConfirmScript(formId, okScript, docId, params, getUser());
			}
		}
		else {
			result = service.runViewDialogConfirmScriptByFieldId(formId, fieldId, docId, params, getUser());
		}

		return success("ok",result);
	}

	/**
	 * 执行视图列操作按钮的脚本
	 * @param applicationId
	 * 		软件id
	 * @param viewId
	 * 		视图id
	 * @param columnId
	 * 		视图列id
	 * @return
	 * @throws Exception
	 */
	@PutMapping(path = "/{applicationId}/views/{viewId}/columns/{columnId}/runActionScript")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "执行视图列操作按钮的脚本", notes = "执行视图列操作按钮的脚本")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "viewId",value = "视图Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "columnId",value = "视图列Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource runViewColumnActionScript(@PathVariable String applicationId, @PathVariable String viewId, @PathVariable String columnId, @RequestBody String content) throws Exception {
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
		DocumentContext parse = parse(content, configuration);
		String docId = parse.read("$.docId");
		//String actionScript = parse.read("$.actionScript");
		String columnName = parse.read("$.columnName");
		ColumnDesignTimeService columnService = DesignTimeServiceManager.columnDesignTimeService();
		Column column = columnService.findById(columnId);
		String actionScript = column.getActionScript();
		JSONObject JsonObj = new JSONObject();
		if(!StringUtil.isBlank(actionScript)){
			IUser user = getUser();
			ParamsTable params = getParams();
			Document doc = (Document) MemoryCacheUtil.getFromPrivateSpace(docId, user);
			if(doc == null ){
				DocumentProcess dp = RunTimeServiceManager.documentProcess( applicationId);
				doc = (Document) dp.doView(docId);
			}
			ViewDesignTimeService viewService = DesignTimeServiceManager.viewDesignTimeService();
			AbstractView view = viewService.doView(viewId);
			IRunner runner = JavaScriptFactory.getInstance(user.getSessionid(),applicationId);
			runner.initBSFManager(doc, params, getUser(), new java.util.ArrayList<ValidateMessage>());
			StringBuffer label = new StringBuffer();
			label.append("Button Action:[viewName:").append(view.getName()).append("][colName:").append(columnName).append("]").append(columnId).append("ActionScript");
			Object result = runner.run(column,label.toString(), actionScript);
			if (result != null) {
				if (result instanceof String
						&& ((String) result).trim().length() > 0) {
					result = new JsMessage(JsMessage.TYPE_SUCCESS,
							(String) result);
				}
			}

			if (result != null && result instanceof JsMessage
					&& !StringUtil.isBlank(((JsMessage) result).getContent())) {
				JsonObj.put("type", ((JsMessage) result).getType());
				JsonObj.put("content", ((JsMessage) result).getContent());
			}
		}
		return success("ok",JsonObj);
	}

	/**
	 * 执行视图列操作按钮的执行前脚本
	 * @param applicationId
	 * 		软件id
	 * @param viewId
	 * 		视图id
	 * @param columnId
	 * 		视图列id
	 * @return
	 * @throws Exception
	 */
	@PutMapping(path = "/{applicationId}/views/{viewId}/columns/{columnId}/beforescript")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "执行视图列操作按钮的执行前脚本", notes = "执行视图列操作按钮的执行前脚本")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "viewId",value = "视图Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "columnId",value = "视图列Id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "content",value = "请求包体",required = true,paramType = "body",dataType = "string")
	})
	public Resource runViewColumnBeforeScript(@PathVariable String applicationId, @PathVariable String viewId, @PathVariable String columnId, @RequestBody String content) throws Exception {
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
		DocumentContext parse = parse(content, configuration);
		String docId = parse.read("$.docId");
		String columnName = parse.read("$.columnName");
		ColumnDesignTimeService columnService = DesignTimeServiceManager.columnDesignTimeService();
		Column column = columnService.findById(columnId);
		String beforeScript = column.getBeforeScript();
		JSONObject JsonObj = new JSONObject();
		if(!StringUtil.isBlank(beforeScript)){
			IUser user = getUser();
			ParamsTable params = getParams();
			Document doc = (Document) MemoryCacheUtil.getFromPrivateSpace(docId, user);
			if(doc == null ){
				DocumentProcess dp = RunTimeServiceManager.documentProcess( applicationId);
				doc = (Document) dp.doView(docId);
			}
			ViewDesignTimeService viewService = DesignTimeServiceManager.viewDesignTimeService();
			AbstractView view = viewService.doView(viewId);
			IRunner runner = JavaScriptFactory.getInstance(user.getSessionid(),applicationId);
			runner.initBSFManager(doc, params, getUser(), new java.util.ArrayList<ValidateMessage>());
			StringBuffer label = new StringBuffer();
			label.append("Button Action:[viewName:").append(view.getName()).append("][colName:").append(columnName).append("]").append(columnId).append("BeforeScript");
			Object result = runner.run(column, label.toString(), beforeScript);
			if (result != null) {
				if (result instanceof String
						&& ((String) result).trim().length() > 0) {
					result = new JsMessage(JsMessage.TYPE_DANGER,
							(String) result);
				}
			}

			if (result != null && result instanceof JsMessage
					&& !StringUtil.isBlank(((JsMessage) result).getContent())) {
				JsonObj.put("type", ((JsMessage) result).getType());
				JsonObj.put("content", ((JsMessage) result).getContent());
			}
		}
		return success("ok",JsonObj);
	}

	/**
	 * gps定位纠偏
	 * @param x
	 * 		经度
	 * @param y
	 * 		维度
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/gps/convert")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "gps定位纠偏", notes = "gps定位纠偏")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "x",value = "经度",required = true,paramType = "query",dataType = "string"),
			@ApiImplicitParam(name = "y",value = "维度",required = true,paramType = "query",dataType = "string")
	})
	public Resource getExactGps(@RequestParam String from, @RequestParam String x, @RequestParam String y) throws Exception {
		String url = "http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" + x + "&y=" + y;
		JSONObject data = HttpRequestUtil.get(url, null);

		JSONObject result = new JSONObject();
		result.put("x", Security.decodeBASE64(data.getString("x")));
		result.put("y", Security.decodeBASE64(data.getString("y")));
		return success("ok",result);
	}
}
