package com.chinaitop.depot.intelligent.grainsituation.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.chinaitop.depot.intelligent.grainsituation.mapper.TTestdataLayerMapper;
import com.chinaitop.depot.intelligent.grainsituation.mapper.TTestdataMapper;
import com.chinaitop.depot.intelligent.grainsituation.mapper.TTestdataPointsMapper;
import com.chinaitop.depot.intelligent.grainsituation.model.*;
import com.chinaitop.depot.intelligent.grainsituation.service.TemperatureRecordService;
import com.chinaitop.depot.intelligent.utils.DateUtils;
import com.chinaitop.depot.intelligent.utils.JsonToObjectUtils;
import com.chinaitop.depot.intelligent.utils.ParameterUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class TemperatureRecordServiceImpl implements TemperatureRecordService {
    @Resource
    private TTestdataMapper tTestdataMapper;

    @Resource
    private TTestdataPointsMapper tTestdataPointsMapper;

    @Resource
    private TTestdataLayerMapper tTestdataLayerMapper;

    //这三个库需要特殊处理
    private final static String []SPECIAL_ORG = {"68", "161", "71"};

    @Override
    public List<TTestdata> getList(String vCfCode, String vDatatime, String startTime, String endTime, String tType, String orgId) {
        TTestdataExample testdataExample = new TTestdataExample();
//        testdataExample.setDistinct(true);
        TTestdataExample.Criteria criteria = testdataExample.createCriteria();
        if (StringUtils.isNotEmpty(vCfCode)) {
            criteria.andStorehouseEqualTo(vCfCode);
        }
        if (StringUtils.isNotEmpty(vDatatime)) {
            criteria.andTTimeBetween(DateUtils.stringToData(vDatatime + DateUtils.startTime), DateUtils.stringToData(vDatatime + DateUtils.endTime));
        }
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            criteria.andTTimeBetween(DateUtils.stringToData(startTime + DateUtils.startTime), DateUtils.stringToData(endTime + DateUtils.endTime));
        }
        if (ParameterUtil.isnull(startTime) && StringUtils.isNotBlank(endTime)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = null;
            try {
                date = dateFormat.parse(endTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            criteria.andTTimeLessThanOrEqualTo(date);
        }
        if (StringUtils.isNotEmpty(tType)) {
            criteria.andIlqYqEqualTo(tType);
        }
        if (StringUtils.isNotEmpty(orgId)) {
            criteria.andOrgIdEqualTo(orgId);
        }
        testdataExample.setOrderByClause("t_time desc");
        return tTestdataMapper.selectByExample(testdataExample);
    }


    @Override
    public List<TTestdataLayer> findByHouseAndTime(String lqId, String vCfCode, String vDatatime, String orgId) {
        TTestdataLayerExample tTestdataLayerExample = new TTestdataLayerExample();
        //tTestdataLayerExample.setDistinct(true);
        TTestdataLayerExample.Criteria criteria = tTestdataLayerExample.createCriteria();
        if (StringUtils.isNotBlank(orgId)) {
            criteria.andOrgIdEqualTo(orgId);
        }
        if (StringUtils.isNotBlank(lqId)) {
            criteria.andLqIdEqualTo(lqId);
        }

        tTestdataLayerExample.setOrderByClause("layerNumber ASC");
        
        List<TTestdataLayer> tTestdata = tTestdataLayerMapper.selectByExample(tTestdataLayerExample);
        return tTestdata;
    }

    @Override
    public ArrayList<Object> findByHouseAndTimes(String lqId, String vCfCode, String vDatatime, String zsfs) {
        TTestdata byId = tTestdataMapper.getById(lqId).get(0);
        String s = byId.gettPoints();

        List<TPoints> tPoints = JSON.parseArray(s, TPoints.class);

        ArrayList<Object> objects = Lists.newArrayList();
        if (tPoints.size() > 0) {
        	Map<Integer, Map<Integer, Map<Integer, List<TPoints>>>> collect1 = null;
        	if ("1".equals(zsfs)) {
        		//collect1 = tPoints.stream().collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ()), Collectors.groupingBy(t -> Integer.parseInt(t.getY()), Collectors.groupingBy(t -> Integer.parseInt(t.getX())))));
                //行数
                Long y_max = tPoints.stream().filter(friend -> friend.getX().equals("1")).filter(friend -> friend.getZ().equals("1")).count();
                //列数
                Long x_max = tPoints.stream().filter(friend -> friend.getZ().equals("1")).filter(friend -> friend.getY().equals("1")).count();
                
                int xl_l = 0;

                //线缆数组
                String[] y_num = null;
                //点位数组
                String[] dw_num = null; 
                //遍历列
                Integer i = 0;
                for (i = 1; i <= x_max; i++) {
                	//遍历线缆行
                	y_num = new String[(int) (y_max+1)];
                	for (int j = 0; j < y_num.length; j++) {
                		if (j==0) {
                			y_num[0] = "电缆号";
                		} else {
                			xl_l = xl_l+1;
                			y_num[j] = xl_l+"";
                		}
                	}
                	objects.add(y_num);
                	System.out.println(Arrays.toString(y_num));
                	//遍历这几根线缆的点位数据
                	String index = i.toString();
                	collect1 = tPoints.stream().filter(friend -> friend.getX().equals(index))
                			                   .collect(Collectors.groupingBy(t -> Integer.parseInt(t.getX()), 
                					                    Collectors.groupingBy(t -> Integer.parseInt(t.getZ()), 
                							            Collectors.groupingBy(t -> Integer.parseInt(t.getY())))));
                	for (Map.Entry<Integer, Map<Integer, Map<Integer, List<TPoints>>>> entryX : collect1.entrySet()) {
                        //每层数据
                        Map<Integer, Map<Integer, List<TPoints>>> layerGroupV = entryX.getValue();
                        for (Map.Entry<Integer, Map<Integer, List<TPoints>>> rows : layerGroupV.entrySet()) {
                            HashMap<Object, Object> objectObjectHashMap = Maps.newLinkedHashMap();

                            //每一行数据
                            Map<Integer, List<TPoints>> value = rows.getValue();
                            int a = 1;
                            List<Map.Entry<Integer, List<TPoints>>> list = new ArrayList<>(value.entrySet());
                            dw_num = new String[(int) (y_max+1)];
                            for (int k = 0; k < list.size()+1; k++) {
                                if (k==0) {
                                	dw_num[0] = "S"+rows.getKey();
                        		} else {
                        			Map.Entry<Integer, List<TPoints>> z = list.get(k-1);
                        			List<TPoints> li = z.getValue();
//                        			System.out.println(li.get(0).getX()+","+li.get(0).getY()+","+li.get(0).getZ()+","+li.get(0).getTemp());
//                        			dw_num[k] = entryX.getKey()+","+z.getKey()+","+rows.getKey();
                        			dw_num[k] = li.get(0).getTemp().toString();
                        		}
                            }
                            System.out.println(Arrays.toString(dw_num));
                            objects.add(dw_num);
                        }
                    }
                
                }
        	} else {
        		collect1 = tPoints.stream().collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ()), Collectors.groupingBy(t -> Integer.parseInt(t.getX()), Collectors.groupingBy(t -> Integer.parseInt(t.getY())))));
        		for (Map.Entry<Integer, Map<Integer, Map<Integer, List<TPoints>>>> entryG : collect1.entrySet()) {
        			//每层数据
        			Map<Integer, Map<Integer, List<TPoints>>> layerGroupV = entryG.getValue();
        			for (Map.Entry<Integer, Map<Integer, List<TPoints>>> rows : layerGroupV.entrySet()) {
        				HashMap<Object, Object> objectObjectHashMap = Maps.newLinkedHashMap();
        				
        				//每一行数据
        				Map<Integer, List<TPoints>> value = rows.getValue();
        				int a = 1;
        				objectObjectHashMap.put(a, entryG.getKey() + "-" + rows.getKey());
        				for (Map.Entry<Integer, List<TPoints>> orws : value.entrySet()) {
        					//列数据
        					List<TPoints> column = orws.getValue();
        					TPoints t = column.get(0);
        					objectObjectHashMap.put(++a, t.getTemp());
        				}
        				objects.add(objectObjectHashMap);
        			}
        		}
        	}
        }
        return objects;
    }
    
    public ArrayList<Object> findByHouseAndTimesTwo(String lqId) {
    	TTestdata byId = tTestdataMapper.getById(lqId).get(0);
    	String s = byId.gettPoints();
        List<TPoints> tPoints = JSON.parseArray(s, TPoints.class);
        ArrayList<Object> objects = Lists.newArrayList();
        /*BigDecimal wholeMax = tPoints.stream().filter(TPoints -> !TPoints.getTemp().toString().equals(new BigDecimal(STR_TEMP).toString()))
				.filter(TPoints -> TPoints.getTemp().abs().compareTo(H_TEMP) == -1)
				.map(TPoints::getTemp)
				.reduce(BD_MINUS_THREE, BigDecimal::max);*/
        //层数
        Long z_max = tPoints.stream().filter(friend -> friend.getX().equals("1")).filter(friend -> friend.getY().equals("1")).count();
        //行数
        Long y_max = tPoints.stream().filter(friend -> friend.getX().equals("1")).filter(friend -> friend.getZ().equals("1")).count();
        //列数
        Long x_max = tPoints.stream().filter(friend -> friend.getZ().equals("1")).filter(friend -> friend.getY().equals("1")).count();
        //线缆数
        Long xl_count = x_max * y_max;
        
        //遍历生成线缆的数据
        List<String[]> xl_list = new ArrayList<>();
        String[] y_num = null;
        for (int i = 0; i < y_max; i++) {
        	y_num = new String[(int) (x_max+1)];
        	for (int j = 0; j < y_num.length; j++) {
        		if (j==0) {
        			y_num[j] = "电缆号";
        		} if (j==1) {
        			y_num[j] = xl_count+"缆";
        		} else {
        			Long xl_num = xl_count-y_max;
        			y_num[j] = xl_num+"揽";
        		}
        	}
        }
        
    	return objects;
    }

    @Override
    public List<TTestdata> getComparison(String vCfCodeLeft, String startTimeLeft, String endTimeLeft, String vCfCodeRight, String startTimeRight, String endTimeRight, String tType, String orgId) {
        TTestdataExample example = new TTestdataExample();
        example.setDistinct(true);
        TTestdataExample.Criteria criteria = example.createCriteria();
        // 左图查询条件
        if (StringUtils.isNotBlank(vCfCodeLeft)) {
            criteria.andStorehouseEqualTo(vCfCodeLeft);
        }
        // 右图查询条件
        if (StringUtils.isNotBlank(vCfCodeRight)) {
            criteria.andStorehouseEqualTo(vCfCodeRight);
        }
        if (StringUtils.isNotBlank(orgId)) {
            criteria.andOrgIdEqualTo(orgId);
        }
        // 时间条件
        if (StringUtils.isNotBlank(startTimeLeft) && StringUtils.isNotBlank(endTimeLeft)) {
            criteria.andTTimeBetween(DateUtils.stringToData(startTimeLeft + DateUtils.startTime), DateUtils.stringToData(endTimeLeft + DateUtils.endTime));
        } else if (StringUtils.isNotBlank(startTimeRight) && StringUtils.isNotBlank(endTimeRight)) {
            criteria.andTTimeBetween(DateUtils.stringToData(startTimeRight + DateUtils.startTime), DateUtils.stringToData(endTimeRight + DateUtils.endTime));
        } else {
            criteria.andTTimeBetween(DateUtils.stringToData(DateUtils.formatDate(DateUtils.getDate()) + DateUtils.startTime), DateUtils.stringToData(DateUtils.formatDate(DateUtils.getDate()) + DateUtils.endTime));
        }
        // 检测类型0测温，1粮油,2测水分
        criteria.andIlqYqEqualTo(tType);
        example.setOrderByClause("t_time desc");
        return tTestdataMapper.selectByExample(example);
    }

    @Transactional
    @Override
    public void insertBatch(List<TTestdata> testData) {
        tTestdataMapper.insertBatch(testData);
    }

    @Override
    public List<TTestdata> getByCodeAndTimes(List<String> cDcsCodes, List<Date> cTimes, List<String> lqTypes) {
        TTestdataExample example = new TTestdataExample();
        TTestdataExample.Criteria criteria = example.createCriteria();
        if ((cDcsCodes != null && cDcsCodes.size() > 0) && (cTimes != null && cTimes.size() > 0) && (lqTypes != null && lqTypes.size() > 0)) {
            criteria.andStorehouseIn(cDcsCodes);
            criteria.andTTimeIn(cTimes);
            criteria.andIlqYqIn(lqTypes);
            List<TTestdata> tTestdata = tTestdataMapper.selectByExample(example);
            return tTestdata;
        }
        return null;
    }

    @Override
    public String getOrgId(String cfCode) {
        return tTestdataMapper.getOrgId(cfCode);
    }

    @Override
    public TTestdata getById(String id) {
        TTestdataExample example = new TTestdataExample();
        TTestdataExample.Criteria criteria = example.createCriteria();
        criteria.andIdEqualTo(id);
        TTestdata tTestdata = tTestdataMapper.selectByExample(example).get(0);
        return tTestdata;
    }

    @Override
    public Map<Integer, Map<Integer, Map<Integer, List<TPoints>>>> findByTempTable(String id, String zsfs) {
    	TTestdata str = tTestdataMapper.findByTempTable(id);
        if (StringUtils.isBlank(str.gettPoints()))
            return null;
        
        List<TPoints> tPoints = null;
//        boolean result = ArrayUtils.contains(SPECIAL_ORG, str.getOrgId());
//    	if (result) {
//    		//把层数(Z)颠倒过来
//    		tPoints = restZ(str.gettPoints(), str.getOrgId(), result);
//    	} else {
//    		// json字符串数组转list对象
//    		tPoints = JSONArray.parseArray(str.gettPoints(), TPoints.class);
//    	}
    	tPoints = JSONArray.parseArray(str.gettPoints(), TPoints.class);
    	
    	Map<Integer, Map<Integer, Map<Integer, List<TPoints>>>> collect = null;
    	if ("1".equals(zsfs)) {
    		collect = tPoints.stream()
        			.collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ())
        					, Collectors.groupingBy(t -> Integer.parseInt(t.getY())
        							, Collectors.groupingBy(t -> Integer.parseInt(t.getX())))));
    	} else {
    		collect = tPoints.stream()
        			.collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ())
        					, Collectors.groupingBy(t -> Integer.parseInt(t.getX())
        							, Collectors.groupingBy(t -> Integer.parseInt(t.getY())))));
    	}
