package com.tofly.gpsboot.service.es.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.util.Date8Util;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.es.GpsUpload;
import com.tofly.gpsboot.common.Constant;
import com.tofly.es.dto.EsQueryDto;

import com.tofly.es.dto.GpsSectionSearchDto;
import com.tofly.es.dto.UserGpsSearchDto;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.es.GpsUploadRepository;
import com.tofly.gpsboot.service.es.IGpsUploadService;
import com.tofly.gpsboot.service.sign.PdasignhisService;
import com.tofly.gpsboot.util.EsQueryUtil;
import com.tofly.gpsboot.util.EsSaveInfoUtil;
import com.tofly.pojo.plan.Pdasignhis;
import org.elasticsearch.index.query.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;

import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author BZ-DJJ
 */
@Service
public class GpsUploadServiceImpl implements IGpsUploadService {
    @Autowired
    private GpsUploadRepository gpsUploadRepository;
    @Autowired
    private EsSaveInfoUtil esSaveInfoUtil;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private PdasignhisService pdasignhisService;

    @Override
    public Boolean saveGpsInfo(GpsUpload gpsUpload) {
        gpsUpload.setUserId(SecurityUtils.getUserId());
        gpsUpload.setUserName(SecurityUtils.getUser().getRealName());
        if (gpsUpload.getUploadTime() == null) {
            gpsUpload.setUploadTime(Date8Util.getCurrentDate());
        }
        gpsUploadRepository.save(gpsUpload);
       // esSaveInfoUtil.checkInsertEsInfo(gpsUploadRepository.getIndex());
        return true;
    }

    @Override
    public Boolean saveBatchGpsInfo(List<GpsUpload> gpsUploadList) {
        Long userId = SecurityUtils.getUserId();
        String userName = SecurityUtils.getUser().getRealName();
        Date now = Date8Util.getCurrentDate();
        gpsUploadList.forEach(info -> {
            info.setUserId(userId);
            info.setUserName(userName);
            if (null == info.getUploadTime()) {
                info.setUploadTime(now);
            }
        });
        gpsUploadRepository.saveAll(gpsUploadList);
        esSaveInfoUtil.checkInsertEsInfo(gpsUploadRepository.getIndex());
        return true;
    }

    @Override
    public Boolean updateGpsInfo(GpsUpload gpsUpload) {
        return gpsUploadRepository.update(gpsUpload);
    }

    @Override
    public GpsUpload getByIdGpsInfo(String id) {
        return gpsUploadRepository.findById(id).get();
    }

    @Override
    public Boolean removeByIdGpsInfo(String id) {
        gpsUploadRepository.deleteById(id);
        return true;
    }

    @Override
    public Page<GpsUpload> getPageGpsInfo(Page page, EsQueryDto dto) {
        GpsUpload gpsUpload = new GpsUpload();
        QueryBuilder[] queryBuilders = EsQueryUtil.putQUery(page, dto);
        return gpsUploadRepository.getPage(gpsUpload, page, queryBuilders);
    }

    @Override
    public Page<GpsUpload> getAllPage(Page page, EsQueryDto dto) {
        GpsUpload gpsUpload = new GpsUpload();
        QueryBuilder[] queryBuilders = EsQueryUtil.putQUery(page, dto);
        return gpsUploadRepository.getAllPage(gpsUpload, page,
                esSaveInfoUtil.DyMonth(gpsUploadRepository.getIndex()), elasticsearchTemplate, queryBuilders);
    }

    @Override
    public List<GpsUpload> getAll(EsQueryDto dto) {
        GpsUpload gpsUpload = new GpsUpload();
        Page page = new Page();
        page.setSize(10000);
        QueryBuilder[] queryBuilders = EsQueryUtil.putQUery(page, dto);
        return gpsUploadRepository.getAll(gpsUpload, page,
                esSaveInfoUtil.DyMonth(gpsUploadRepository.getIndex()), elasticsearchTemplate, queryBuilders);
    }

