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

import cn.myapps.authtime.privilege.operation.model.OperationVO;
import cn.myapps.common.auth.IUser;
import cn.myapps.common.controller.Resource;
import cn.myapps.common.controller.ResourceNotFoundException;
import cn.myapps.common.data.ParamsTable;
import cn.myapps.common.util.PropertyUtil;
import cn.myapps.designtime.common.service.DesignTimeServiceManager;
import cn.myapps.designtime.form.service.FormDesignTimeService;
import cn.myapps.designtime.permission.PermissionUtil;
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.FormDataPacket;
import cn.myapps.runtime.dynaform.form.ejb.Form;
import cn.myapps.runtime.dynaform.form.service.FormRunTimeService;
import cn.myapps.util.StringUtil;
import cn.myapps.common.util.cache.MemoryCacheUtil;
import com.bcxin.saas.core.exceptions.SaasNofoundException;
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 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.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.Map;

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

/**
 * Form Restful 接口
 *
 * @author ahan
 *
 */
@Api(tags = "表单执行模块")
@Component
@RequestMapping(path = "/api/runtime/{applicationId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class FormController extends AbstractRuntimeController {

	@Autowired
	private FormRunTimeService formRunTimeService;

	/**
	 * 获取表单信息
	 * @param applicationId 软件id
	 * @param formid 表单id
	 * @param docid 文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/forms/{formid}/documents/{docid}")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "获取表单信息", notes = "获取表单信息")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "formid",value = "表单Id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "docid",value = "文档Id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "isReadonly",value = "是否只读",required = false,paramType = "query",dataType = "boolean")
	})
	public Resource findFormDataPacket(@PathVariable String applicationId, @PathVariable String formid,
			@PathVariable String docid, @RequestParam(required = false) boolean isReadonly) throws Exception {
		FormDataPacket result = formRunTimeService.findFormDataPacket(applicationId, formid, docid, isReadonly, getParams(),
				getUser());

		if (result != null) {
			MemoryCacheUtil.putToPrivateSpace(result.getDocument().getId(), result.getDocument(), getUser());
			return success("ok", result);
		} else {
			throw new ResourceNotFoundException("Not Found");
		}
	}

	/**
	 * 判断表单打开权限
	 * @param applicationId 软件id
	 * @param formid 表单id
	 * @param docid 文档id
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/forms/{formid}/documents/{docid}/openable")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "判断表单打开权限", notes = "判断表单打开权限")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "formid",value = "表单Id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "docid",value = "文档Id",required = true,paramType = "path",dataType = "string")
	})
	public Resource documentOpenable(@PathVariable String applicationId, @PathVariable String formid,
			@PathVariable String docid) throws Exception {
		boolean openable = formRunTimeService.openable(applicationId, formid, docid, getParams(), getUser());
		return success("ok", openable);
	}

	/**
	 * 判断表单打开权限
	 * @param applicationId 软件id
	 * @param formId 表单id
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/forms/{formId}/openable")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "判断表单打开权限", notes = "判断表单打开权限")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
			@ApiImplicitParam(name = "formId",value = "表单Id",required = true,paramType = "path",dataType = "string")
	})
	public Resource documentOpenable(@PathVariable String applicationId, @PathVariable String formId) throws Exception {
		FormDesignTimeService formService = DesignTimeServiceManager.formDesignTimeService();
		Form form = formService.doView(formId);
		if(form==null) {
			throw new SaasNofoundException(String.format("无效表(%s)单信息", formId));
		}

		boolean allow = true;
		if(!Form.PERMISSION_TYPE_PUBLIC.equals(form.getPermissionType())){
			IUser user = getUser();
			String[] roleids = user.getRolelist(applicationId).split(",");
			allow = PermissionUtil.check(roleids, formId, formId, OperationVO.FORM_VIEW_ALLOW_OPEN);
		}

		return success("ok", allow);
	}

	/**
	 * 刷新表单
	 * @param applicationId 软件id
	 * @param formid 表单id
	 * @param docid 文档id
	 * @param content
	 * @return
	 * @throws Exception
	 */
	@PostMapping(path = "/forms/{formid}/documents/{docid}/refresh")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "刷新表单", notes = "刷新表单")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "formid",value = "表单Id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "docid",value = "文档Id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "content",value = "请求内容",required = true,paramType = "body",dataType = "string")
	})
	public Resource documentRefresh(@PathVariable String applicationId, @PathVariable String formid,
			@PathVariable String docid, @RequestBody String content) throws Exception {
		IUser user = getUser();
		if (user == null) {
			throw new Exception("用户未登陆");
		}
		Configuration configuration = Configuration.defaultConfiguration();
		configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);

		DocumentContext parse = parse(content, configuration);
		String actField = parse.read("$.actField");
		String tabId = parse.read("$.tabId");
		Map<String, Object> items = parse.read("$.document.items");

		ParamsTable params = getParams();
		String templateForm = parse.read("$.document.templateForm");
		params.setParameter("templateForm", templateForm);

		Map<String, Object> refresh = formRunTimeService.refresh(applicationId, formid, docid, actField, tabId, items,
				params, user);
		return success("ok", refresh);
	}

	/**
	 * 新建空文档
	 * @param applicationId 软件id
	 * @param formid 表单id
	 * @return
	 * @throws Exception
	 */
	@GetMapping(path = "/forms/{formid}/empty")
	@ResponseStatus(HttpStatus.OK)
	@ApiOperation(value = "新建空文档", notes = "新建空文档")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "applicationId",value = "软件id",required = true,paramType = "path",dataType = "string"),
		@ApiImplicitParam(name = "formid",value = "表单Id",required = true,paramType = "path",dataType = "string")
	})
	public Resource newDocument(@PathVariable String applicationId, @PathVariable String formid) throws Exception {
		ParamsTable params = getParams();
		params.setParameter("formId", formid);
		IUser user = getUser();
		Document doc = formRunTimeService.newDocument(applicationId, params, user);
		return success("ok", doc);
	}
	/**

	 * 获取上传控件水印
	 * @return
	 */
	@GetMapping("/getUploadFieldWaterMark")
	@ResponseBody
	public String getUploadFieldWaterMark(@RequestParam String waterMarkSetting){
		try {
			ParamsTable params = ParamsTable.convertHTTP(request);
			IUser user = getUser();
//			String encoding = "utf-8";
//			waterMarkSetting = URLDecoder.decode(waterMarkSetting.replace("%20", "%2B"), encoding);

			//判断waterMarkSetting是否为空
			if(!StringUtil.isBlank(waterMarkSetting)){
				net.sf.json.JSONObject setting = net.sf.json.JSONObject.fromObject(waterMarkSetting);
				String applicationid = setting.getString("applicationId");
				String docId = setting.getString("docId");
				String itemId = setting.getString("itemId");

				if(!StringUtil.isBlank(applicationid)){
					DocumentProcess docProcess = RunTimeServiceManager.documentProcess( applicationid);
					String result = docProcess.getUploadFieldWaterMark(docId,itemId,user,params);
					return result;
				}
			}
		}  catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

    /**
     * 返回水印文件路径
     */
	@ResponseBody
	@RequestMapping("/fileDownloadWithWaterMark")
	public String doFileDownloadWithWaterMark(@RequestParam String filename,@RequestParam String filepath,@RequestParam String waterMarkSetting) throws Exception{
		OutputStream os = null;
		File file = null;
		InputStream ins = null;
		try {
			String encoding = "ISO-8859-1";
			filename = filename.substring(0,filename.lastIndexOf("."))+".pdf";
			if(!filepath.startsWith("/uploads/")){
				return "none";
			}
			filepath = URLDecoder.decode(filepath, encoding);
			String realPath = PropertyUtil.getPath();

			//waterMarkSetting = URLDecoder.decode(URLDecoder.decode(waterMarkSetting.replace("%20", "%2B"), encoding), encoding);

			//判断waterMarkSetting是否为空
			if(!StringUtil.isBlank(waterMarkSetting)){
				net.sf.json.JSONObject setting = net.sf.json.JSONObject.fromObject(waterMarkSetting);
				String applicationid = setting.getString("applicationId");
				String docId = setting.getString("docId");
				String itemId = setting.getString("itemId");
				DocumentProcess docProcess = RunTimeServiceManager.documentProcess( applicationid);
				file = docProcess.getPdfWithWaterMark(docId,itemId,realPath,filepath,filename,getUser());
			}

			return file.getAbsolutePath();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ins != null) {
				try {
					ins.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return "none";
	}
}