//    	Map<Integer, Map<Integer, Map<Integer, List<TPoints>>>> collect = tPoints.stream()
//    			.collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ())
//    					, Collectors.groupingBy(t -> Integer.parseInt(t.getX())
//    							, Collectors.groupingBy(t -> Integer.parseInt(t.getY())))));
		return collect;
    }

    @Override
    public Map<Integer,List<TPoints>> shallowCircularPointTempTable(String id) {
    	TTestdata str = tTestdataMapper.findByTempTable(id);
        if (StringUtils.isBlank(str.gettPoints()))
            return null;
        List<TPoints> tPoints = JSONArray.parseArray(str.gettPoints(), TPoints.class);
        // 按z层分组
        Map<Integer, List<TPoints>> collect = tPoints.stream()
                .collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ())));
        return collect;
    }

    @Override
    public void test(String lqid, Integer pageSize) throws IOException {

    	TTestdata byId = tTestdataMapper.getById(lqid).get(0);
    	String s = byId.gettPoints();
        List<TPoints> tPoints = JSON.parseArray(s, TPoints.class);
        ArrayList<Object> objects = Lists.newArrayList();
        //层数
        Long z_count = tPoints.stream().filter(friend -> friend.getX().equals("1")).filter(friend -> friend.getY().equals("1")).count();
        //行数
        Long y_count = tPoints.stream().filter(friend -> friend.getX().equals("1")).filter(friend -> friend.getZ().equals("1")).count();
        //列数
        Long x_count = tPoints.stream().filter(friend -> friend.getY().equals("1")).filter(friend -> friend.getZ().equals("1")).count();
        //线缆总数
        Long xl_count = x_count * y_count;
        //整个表格的行数(层数X行数+行数)
        int sum_y = z_count.intValue() * y_count.intValue() + y_count.intValue();
        System.out.println(xl_count);
        
        List<Object> list = Lists.newArrayList();
        //每一行的数据量数组
        String [] str;
        //有y行标题先遍历标题行
        for (int i = 1; i <= sum_y; i++) {
        	str = new String[Integer.parseInt(x_count.toString())+1];
        	if (i == 1) {
        		//遍历行数据
        		for (int k = 0; k < x_count; k++) {
        			str[i] = "电缆号";
        		}
        		
        		
        	}
        }

        /*Map<Integer, Map<Integer, Map<Integer, List<TPoints>>>> collect1 = tPoints.stream().collect(Collectors.groupingBy(t -> Integer.parseInt(t.getZ()), Collectors.groupingBy(t -> Integer.parseInt(t.getY()), Collectors.groupingBy(t -> Integer.parseInt(t.getX())))));
        
        for (Map.Entry<Integer, Map<Integer, Map<Integer, List<TPoints>>>> entryG : collect1.entrySet()) {
            //每层数据
            Map<Integer, Map<Integer, List<TPoints>>> layerGroupV = entryG.getValue();
            for (Map.Entry<Integer, Map<Integer, List<TPoints>>> rows : layerGroupV.entrySet()) {
                HashMap<Object, Object> objectObjectHashMap = Maps.newLinkedHashMap();

                //每一行数据
                Map<Integer, List<TPoints>> value = rows.getValue();
                int a = 1;
                objectObjectHashMap.put(a, entryG.getKey() + "-" + rows.getKey());
                for (Map.Entry<Integer, List<TPoints>> orws : value.entrySet()) {
                    //列数据
                    List<TPoints> column = orws.getValue();
                    TPoints t = column.get(0);
                    objectObjectHashMap.put(++a, t.getTemp());
                    System.out.print(t.getX()+","+t.getY()+","+t.getZ()+" | ");
                }
                objects.add(objectObjectHashMap);
            }
        }*/
    }

    /**
     * Z的坐标是否需要颠倒
     * @param t_Points 原点位值
     * @param orgId 组织机构ID
     * @param flag 是否颠倒
     * @return
     */
    private ArrayList<TPoints> restZ(String t_Points, String orgId, boolean flag) {
    	
    	// 层倒叙 最小变最大, 最大变最小
        List<TPoints> tP = JSON.parseArray(t_Points, TPoints.class);
        // 数据总长度
        int size = tP.size();//测温点总数
        // 层分组 总层数
        Map<Integer, List<TPoints>> collect = tP.stream().collect(Collectors.groupingBy(point -> Integer.parseInt(point.getZ())));
        Integer sizeZ = collect.size();//总层数
        int i = 1; // 计数初始变量
        int y = size / sizeZ; // 每层测温点的数量
        ArrayList<TPoints> tPoints = Lists.newArrayList();
        for (Integer integer : collect.keySet()) {
            List<TPoints> tPoints1 = collect.get(integer);//获取当前层的所有点位
            for (TPoints tPoint : tPoints1) {//遍历这层的这些点位
            	if (flag) {
            		tPoint.setZ(sizeZ.toString()); // 倒叙放入层值
            		if (i == y) { // 每层有多少个点
            			sizeZ--;
            		}
            		i++;
            		if (i > y) { // 到达每层点将初始计数初始化,执行替换为下一个sizeZ--
            			i = 1;
            		}
            	}
                tPoints.add(tPoint); // 重新添加到list
            }
        }

    	return tPoints;
    }
}