    @Override
    public List<String> getSectionGps(EsQueryDto dto) {
        GpsUpload gpsUpload = new GpsUpload();
        if (dto.getUserId() == null) {
            throw new BusinessException(Constant.IS_USER_ID_NULL_CODE, Constant.IS_USER_ID_NULL);
        }
        if (null == dto.getStartDate() || null == dto.getEndDate()) {
            throw new BusinessException(Constant.IS_START_TIME_ADD_END_TIME_CODE, Constant.IS_START_TIME_ADD_END_TIME);
        }

        Page page = new Page();
        page.setSize(new Long(10000));
        dto.setIsAsc(true);
        QueryBuilder[] queryBuilders = EsQueryUtil.putQUery(page, dto);
        List<GpsUpload> list = gpsUploadRepository.getAll(gpsUpload, page,
                esSaveInfoUtil.DyMonth(gpsUploadRepository.getIndex()), elasticsearchTemplate, queryBuilders);
        //截取分段信息
        int pointNum = 1000;
        int total = list.size();
        float section = (float) total / pointNum;
        List<String> result = new ArrayList<>();
        for (int i = 0; i < section; i++) {
            int start = i * pointNum;
            int end = start + pointNum - 1;
            if (section - i < 1) {
                end = start + total % pointNum - 1;
            }
            result.add("第" + (i + 1) + "段:" + Date8Util.format(list.get(start).getUploadTime(), "yyyy-MM-dd HH:mm:ss") + " - "
                    + Date8Util.format(list.get(end).getUploadTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        return result;
    }

    @Override
    public Page getUserSectionGps(Page page, UserGpsSearchDto dto) {
        GpsUpload gpsUpload = new GpsUpload();
        if (Long.valueOf(10).equals(page.getSize())) {
            page.setSize(1000L);
        }
        QueryBuilder[] queryBuilders = EsQueryUtil.getGpsLst(page, dto);
        return gpsUploadRepository.getAllPage(gpsUpload, page,
                esSaveInfoUtil.DyMonth(gpsUploadRepository.getIndex()), elasticsearchTemplate, queryBuilders);
    }

    @Override
    public List<Map<String, Object>> getUserSection(GpsSectionSearchDto dto) {

        List<Pdasignhis> signList = pdasignhisService.list(Wrappers.<Pdasignhis>lambdaQuery()
                .ge(Pdasignhis::getSignTime, dto.getStartDate())
                .le(Pdasignhis::getSignTime, dto.getEndDate())
                .eq(Pdasignhis::getSignUser, dto.getUserId())
                .orderByAsc(Pdasignhis::getSignTime));

        int k = 1;
        Date start = null;
        List<Map<String, Object>> list = new ArrayList<>();
//        List<String> section = new ArrayList<>();
        for (int i = 0; i < signList.size(); i++) {
            Map<String, Object> result = new HashMap<>(12);
            if ("1".equals(signList.get(i).getSignType())) {
                start = signList.get(i).getSignTime();
                if (signList.size() == (i + 1)) {
//                    section.add("第"+k+"段 "+Date8Util.format(start,"yyyy-MM-dd HH:mm:ss")+" - "+ Date8Util.format(Date8Util.getCurrentDate(),"yyyy-MM-dd HH:mm:ss"));
                    result.put("section", k);
                    result.put("startTime", start);
                    result.put("endTime", dto.getEndDate().equals(Date8Util.getEndTime()) ? Date8Util.getCurrentDate() : dto.getEndDate());
                    list.add(result);
                }
            }
            if ("2".equals(signList.get(i).getSignType())) {
//                section.add("第"+k+"段 "+Date8Util.format(start,"yyyy-MM-dd HH:mm:ss")+" - "+Date8Util.format(signList.get(i).getSignTime(),"yyyy-MM-dd HH:mm:ss"));
                result.put("section", k);
                result.put("startTime", start);
                result.put("endTime", signList.get(i).getCreateTime());
                list.add(result);
                k++;
            }
        }

        return list;
    }

    @Override
    public List<GpsUpload> getNowUserInfoList(String users, Date startTime, Date endTime) {
        EsQueryDto dto = new EsQueryDto();
        dto.setStartDate(startTime);
        dto.setEndDate(endTime);
        dto.setUserIds(users);
        // 按照时间排序用户分组
        Map<Long, List<GpsUpload>> listMap = this.getAll(dto).stream().sorted(Comparator.comparing(GpsUpload::getUploadTime).reversed()).collect(Collectors.groupingBy(GpsUpload::getUserId, Collectors.toList()));
        List<GpsUpload> result = new ArrayList<>();
        listMap.forEach((k,v) ->{
            result.add(v.get(0));
        });
        return result;
    }
}
