package weaver.formmode.virtualform;

import com.alibaba.fastjson.JSONObject;
import com.weaver.formmodel.util.StringHelper;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.ConnStatement;
import weaver.conn.RecordSet;
import weaver.docs.docs.DocExtUtil;
import weaver.file.FileUpload;
import weaver.formmode.data.ModeDataInterface;
import weaver.formmode.service.CommonConstant;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class VirtualFormHandler {
	
	private static Map<String, String> pkTypeInfoMap = new HashMap<String, String>();
	
	static{
		pkTypeInfoMap.put("1", SystemEnv.getHtmlLabelName(83174, Util.threadVarLanguage()));//32位ID (UUID)
		pkTypeInfoMap.put("2", SystemEnv.getHtmlLabelName(83175, Util.threadVarLanguage()));//主键自动增长
		pkTypeInfoMap.put("3", SystemEnv.getHtmlLabelName(83176, Util.threadVarLanguage()));//自定义主键策略
	}
	
	public static List<String> getPKTypeIdList(){
		List<String> result = new ArrayList<String>();
		result.addAll(pkTypeInfoMap.keySet());
		Collections.sort(result);
		return result;
	}
	
	public static String getPKTypeText(String pkTypeId){
		return Util.null2String(pkTypeInfoMap.get(pkTypeId));
	}
	
	/**
	 * 判断是否是虚拟表单
	 * @param formId
	 * @return
	 */
	public static boolean isVirtualForm(int formId){
		return isVirtualForm(String.valueOf(formId));
	}
	
	/**
	 * 判断是否是虚拟表单
	 * @param formId
	 * @return
	 */
	public static boolean isVirtualForm(String formId){
		return VirtualFormCacheManager.isContainsVForm(formId);
	}

	/**
	 * 批量查询虚拟表单
	 * @param formIds
	 * @return
	 */
	public static List<String> filterNonVirtualFormIds(List<String> formIds){
		List<String> ids = new ArrayList<>();
		List<String> virtualForms = new ArrayList<>();
		//从缓存中取一遍
		formIds.forEach(any -> {
			if (VirtualFormCacheManager.isContainsVFormInCache(any)) {
				virtualForms.add(any);
			} else {
				ids.add(any);
			}
		});
		if (ids.size() == 0){
			return virtualForms;
		}
		//缓存中没有的查询数据库
		RecordSet rs = new RecordSet();
		String sqlwhere = StringUtils.join(ids,",");
		StringBuilder sqlbuilder = new StringBuilder(sqlwhere);
		//oracle的in超出1000处理
		if ("oracle".equalsIgnoreCase(rs.getDBType())){
			int time = ids.size()/1000;
			for (int i = 1; i < time + 1; i++){
				sqlbuilder = sqlbuilder.replace(StringUtils.ordinalIndexOf(sqlbuilder, ",", 999 * i),StringUtils.ordinalIndexOf(sqlbuilder, ",", 999 * i ) + 1,") or a.id in(");
			}
		}
		String sql = "select m.formid from workflow_bill a left join HtmlLabelInfo c on a.namelabel=c.indexid and c.languageid = 7 left join ModeFormExtend m on a.id=m.formid where m.isvirtualform = '1' and a.id in (" + sqlbuilder + ")";
		rs.executeQuery(sql);
		while (rs.next()) {
			virtualForms.add(rs.getInt("formid") + "");
		}
		return virtualForms;
	}
	
	public static Map<String, Object> getVFormInfo(int formId){
		return getVFormInfo(String.valueOf(formId));
	}
	
	public static Map<String, Object> getVFormInfo(String formId){
		Map<String, Object> vFormInfo = VirtualFormCacheManager.getVFormInCache(formId);
		return vFormInfo;
	}
	
	public static Object handlerSave(Map<String, Object> paramMap){
		
		int formid = Util.getIntValue(Util.null2String(paramMap.get("formid")));
		FileUpload fu = (FileUpload)paramMap.get("fu");
		
		Map<String, String> dataIDMap = new HashMap<String, String>();
		Map<String, String> dataNameMap = new HashMap<String, String>();
		
		RecordSet rs = new RecordSet();
		rs.executeProc("workflow_billfield_Select", String.valueOf(formid));
		while (rs.next()) {
			String fieldid = Util.null2String(rs.getString("id"));
			String fieldname = Util.null2String(rs.getString("fieldname"));
			
			String fieldV = fu.getParameter("field" + fieldid);
			
			dataIDMap.put(fieldid, fieldV);
			dataNameMap.put(fieldname, fieldV);
			
		}
		
		paramMap.put("dataIDMap", dataIDMap);
		paramMap.put("dataNameMap", dataNameMap);
		
		Map<String, Object> vFormInfo = getVFormInfo(formid);
		paramMap.put("vFormInfo", vFormInfo);
		
		String vpkgentype = Util.null2String(vFormInfo.get("vpkgentype"));	//主键生成策略
		AbstractPKVFormDataSave vFormDataSave = AbstractPKVFormDataSave.createInstance(vpkgentype);
		return vFormDataSave.saveData(paramMap);
	}
	
	
	public static Object handlerSaveApi(Map<String, Object> paramMap){
		
		int formid = Util.getIntValue(Util.null2String(paramMap.get("formid")));
		JSONObject jo = (JSONObject)paramMap.get("jo");
		HttpServletRequest request = (HttpServletRequest)paramMap.get("request");
		
		Map<String, String> dataIDMap = new HashMap<String, String>();
		Map<String, String> dataNameMap = new HashMap<String, String>();
		
		RecordSet rs = new RecordSet();
		rs.executeProc("workflow_billfield_Select", String.valueOf(formid));
		while (rs.next()) {
			String fieldid = Util.null2String(rs.getString("id"));
			String fieldname = Util.null2String(rs.getString("fieldname"));
			
			String fieldV = "";

			fieldV = Util.null2String(jo.get("field" + fieldid));
			
			if("".equals(fieldV)){
				fieldV = Util.null2String(request.getParameter("field" + fieldid));
			}
			
			dataIDMap.put(fieldid, fieldV);
			dataNameMap.put(fieldname, fieldV);
			
		}
		
		paramMap.put("dataIDMap", dataIDMap);
		paramMap.put("dataNameMap", dataNameMap);
		
		Map<String, Object> vFormInfo = getVFormInfo(formid);
		paramMap.put("vFormInfo", vFormInfo);
		
		String vpkgentype = Util.null2String(vFormInfo.get("vpkgentype"));	//主键生成策略
		AbstractPKVFormDataSave vFormDataSave = AbstractPKVFormDataSave.createInstance(vpkgentype);
		return vFormDataSave.saveData(paramMap);
	}
	
	@SuppressWarnings(value="unchecked")
	public static Object saveData(Map<String, Object> paramMap){
		
		int formid = Util.getIntValue(Util.null2String(paramMap.get("formid")));
		Map<String, String> dataIDMap = (Map<String, String>)paramMap.get("dataIDMap");
		String iscreate = Util.null2String(paramMap.get("iscreate"));
		String billid = Util.null2String(paramMap.get("billid"));
		String formmodeid = Util.null2String(paramMap.get("formmodeid"));
		int pageexpandid = Util.getIntValue(Util.null2String(paramMap.get("pageexpandid")));
		User user = (User) paramMap.get("user");
		Map<String, Object> vFormInfo = (Map<String, Object>)paramMap.get("vFormInfo");
		String billtablename = Util.null2String(vFormInfo.get("tablename"));
		billtablename = VirtualFormHandler.getRealFromName(billtablename);
		String vdatasource = Util.null2String(vFormInfo.get("vdatasource"));
		String vprimarykey = Util.null2String(vFormInfo.get("vprimarykey"));	//主键列名称
		String src = Util.null2String(paramMap.get("src"));
		if(src.equals("del")){
			RecordSet delrs = new RecordSet();
			String billidSQLV = "";
			if(!billid.equals("")){
				billidSQLV = "'" + billid + "'";
			}
			
			//删除操作先执行action与实际表单一致
			ModeDataInterface modeDataInterface = new ModeDataInterface(billid, Util.getIntValue(formmodeid));
			modeDataInterface.setPageexpandid(pageexpandid);
			modeDataInterface.setUser(user);
			modeDataInterface.execute();
			delrs.executeSql("delete from "+billtablename+" where "+vprimarykey+" = "+billidSQLV,vdatasource);
			return billid;
		}
		
		boolean isoracle = CommonConstant.DB_TYPE.equals("oracle");
		Map htmlfieldMap = new HashMap();
		int userlanguage = 7;
		
		RecordSet rs = new RecordSet();
		rs.executeProc("workflow_billfield_Select", String.valueOf(formid));
		
        Map<String, Object> dataSQLMap = new HashMap<String, Object>();
        
		while (rs.next()) {
			String viewtype = Util.null2String(rs.getString("viewtype"));   // 如果是从表字段,不进行操作
			if (viewtype.equals("1")) continue;
			String fieldid = Util.null2String(rs.getString("id"));
			String fieldname = Util.null2String(rs.getString("fieldname"));
			String fielddbtype = Util.null2String(rs.getString("fielddbtype"));
			String fieldhtmltype = Util.null2String(rs.getString("fieldhtmltype"));
			String fieldtype = Util.null2String(rs.getString("type"));
			
			if(fieldname.equals(vprimarykey)){
				continue;
			}
			
			String fieldV = (String)dataIDMap.get(fieldid);
			
			if (isoracle) {
				if ((fielddbtype.toUpperCase()).indexOf("INT") >= 0){
					if("5".equals(fieldhtmltype)){
						 if (!(Util.null2String(fieldV)).equals("")) {
							 dataSQLMap.put(fieldname, Util.getIntValue(fieldV, -1));
						 } else {
                        	 dataSQLMap.put(fieldname, "NULL");
                         }
					}else{
						 if (!(Util.null2String(fieldV)).equals("")) {
							 dataSQLMap.put(fieldname, Util.getIntValue(fieldV, 0));
						 } else {
                        	 dataSQLMap.put(fieldname, "NULL");
                         }
					}
				}else if ((fielddbtype.toUpperCase()).indexOf("NUMBER") >= 0||(fielddbtype.toUpperCase()).indexOf("FLOAT") >= 0){
					int digitsIndex = fielddbtype.indexOf(",");
					int decimaldigits = 2;
		        	if(digitsIndex > -1){
		        		decimaldigits = Util.getIntValue(fielddbtype.substring(digitsIndex+1, fielddbtype.length()-1).trim(), 2);
		        	}else{
		        		decimaldigits = 2;
		        	}
		        	if (!(Util.null2String(fieldV)).equals("")) {
		        		dataSQLMap.put(fieldname, Util.getPointValue2(fieldV,decimaldigits));
		        	}
		        	else {
		        		dataSQLMap.put(fieldname, "NULL");
		        	}
				}else if(fieldhtmltype.equals("6")){
					String tempvalue="";
					tempvalue=Util.null2String(fieldV);

					DocExtUtil docExtUtil = new DocExtUtil();
					String[] oldUploadIdsStrs = null;
					String oldUploadIdsStrs_ = "";
					if(!iscreate.equals("1")){	//非创建时，因为创建时是不可能有数据的
						RecordSet rsUploadId = new RecordSet();
						rsUploadId.executeSql("select "+fieldname+" from "+ billtablename +" where "+vprimarykey+" = " + billid, vdatasource);
						if(rsUploadId.next()){
							oldUploadIdsStrs_ = rsUploadId.getString(fieldname);
						}
					}
					if(oldUploadIdsStrs_ != null && !"".equals(oldUploadIdsStrs_)){
						oldUploadIdsStrs = Util.TokenizerString2(oldUploadIdsStrs_, ",");
					}
					if(!tempvalue.equals("")){
						dataSQLMap.put(fieldname, "'" + tempvalue + "'");
					}else if(tempvalue.equals("")){
						dataSQLMap.put(fieldname, "''");
					}
					if(oldUploadIdsStrs != null){
						for( int y =0; y < oldUploadIdsStrs.length; y++){
							if(tempvalue.indexOf(oldUploadIdsStrs[y]) == -1){
								if( Util.getIntValue(oldUploadIdsStrs[y],0) != 0 )
								docExtUtil.deleteDoc(Integer.parseInt(oldUploadIdsStrs[y]));
							}
						}
					}
				}else{
					boolean ishtml = false;
					String thetempvalue ="";
					if(fieldhtmltype.equals("3")&&(fieldtype.equals("161") || fieldtype.equals("162"))){
						thetempvalue = Util.null2String(fieldV);
						thetempvalue = thetempvalue.trim();
					}else{
						if(fieldhtmltype.equals("2")&&fieldtype.equals("2")){
							thetempvalue = Util.toHtml100(fieldV);
							ishtml = true;
						}else if(fieldhtmltype.equals("1")&&fieldtype.equals("1")){
							thetempvalue = Util.toHtmlForWorkflow(fieldV);
						}else{
							thetempvalue = Util.StringReplace(Util.toHtml10(fieldV)," ","&nbsp;");
						}
					}
					//判断如果是HTML类型，单独处理
					if(ishtml) {
						htmlfieldMap.put(fieldname, thetempvalue);
					}else{
						dataSQLMap.put(fieldname, "'" + thetempvalue + "'");
					}
				}
			} 
            else
            // 非ORACLE数据库
            {
				if ((fielddbtype.toUpperCase()).indexOf("INT") >= 0)
				{
				    if("5".equals(fieldhtmltype))
                    {
                        if (!"".equals(fieldV))
                        {
                            dataSQLMap.put(fieldname, Util.getIntValue(fieldV, -1));
                        }
                        else
                        {
                            dataSQLMap.put(fieldname, "NULL");
                        }
                    }
				    else
                    {
                        if (!"".equals(fieldV))
                        {
                            dataSQLMap.put(fieldname, Util.getIntValue(fieldV, 0));
                        }
                        else
                        {
                            dataSQLMap.put(fieldname, "NULL");
                        }
                    }
				}
				else if ((fielddbtype.toUpperCase()).indexOf("DECIMAL") >= 0||(fielddbtype.toUpperCase()).indexOf("FLOAT") >= 0)
                {
					int digitsIndex = fielddbtype.indexOf(",");
					int decimaldigits = 2;
		        	if(digitsIndex > -1){
		        		decimaldigits = Util.getIntValue(fielddbtype.substring(digitsIndex+1, fielddbtype.length()-1).trim(), 2);
		        	}else{
		        		decimaldigits = 2;
		        	}
                    if (!"".equals(fieldV))
                    {
                        dataSQLMap.put(fieldname, Util.getPointValue2(fieldV,decimaldigits));
                    }
                    else
                    {
                        dataSQLMap.put(fieldname, "NULL");
                    }
                }
                else if(fieldhtmltype.equals("6")){
					String tempvalue="";
					//处理附件
					tempvalue=Util.null2String(fieldV);
					//由RequestAddShareInfo统一处理附件上传字段的共享
					String[] oldUploadIdsStrs = null;
					DocExtUtil docExtUtil = new DocExtUtil();
					String oldUploadIdsStrs_ = "";
					if(!iscreate.equals("1")){	//非创建时，因为创建时是不可能有数据的
						RecordSet rsUploadId = new RecordSet();
						rsUploadId.executeSql("select "+fieldname+" from "+ billtablename +" where id = " + billid, vdatasource);
						if(rsUploadId.next()){
							oldUploadIdsStrs_ = rsUploadId.getString(fieldname);
						}
					}
					if(oldUploadIdsStrs_ != null && !"".equals(oldUploadIdsStrs_)){
						oldUploadIdsStrs = Util.TokenizerString2(oldUploadIdsStrs_, ",");
					}
					if(!tempvalue.equals("")){
						dataSQLMap.put(fieldname, "'" + tempvalue + "'");
					}else if(tempvalue.equals("")){
						dataSQLMap.put(fieldname, "''");
					}

					if(oldUploadIdsStrs != null){
						for( int y =0; y < oldUploadIdsStrs.length; y++){
							if(tempvalue.indexOf(oldUploadIdsStrs[y]) == -1){
								if( Util.getIntValue(oldUploadIdsStrs[y],0) != 0 ){
									docExtUtil.deleteDoc(Integer.parseInt(oldUploadIdsStrs[y]));	
								}
							}
						}
					}
				}else{
					boolean ishtml = false;
					String thetempvalue ="";
					if (fieldhtmltype.equals("2")&&fieldtype.equals("2")){
						thetempvalue = Util.toHtml100(fieldV);
						ishtml = true;
					}else if(fieldhtmltype.equals("1")&&fieldtype.equals("1")){
						thetempvalue = Util.toHtmlForWorkflow(fieldV);
					}else{
						thetempvalue = Util.StringReplace(Util.fromScreen2(fieldV, userlanguage)," ","&nbsp;");
					}
					//判断如果是HTML类型，单独处理
					if(ishtml) {
						htmlfieldMap.put(fieldname, thetempvalue);
					}else{
						dataSQLMap.put(fieldname, "'" + thetempvalue + "'");
					}
				}
			}
		}
		
		
		
		if(iscreate.equals("1")){	//新建
			String billidSQLV = "";
			if(!billid.equals("")){
				billidSQLV = "'" + billid + "'";
			}
			dataSQLMap.put(vprimarykey, billidSQLV);
			
			StringBuffer sqlBuffer = new StringBuffer();
			sqlBuffer.append("insert into ").append(billtablename);
			
			StringBuffer fieldBuffer = new StringBuffer();
			fieldBuffer.append("(");
			
			StringBuffer valueBuffer = new StringBuffer();
			valueBuffer.append(" values(");
			
			Set<String> fieldnameSet = dataSQLMap.keySet();
			for(String fieldname : fieldnameSet){
				String v = Util.null2String(dataSQLMap.get(fieldname));
				if(!v.equals("")){
					fieldBuffer.append(fieldname).append(",");
					valueBuffer.append(v).append(",");
				}
			}
			fieldBuffer = fieldBuffer.deleteCharAt(fieldBuffer.length() - 1);
			valueBuffer = valueBuffer.deleteCharAt(valueBuffer.length() - 1);
			
			fieldBuffer.append(")");
			valueBuffer.append(")");
			
			sqlBuffer.append(fieldBuffer).append(valueBuffer);
			//System.out.println(sqlBuffer);
			
			rs.executeSql(sqlBuffer.toString(), vdatasource);
			if(StringHelper.isEmpty(billid)){
				rs.executeSql("select max("+vprimarykey+") from "+billtablename, vdatasource);
				if(rs.next()){
					billid = rs.getString(1);
				}
			}
			
		}else{	//修改
			
			StringBuffer sqlBuffer = new StringBuffer();
			sqlBuffer.append("update ").append(billtablename).append(" set ");
			
			StringBuffer fieldBuffer = new StringBuffer();
			
			Set<String> fieldnameSet = dataSQLMap.keySet();
			for(String fieldname : fieldnameSet){
				String v = Util.null2String(dataSQLMap.get(fieldname));
				if(!v.equals("")){
					fieldBuffer.append(fieldname).append("=").append(v).append(",");
				}
			}
			fieldBuffer = fieldBuffer.deleteCharAt(fieldBuffer.length() - 1);
			
			sqlBuffer.append(fieldBuffer);
			sqlBuffer.append(" where "+vprimarykey+"='"+billid+"'");
			//System.out.println(sqlBuffer);
			
			rs.executeSql(sqlBuffer.toString(), vdatasource);
		}
		
		
		
		try {
			String fdsql = "";
			fdsql = " update " + billtablename + " set ";
			int fdcn = 0;
			String fdsp = "";
			Iterator fdit = htmlfieldMap.entrySet().iterator();
			while(fdit.hasNext()) {
				fdcn++;
				Map.Entry entry = (Map.Entry) fdit.next();
				String key = entry.getKey().toString();
				fdsql += fdsp+" "+key+"=? ";
				fdsp = ",";
			}
			fdsql += " where "+vprimarykey+" = '" + billid+"'";
			if(fdcn>0) {
				ConnStatement fdst = null;
				try {
					fdst = new ConnStatement();
					fdst.setStatementSql(fdsql, vdatasource, true);
					fdit = htmlfieldMap.entrySet().iterator();
					fdcn = 0;
					while(fdit.hasNext()) {
						fdcn++;
						Map.Entry entry = (Map.Entry) fdit.next();
						String value = "";
						if(entry.getValue()!=null) {
							if(String.valueOf(entry.getValue()).equals(" ")) value = "";
							else value = String.valueOf(entry.getValue());
						}
						fdst.setString(fdcn, value);
					}
					fdst.executeUpdate();
				} catch (Exception e) {
					return false;
				} finally {
					if(fdst!=null) fdst.close(vdatasource);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		ModeDataInterface modeDataInterface = new ModeDataInterface(billid, Util.getIntValue(formmodeid));
		modeDataInterface.setPageexpandid(pageexpandid);
		modeDataInterface.setUser(user);
		modeDataInterface.execute();

		return billid;
	}
	
	/**
	 * 获取虚拟表单名称
	 * @param formName 真实表单名称
	 * @return 32位id_真实表单名称
	 */
	public static String getVirtualFormName(String formName){
		UUIDPKVFormDataSave fds = new UUIDPKVFormDataSave();
		return fds.generateID(null)+"_"+formName;
	}
	
	/**
	 * 获取真实表单名称
	 * @param virtualFormName 32位id_真实表单名称
	 * @return realFromName
	 */
	public static String getRealFromName(String virtualFormName){
		if(virtualFormName.length()>33&&virtualFormName.charAt(32)=='_'){
			virtualFormName = virtualFormName.substring(33);
		}
		return virtualFormName;
	}
	
	/**
	 * 获取真数据源在表单建模中是否有效
	 * @param dbType 数据源类型
	 * @return Boolean
	 */
	public static Boolean getDSIsEffectiveWithMode(String pointid,String dbType){
		boolean flag = true;
		boolean isflag = false;
		if(dbType.indexOf("sqlserver") != -1){
				String regEx="[^0-9]";
				Pattern p = Pattern.compile(regEx);
				Matcher m = p.matcher(dbType);
				int type = Util.getIntValue(m.replaceAll("").trim());
				isflag = type > 2000 ? false : true ;//仅支持2000以上的sqlserver
		}else{
			if(!"db2".equals(dbType)&&!"mysql".equals(dbType)&&!"mysql8".equals(dbType)&&!"oracle".equals(dbType)&&!"oracle12c".equals(dbType)
					&&!"jc".equals(dbType) &&!"gs".equals(dbType) &&!"dm".equals(dbType) &&!"st".equals(dbType)&&!"postgresql".equals(dbType.toLowerCase())
				&& !"informix".equals(dbType.toLowerCase())){
				flag = false;
			}
		}
		if(isflag){
			flag = false;
		}

	    if(pointid.equals("")){
	    	flag = false;
	    }
		return flag;
	}
	
	public static void main(String[] args){
		String str = VirtualFormHandler.getVirtualFormName("abc");
		//System.out.println(VirtualFormHandler.getRealFromName(str));
	}
}
