package com.huigou.uasp.model.application.impl;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.google.common.base.CaseFormat;
import com.huigou.cache.SystemCache;
import com.huigou.data.domain.model.CommonDomainConstants;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.exception.ApplicationException;
import com.huigou.uasp.annotation.ControllerMapping;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.uasp.client.CommonController;
import com.huigou.uasp.form.repository.SafFormslistRepository;
import com.huigou.uasp.model.application.DbTablesApplication;
import com.huigou.uasp.model.domain.model.DbTables;
import com.huigou.uasp.model.domain.model.TablesMeta;
import com.huigou.uasp.model.domain.query.DbTablesQueryRequest;
import com.huigou.uasp.model.repository.DbTablesRepository;
import com.huigou.uasp.model.repository.TablesMetaRepository;
import com.huigou.uasp.util.Constant;
import com.huigou.uasp.util.Utils;


@Service("dbTablesApplication")
public class DbTablesApplicationImpl extends BaseApplication implements DbTablesApplication {

	// config文件路径
	static String QUERY_XML_FILE_PATH = "config/formdesign/dbtables.xml";

	@Autowired
	private DbTablesRepository dbTablesRepository;
	
	@Autowired
	private  TablesMetaRepository tablesMetaRepository;
	
	@Autowired
	private SafFormslistRepository syfFormsRepository;
	
	@Autowired
	private DbTableService dbTableService;
	
	//@Autowired
//	private ProcessDeletedData processDeletedData;
	
	private String pagePath = "/biz/mdm/model/";
	
