package com.uas.eis.serviceImpl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.uas.eis.entity.ActionConfig;
import com.uas.eis.entity.ErrorMsg;
import com.uas.eis.exception.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.uas.eis.core.support.TokenHandler;
import com.uas.eis.dao.BaseDao;
import com.uas.eis.entity.QueryArgs;
import com.uas.eis.entity.QueryConfig;
import com.uas.eis.entity.QueryConfigDetail;
import com.uas.eis.service.QueryService;
import com.uas.eis.utils.BaseUtil;

import net.sf.json.JSONObject;

@Service
public class QueryServiceImpl implements QueryService {

	@Autowired
	private BaseDao baseDao;
	@Autowired
	private ActionConfig actionConfig;
	
	@Override
	public String login(String username, String password) {
		if(checkUser(username, password)) {
			return TokenHandler.createToken(username, password);
		}else {
			return null;
		}
	}
	
	@Override
	@Cacheable(value="userEnableCache")
	public boolean checkUser(String username, String password) {
		return baseDao.checkIf("EIS_USER", "eu_enable=-1 and " + "eu_name='" + username + "' and eu_password='" + password + "'");
	}

	@Override
	@Cacheable(value="userActionEnableCache")
	public boolean checkAction(String username, String action) {
		boolean flag = false;
		
		String roles = baseDao.queryForObject("select eu_role from eis_user where eu_name='" + username + "'", String.class);
		if(roles == null) {
			return false;
		}
		// 开放公共API的权限
		String apiAction = actionConfig.getApiAction();
		if(action.startsWith(apiAction)) {
			return true;
		}
		// 判断是否在不需要权限控制的请求配置中
		String[] publicActions = actionConfig.getPublicActions();
		for(String publicAction : publicActions) {
			if(publicAction.equals(action)) {
				return true;
			}
		}
		String[] fields = {"er_reg","er_action"};
		List<JSONObject> res = baseDao.getFieldsJSONDatasByCondition("EIS_ROLE", fields, "er_id in (" + roles + ")");
		for(int o = 0; o< res.size(); o++) {
			JSONObject data = res.get(o);
			String reg = data.containsKey("er_reg") ? data.getString("er_reg") : "(\\S)*";
			String act = data.containsKey("er_action") ? data.getString("er_action") : "";
			// 通过正则和预设接口校验请求权限
			if(action.matches(reg) || act.indexOf(action) != -1) {
				flag = true;
				break;
			}
		}
		return flag;
	}
	public String getUsers(){
		String sql = "SELECT EM_NAME,EM_CODE,TO_CHAR(EM_INDATE,'yyyy-MM-dd hh24:mm:ss') EM_INDATE FROM EMPLOYEE WHERE EM_CODE = 'U0818'";
		Map<String, Object> map = baseDao.getJdbcTemplate().queryForMap(sql);
		List<Map<String,Object>> list = baseDao.queryForList("SELECT * FROM UPLOADDOCDETAIL WHERE UDD_UDID=284");
		return BaseUtil.parseDataToJson(map,list);
	}
	