	//int x=1;
	@Override
	public Map<String, Object> queryDbTables(DbTablesQueryRequest queryRequest) {
		return this.sqlExecutorDao.executeSlicedQuery(getQueryDescriptor("dbTables"), queryRequest);
	}
	
	
	@Override
	public List<Map<String, Object>> queryDbTableColumns(DbTablesQueryRequest queryRequest){
	  String sql = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH,"dbTables_columns").getSql();
	  return this.sqlExecutorDao.queryToListMap(sql,queryRequest.getTableName(),queryRequest.getTableName());
	}
	
	@Override
	public Map<String, Object> queryUserTables(DbTablesQueryRequest queryRequest) {
		return this.sqlExecutorDao.executeSlicedQuery( this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH,"userTables"), queryRequest);
	}
	
	/*
	  * 表名是否已经存在
	  */
	 public Map<String, Object> queryExistTableName(DbTablesQueryRequest queryRequest){
			Map <String,Object>map=new HashMap<String,Object>();
			  map.put("result","");
			 List <DbTables>list=this.dbTablesRepository.findByTableName(queryRequest.getTableName().toUpperCase());
			if (queryRequest.getId()!=null&&!"".equals(queryRequest.getId())){
			   if (list!=null&&list.size()>0){
				 DbTables dbTables=list.get(0);
				if (!(dbTables.getId()).equals(queryRequest.getId())){
					map.put("result", "表名"+queryRequest.getTableName().toUpperCase()+"已经存在！");
				}
			   }
			} else {
			   if (list.size()>0){
				 map.put("result", "表名"+queryRequest.getTableName().toUpperCase()+"已经存在！");
			   }
			}
			return map;
	 }
	  
	@SuppressWarnings("unchecked")
	@Transactional
	@Override
	public String saveUserTables(DbTablesQueryRequest queryRequest,List <Object>plist){
		//DbTablesQueryRequest queryRequest=new DbTablesQueryRequest();
		Map <String,Object>map=null;
		DbTables dbtable=null;
		String backStr="";
		//判断是否是修改
		if (queryRequest.getId()!=null&&!"".equals(queryRequest.getId())){
			dbtable=dbTablesRepository.findOne(queryRequest.getId());
			dbtable.setTableName(queryRequest.getTableName().toUpperCase());
			dbtable.setName(queryRequest.getName());
		   // List <TablesMeta>metaLists=this.tablesMetaRepository.findByTableId(dbtable.getId());
		    //for (TablesMeta meta:metaLists){
		    //   this.tablesMetaRepository.delete(meta);
		    //}
		    this.tablesMetaRepository.deleteTablesMetaByTableId(dbtable.getId());
		} else {
			 dbtable=new DbTables();
			List <DbTables>dblist=this.dbTablesRepository.findByTableName(queryRequest.getTableName().toUpperCase());
		    if (dblist!=null&&dblist.size()>0){	
			   backStr="表名已经存在！";
			   throw new IllegalArgumentException("表名"+queryRequest.getTableName().toUpperCase()+"已经存在！");
		    }
				dbtable.setTableName(queryRequest.getTableName().toUpperCase());
				dbtable.setParentId(queryRequest.getParentId());
				dbtable.setTableType("2");//表类型 
				dbtable.setType("2");
				dbtable.setStatus(1);
				dbtable.setPublished(0);
				dbtable.setName(queryRequest.getName());
		}
				dbtable=this.dbTablesRepository.saveAndFlush(dbtable);
				TablesMeta tablesMeta=null;

		for (int i=0;i<plist.size();i++) {
			map=(Map<String,Object>)plist.get(i);
			String metaId=map.get("id").toString();
			//String fieldName=map.get("fieldName").toString();
			String fieldCode=map.get("fieldCode").toString();
			tablesMeta=new TablesMeta();
			tablesMeta.setId(Utils.createUuid());
			tablesMeta.setTableId(dbtable.getId());
			tablesMeta.setMetaId(metaId);
			tablesMeta.setFieldCode(fieldCode);
			tablesMeta.setNums(Integer.parseInt(map.get("nums")!=null?map.get("nums").toString():"0"));
			tablesMeta.setStatus(1);
			this.tablesMetaRepository.save(tablesMeta);
			
		//	queryRequest.setTableName(tableName);
		   // QueryModel queryModel = this.sqlExecutorDao.getQueryModel(getQueryDescriptor("dbTablesByName"),queryRequest);
			//map=this.sqlExecutorDao.executeQuery(queryModel);
	
		}
		return backStr;
	}
	
	@Override
	@Transactional
	public void deleteUserTables(List <String>ids){
	  List<DbTables> dblist = this.dbTablesRepository.findAll(ids); 
	  DbTables obj=null;
	  for (int i=0;i<dblist.size();i++){
		  obj=(DbTables)dblist.get(i);
	      List <TablesMeta>metaLists=this.tablesMetaRepository.findByTableId(obj.getId());
	      for (TablesMeta meta:metaLists){
	        this.tablesMetaRepository.delete(meta);
	      }
	  }
	  this.dbTablesRepository.delete(dblist);
	}
	
	 /**
	  * 删除模型分类 
	  */
	 public void deleteModelClassData(List <String>ids){
		 
		  List<DbTables> dblist = this.dbTablesRepository.findAll(ids); 
		  DbTables obj=null;
		  List <?>list=null;
		  boolean flag=true;
		  for (int i=0;i<dblist.size();i++){
			  obj=(DbTables)dblist.get(i);
			  list=this.dbTablesRepository.findByParentId(obj.getId());
		     if (list!=null&&list.size()>0){
		    	 flag=false;
		    	 throw new ApplicationException(obj.getTableName()+obj.getName()+"存在子节点，不能删除！");
		     }
		  }
		  if (flag){
		    this.dbTablesRepository.delete(dblist);
		  }
	 }
	 
	 
	
	@Override
	public Map<String, Object> querySubDbTables(DbTablesQueryRequest queryRequest) {
        return this.sqlExecutorDao.executeQuery(getQueryDescriptor("dbTables"), queryRequest);
	}
	
	 /**
		 * 查询表中的所有字段
		 * @param queryRequest
		 * @return
		 */
	@Override
	public Map<String, Object> querySubDbTableFields(DbTablesQueryRequest queryRequest){
	    QueryModel queryModel = this.sqlExecutorDao.getQueryModel(getQueryDescriptor("dbTableFields"), queryRequest);
	   // String sql= queryModel.getSql();
	  //  sql+="  order by s.is_hidden ";  
	   // queryModel.setSql(sql);
	    Map <String,Object>map=new HashMap<String,Object>();
	    if (queryRequest.getTableId()!=null){
	    	map.put("tableId", queryRequest.getTableId());
	    }
	    if (queryRequest.getTableName()!=null){
	    	map.put("tableName", queryRequest.getTableName());
	    }
	    if (queryRequest.getIsHidden()!=null){
	    	map.put("isHidden", queryRequest.getIsHidden());
	    }
	    queryModel.setSortFieldName("is_hidden");
	    queryModel.setPageSize(100);// 默认100
		queryModel.setPageIndex(1);
	    queryModel.setQueryParams(map);

	   return  this.sqlExecutorDao.executeSlicedQuery(queryModel);
	  // return this.sqlExecutorDao.executeQuery(getQueryDescriptor("dbTableFields"), queryRequest);
	}

	private QueryDescriptor getQueryDescriptor(String entityName) {
	    return this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, entityName);
	}