	/**
	 * 标准查询API
	 * @param code		查询方案Code
	 * @param param		参数
	 * @return
	 */
	public Object query(String code, String param){
		Map<String, Object> resultmap = new HashMap<String, Object>();
		List<Map<String, Object>> resultList = new ArrayList<Map<String,Object>>();
		com.alibaba.fastjson.JSONObject json = JSON.parseObject(param);
		//查询参数配置表
		String getInOutParamsSql = "select * from queryArgs where qa_qccode = ?";
		List<QueryArgs> inOutParamList = baseDao.query(getInOutParamsSql,  QueryArgs.class, code);
		Map<String, String> argsMap = new HashMap<String, String>();	//存参数名对应的参数值
		Map<String, String> argsTypeMap = new HashMap<String, String>();		//存参数名对应的参数类型
		for(QueryArgs args : inOutParamList){
			argsMap.put(args.getQa_param(),json.getString(args.getQa_param()));
			argsTypeMap.put(args.getQa_param(), args.getQa_paramtype());
		}
		//校验查询方案传入的参数是否正确
		checkParam(code, param);
		//code对应的查询方案
		String getQueryConfigsql = "select * from queryconfig where qc_code=? order by qc_detno"; 
		List<QueryConfig> queryConfigList = baseDao.query(getQueryConfigsql, QueryConfig.class, code);
		if(queryConfigList != null){
			List<String> valueList = new ArrayList<String>();
			Object mainField = baseDao.getFieldDataByCondition("queryArgs", "qa_param", "qa_qccode='"+code+"' and qa_ismainfield=1");
			if(mainField != null && "array".equals(argsTypeMap.get(mainField))){
				String argValue = argsMap.get(mainField);
				String[] valueArray = argValue.replace("[", "").replace("]", "").replaceAll("\"", "").split(",");
				valueList = new ArrayList<String>(Arrays.asList(valueArray));
			}else{
				valueList.add(argsMap.get(mainField));
			}
			for(int i = 0; i < valueList.size(); i++){
				Map<String, Object> map = new HashMap<String, Object>();
				for(QueryConfig queryConfig : queryConfigList){
					StringBuilder inParam = new StringBuilder();
					StringBuilder outParam = new StringBuilder();
					//查询方案明细表，得到要查询的字段
					String getQueryFieldssql = "select * from queryConfigDetail where qcd_qcid = ?";
					List<QueryConfigDetail> queryFieldsList = baseDao.query(getQueryFieldssql, QueryConfigDetail.class, queryConfig.getQc_id());
					StringBuilder sb = new StringBuilder();
					sb.append("select ");
					for(QueryConfigDetail field : queryFieldsList){
						sb.append(field.getQcd_field() + " \"" + field.getQcd_mappingkey() + "\",");
					}
					sb.deleteCharAt(sb.length()-1);			//去掉最后一个 ,
					sb.append(" from " + queryConfig.getQc_table());
					//拼接condition
					String condition = queryConfig.getQc_condition();
					Pattern pattern = Pattern.compile("@[\\w]+");		//通过正则替换@变量
					Matcher m = pattern.matcher(condition);
					List<String> matchList = new ArrayList<String>();
					while(m.find()){
						matchList.add(m.group());
					}
					for(String match : matchList){
						/*if("array".equals(argsTypeMap.get(match.replace("@", "")))){
							String value = argsMap.get(match.replace("@", ""));
							value = value.replaceAll("\"", "'");
							condition = condition.replaceAll(match, value);
						}else{
							condition = condition.replaceAll(match, "'"+argsMap.get(match.replace("@", ""))+"'");
						}*/
						if(match.equals("@"+mainField)){
							condition = condition.replaceAll(match, "'"+valueList.get(i)+"'");
							inParam.append(mainField+"="+valueList.get(i)+";");
						}else{
							condition = condition.replaceAll(match, "'"+argsMap.get(match.replace("@", ""))+"'");
							inParam.append(match.replace("@","")+"="+argsMap.get(match.replace("@", ""))+";");
						}
					}
					sb.append(" " + condition);		//append where条件
					//append order by语句
					if(!StringUtils.isEmpty(queryConfig.getQc_orderby())){
						sb.append(" " + queryConfig.getQc_orderby());
					}
					if(queryFieldsList != null && queryFieldsList.size()>0){
						if(queryConfig.getQc_isArray() != null && queryConfig.getQc_isArray() == 0){
							map.put(queryConfig.getQc_mapkey(), baseDao.getJdbcTemplate().queryForMap(sb.toString()));
						}else{
							map.put(queryConfig.getQc_mapkey(), baseDao.queryForList(sb.toString()));
						}
					}
					
					//获取额外返回值
					if(!StringUtils.isEmpty(queryConfig.getQc_return())){
						String getReturnSql = "select " + queryConfig.getQc_return() + " from " + queryConfig.getQc_table() + " " + condition;
						Map<String, Object> returnMap = baseDao.getJdbcTemplate().queryForMap(getReturnSql);
						List<Object> list = baseDao.getFieldDatasByCondition("queryArgs", "qa_param", "qa_qccode='"+queryConfig.getQc_code()+"' and qa_relation="+queryConfig.getQc_id()+" order by qa_detno");
						Iterator<Object> it = returnMap.values().iterator();
						int j = 0;
						while(it.hasNext()){
							String value = String.valueOf(it.next());
							argsMap.put(String.valueOf(list.get(j)), value);
							outParam.append(String.valueOf(list.get(j))+"="+value+";");
							j++;
						}
					}
					//记录日志
					String insertSql = "INSERT INTO QUERYLOG(QL_ID,QL_QCCODE,QL_PARAM,QL_RETURN,QL_DATE) VALUES(QUERYLOG_SEQ.NEXTVAL,'"+queryConfig.getQc_code()+"','"+inParam.toString()+"','"+outParam.toString()+"',SYSDATE)";
					baseDao.execute(insertSql);
				}
				if(valueList.size() > 1){
					resultList.add(map);
				}else{
					resultmap.putAll(map);
				}
			}
			if(valueList.size() > 1)
				return resultList;
			else
				return resultmap;
		}else{
			return resultmap;
		}
		
	}
	
	public Object doAction() {
		return null;
	}
	
	/**
	 * 传入参数的合法性校验
	 * @param code
	 * @param param
	 */
	private void checkParam(String code, String param){
		com.alibaba.fastjson.JSONObject json = JSON.parseObject(param);
		if(StringUtils.isEmpty(code)){
			throw new SystemException(ErrorMsg.NULL_QUERY_CODE);
		}
		if(json == null){
			throw new SystemException(ErrorMsg.PARAM_AMOUNT_ERROR);
		}
		String getInParamsSql = "select * from queryArgs where qa_qccode = ? and qa_relation is null";
		List<QueryArgs> inParamList = baseDao.query(getInParamsSql,  QueryArgs.class, code);
		if(inParamList.size() != json.size()){
			throw new SystemException(ErrorMsg.PARAM_AMOUNT_ERROR);
		}else{
			 for(QueryArgs queryArgs : inParamList){
				 if(json.getString(queryArgs.getQa_param()) == null){
					 throw new SystemException(ErrorMsg.PARAM_NAME_ERROR);
				 }else{
					 if("array".equals(queryArgs.getQa_paramtype())){
						 String stringArray = json.getString(queryArgs.getQa_param());
						 if(!(stringArray.contains("[") && stringArray.contains("]"))){
							 BaseUtil.showError(ErrorMsg.PARAM_FORMAT_ERROR,"传入的参数："+queryArgs.getQa_param()+"格式不正确");
						 }
					 }
				 }
			 }
		}
	}

	@Override
	public Object doAction(String code, String param) {
		return null;
	}
	
	
	
}