//	private QueryDescriptor getQueryDescriptor() {
  //      return this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "dbTables");
 //   }

	//查询待选择的元数据
	@Override
	public Map<String, Object> queryAlternativeMetaLists(DbTablesQueryRequest queryRequest) {
		QueryDescriptor queryDescriptor = getQueryDescriptor("alternativeMetaData");
		Map<String, Object> map = this.sqlExecutorDao.executeSlicedQuery(queryDescriptor,queryRequest);
		return  map;
	}
	//查询已经选择的元数据
	@Override
	public List<Map<String, Object>> querySelectedMetaLists(DbTablesQueryRequest queryRequest) {
		String sql= getQueryDescriptor("selectedMetaData").getSql();
		List<Map<String, Object>> data = this.sqlExecutorDao.queryToListMap(sql, queryRequest.getTableId());
		return data;
	}
 	//************************************************************************************//
	/**
	 * 数据模型发布
	 */
	@Override
	@Transactional
	//parameter: tableId 、  （hasProcess=1表示有流程的）
	public Map<String, Object> publishToModelRecordTable(String  tableId,String hasProcess) {
		Map<String, Object> map = new HashMap<String, Object>();
		String backStr = "";
		String tableName = this.dbTableService.getTableName(tableId);
		try {
			DbTablesQueryRequest queryRequest=new DbTablesQueryRequest();
			queryRequest.setId(tableId);
			queryRequest.setTableId(tableId);
			queryRequest.setTableName(tableName);
			queryRequest.setHasProcess(hasProcess);
			List<Map<String, Object>> fieldList = this.queryModelRecordSingleFields(queryRequest);

			if (fieldList.size() == 0) {
				map.put("result", Constant.NOT_ATTRIBUTE_MODEL);
				return map;
			}

			String[] fieldContent = dbTableService.composizeFieldContent(fieldList,queryRequest.getHasProcess());
			backStr = this.dbTableService.createTable(tableName, fieldContent[0], fieldContent[1]);
			if (!"".equals(backStr)) {
				map.put("result", backStr);
				return map;
			}
			// 重新发布 需要删除已经生成的页面文件
			/*String webPath = this.getClass().getClassLoader().getResource("/").getPath();
			webPath = webPath.substring(1, webPath.length() - 16);
			webPath += pagePath;
			String pageName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName);
			String filePathName = webPath + "/" + pageName + ".jsp";
			File file = new File(filePathName);
			if (file.exists()) {
				file.delete();
			}
			*/

			// 判断是否存在多值字段
		/*	List<Map<String, Object>> multsFieldList = this.queryModelRecordMultsFields(queryRequest);
			String attrCodes = "";
			if (multsFieldList.size() > 0) {
				Map<String, Object> mapAttr = new HashMap<String, Object>();
				// 判断是否有多个明细表的属性
				for (int u = 0; u < multsFieldList.size(); u++) {
					mapAttr = multsFieldList.get(u);
					if (attrCodes.indexOf(mapAttr.get("attrCode").toString()) < 0) {
						if (!"".equals(attrCodes)) {
							attrCodes += ",";
						}
						//fields=CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE,mapAttr.get("attrCode").toString());//转成下划线
						attrCodes += CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE,mapAttr.get("attrCode").toString());//转成下划线
					}
				}
				String[] attrCode = attrCodes.split(",");
				List<Map<String, Object>> attrCodeList = new ArrayList<Map<String, Object>>();
				for (int j = 0; j < attrCode.length; j++) { // 如果有多个明细表
					attrCodeList = new ArrayList<Map<String, Object>>();
					for (int u = 0; u < multsFieldList.size(); u++) {
						mapAttr = multsFieldList.get(u);
						if (attrCode[j].equals(mapAttr.get("attrCode").toString())) {
							attrCodeList.add(mapAttr);
						}
					}
					fieldContent = dbTableService.composizeFieldContent(attrCodeList, "2"); //组装明细表
					backStr = this.dbTableService.createTable(tableName + "_" + attrCode[j], fieldContent[0],
							fieldContent[1]);
					if (!"".equals(backStr)) {
						map.put("result", backStr);
						return map;
					}
				}
			} */
			//同步上一个版本的数据到当前版本
			//if ("".equals(backStr)){
			
			//	backStr=synchrionData(queryRequest.getModelId(),tableName,multsFieldList,attrCodes);
				
			//}
		} catch (Exception ex) {
			backStr = ex.getMessage();
			ex.printStackTrace();
		}
		map.put("result", backStr);
		return map;
	}
	// para :tableName
	//@Override
	public List<Map<String, Object>> queryModelRecordSingleFields(DbTablesQueryRequest queryRequest) {
		Map<String, Object> mapData = new HashMap<String, Object>();
		QueryModel queryModel = this.sqlExecutorDao.getQueryModel(getQueryDescriptor("dbTables"), queryRequest);
		queryModel.setPageSize(101);// 默认100
		queryModel.setPageIndex(1);
		// 查询单值字段
		StringBuffer sb = new StringBuffer("");
		/*sb.append(
				"select a.attr_name,a.attr_code,a.sequence,c.id,c.field_name,c.field_code,c.field_length,c.field_decimal,c.field_type,c.code_rule_id,")
				.append("a.attr_type,a.data_format,a.field_tag,a.display_listing,a.must_input,a.multi_value,a.search_field," +
						//"a.unique_field," +
						"")
				.append(" case when b.dict_code is null then c.dict_code else b.dict_code end  dict_code")
				.append(" from mdm_model_attribute a,mdm_model_attri_meta b,")
				.append("(select x.id,x.field_name,x.field_code,x.field_length,x.field_decimal,x.field_data_type as field_type,x.code_rule_id,y.dict_code,y.dict_name from mdm_meta_data x left join MDM_META_DATA_DICT y ")
				.append(" on y.meta_data_id=x.id ) c")
				.append(" where  b.attribute_id=a.id and c.id=b.meta_id  and a.multi_value=0 and a.model_id='")
				.append(queryRequest.getId()).append("'").append(" order by a.sequence ");
		*/
		sb.append(" select  s.id,s.field_name, s.field_code, s.field_data_type, s.field_length,s.field_decimal")
          .append(",s.code_rule_id,s.is_null,s.field_engname,s.default_value,s.is_primary_key,m.nums ")
          .append(" from saf_tables t ,saf_tables_meta m,saf_meta_Data s ")
          .append(" where m.table_id=t.id and  s.id=m.meta_id  and t.id='").append(queryRequest.getId()).append("'")
          .append(" order by m.nums asc ");
		queryModel.setSortFieldName("nums");
		queryModel.setSql(sb.toString());
		if ("all".equals(queryModel.getExportType())) {// 导出Excel
			queryModel.setExportType(null);
		}
		mapData = this.sqlExecutorDao.executeSlicedQuery(queryModel);
		@SuppressWarnings("unchecked")
		List<Map<String, Object>> list = (List<Map<String, Object>>) mapData.get("Rows");
		return list;
	}
}
