package com.tofly.gpsboot.controller.es;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.api.UserClent;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.es.CarGpsUpload;
import com.tofly.es.GpsUpload;
import com.tofly.es.dto.EsCarGpsUploadQueryDto;
import com.tofly.es.dto.EsQueryDto;
import com.tofly.es.dto.StatisticalInfoDto;
import com.tofly.es.vo.InspectionTrackVo;
import com.tofly.es.vo.StatisticalInfoVo;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.service.calculate.ICalculateGpsService;
import com.tofly.gpsboot.service.comm.IDisposeDateService;
import com.tofly.gpsboot.service.es.ICarGpsUploadService;
import com.tofly.gpsboot.service.es.IGpsUploadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;


/**
 * ES存储GPS信息
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@RestController
@RequestMapping("/gps")
@Api(tags = "ES存储GPS信息")
@Slf4j
public class GpsUploadController {

    @Autowired
    private IGpsUploadService iGpsUploadService;

    @Autowired
    private IDisposeDateService disposeDateService;

    @Autowired
    private ICalculateGpsService iCalculateGpsService;

    @Autowired
    private UserClent userClent;

    @Autowired
    private ICarGpsUploadService iCarGpsUploadService;

    @ApiOperation(value = "新增GPS信息")
    @PostMapping
    public ResultRespone<Boolean> save(@RequestBody GpsUpload gpsUpload) {
        log.info("gps上传信息" + JSON.toJSONString(gpsUpload));
        return ResultRespone.success(iGpsUploadService.saveGpsInfo(gpsUpload));
    }

    @ApiOperation(value = "批量新增GPS信息")
    @PostMapping("/saveBatch")
    public ResultRespone<Boolean> saveBatch(@RequestBody List<GpsUpload> gpsUploadList) {
        return ResultRespone.success(iGpsUploadService.saveBatchGpsInfo(gpsUploadList));
    }

    @ApiOperation(value = "修改GPS信息")
    @PutMapping
    public ResultRespone<Boolean> update(@RequestBody GpsUpload gpsUpload) {
        return ResultRespone.success(iGpsUploadService.updateGpsInfo(gpsUpload));
    }

    @ApiOperation(value = "根据ID获取GPS信息")
    @GetMapping("/findone")
    public ResultRespone<GpsUpload> get(String id) {
        return ResultRespone.success(iGpsUploadService.getByIdGpsInfo(id));
    }

    /**
     * 通过id删除GPS信息表
     *
     * @param id id
     * @return ResultRespone
     */
    @ApiOperation(value = "通过id删除GPS信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String")
    })
    @DeleteMapping("/{id}")
    public ResultRespone<Boolean> removeById(@PathVariable String id) {
        return ResultRespone.success(iGpsUploadService.removeByIdGpsInfo(id));
    }

    @ApiOperation(value = "分页获取GPS信息")
    @GetMapping("/page")
    public ResultRespone<Page<GpsUpload>> get(Page page, @ModelAttribute EsQueryDto dto) {
        return ResultRespone.success(iGpsUploadService.getPageGpsInfo(page, dto));
    }

    @ApiOperation(value = "获取所有index的GPS信息")
    @GetMapping("/getAllPage")
    public ResultRespone<Page<GpsUpload>> getAllPage(Page page, @ModelAttribute EsQueryDto dto) {
        try {
            return ResultRespone.success(iGpsUploadService.getAllPage(page, dto));
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            return ResultRespone.failed(e.getMessage());
        }


    }

    @ApiOperation(value = "获取所有index的GPS信息（非分页）")
    @GetMapping("/getAll")
    public ResultRespone<List<GpsUpload>> getAll(@ModelAttribute EsQueryDto dto) {
        try {
            List<GpsUpload> all = iGpsUploadService.getAll(dto);
            return ResultRespone.success(all);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultRespone.success();
    }

    @ApiOperation(value = "获取所有GPS信息分段信息")
    @GetMapping("/getSection")
    public ResultRespone<List<String>> getSection(@ModelAttribute EsQueryDto dto) {
        return ResultRespone.success(iGpsUploadService.getSectionGps(dto));
    }

    @ApiOperation(value = "多个用户获取GPS信息分段信息,分用户展示")
    @GetMapping("/getSectionMulti")
    public ResultRespone<List<Map<String, Object>>> getSectionMulti(@ModelAttribute EsQueryDto dto) {
        Assert.isTrue(StringUtils.isNotBlank(dto.getUserIds()), "不存在用户信息");

        String[] userIDlIST = dto.getUserIds().split(Constant.CSV);
        List<Map<String, Object>> list = new ArrayList<>();
        for (String userId : userIDlIST) {
            Map<String, Object> userSectionMap = new HashMap<>();
            dto.setUserId(Long.valueOf(userId));
            dto.setUserIds(null);
            List<String> sectionGps = iGpsUploadService.getSectionGps(dto);
            if (CollectionUtils.isNotEmpty(sectionGps)) {
                String realName = userClent.getById(Long.valueOf(userId)).getResult().getRealName();
                userSectionMap.put("realName", realName);
                userSectionMap.put("userId", userId);
                userSectionMap.put("sectionData", sectionGps);
                list.add(userSectionMap);
            }
        }

        return ResultRespone.success(list);
    }

    @ApiOperation(value = "获取统计信息")
    @PostMapping("/statisticalInfo")
    public ResultRespone<List<StatisticalInfoVo>> getStatisticalInfo(@RequestBody StatisticalInfoDto dto) {
        List<StatisticalInfoVo> statisticalInfo = iCalculateGpsService.getStatisticalInfo(dto);
        return ResultRespone.success(statisticalInfo);
    }

    @ApiOperation(value = "巡检轨迹查询")
    @PostMapping("/inspectionTrackQuery")
    public ResultRespone<InspectionTrackVo> inspectionTrackQuery(Page page, EsQueryDto dto) {
        InspectionTrackVo vo = new InspectionTrackVo();
        // 判断参数是否传入 部门ID 或 用户id
        Long userId = dto.getUserId();
        Long deptId = dto.getDeptId();
        String userIds = disposeDateService.getDeptUsers(userId, deptId);
        dto.setUserIds(userIds);
        // 总里程 km
        BigDecimal totalMileage;
        // 总耗时 h
        BigDecimal totalTimeConsuming;
        // 总平均速度 km/h
        BigDecimal overallAverageSpeed = BigDecimal.ZERO;
        Page pageGpsInfo;
        // 判断人巡还是车巡
        if ("0".equals(dto.getTrackType())) {
            // 统计
            List<GpsUpload> all = iGpsUploadService.getAll(dto);

            totalMileage = all.stream().map(GpsUpload::getDistance).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP);

            totalTimeConsuming = all.stream()
                    .filter(g -> 0 != BigDecimal.ZERO.compareTo(g.getDistance()))
                    .map(GpsUpload::getGpsTimespan).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(3600), 4, RoundingMode.HALF_UP);

            if (0 != BigDecimal.ZERO.compareTo(totalTimeConsuming)) {
                overallAverageSpeed = totalMileage.divide(totalTimeConsuming, 2, RoundingMode.HALF_UP);
            }
            page.setOrders(new ArrayList<>());
            pageGpsInfo =  iGpsUploadService.getPageGpsInfo(page, dto);

        }else {
            dto.setUserIds("");
            List<CarGpsUpload> all = iCarGpsUploadService.getAll(dto);
            totalMileage = all.stream().map(CarGpsUpload::getDistance).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP);
//            totalTimeConsuming = all.stream()
//                    .filter(g -> 0 != BigDecimal.ZERO.compareTo(g.getDistance()))
//                    .map(CarGpsUpload::getGpsTimespan)
//                    .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(3600), 4, RoundingMode.HALF_UP);
            // 计算总耗时和总速度
            long startTime = dto.getStartDate().getTime();
            long endTime = dto.getEndDate().getTime();
            totalTimeConsuming = BigDecimal.valueOf(endTime).subtract(BigDecimal.valueOf(startTime)).divide(BigDecimal.valueOf(3600000), 4, RoundingMode.HALF_UP);
            if (0 != BigDecimal.ZERO.compareTo(totalTimeConsuming)) {
                overallAverageSpeed = totalMileage.divide(totalTimeConsuming, 2, RoundingMode.HALF_UP);
            }
            page.setOrders(new ArrayList<>());
            pageGpsInfo =  iCarGpsUploadService.getPageGpsCarInfo(page, dto);
        }

        vo.setTotalMileage(totalMileage);
        vo.setTotalTimeConsuming(totalTimeConsuming);
        vo.setOverallAverageSpeed(overallAverageSpeed);
        vo.setPageGpsInfo(pageGpsInfo);
        return ResultRespone.success(vo);
    }

    @ApiOperation(value = "巡检轨迹查询（非分页）")
    @PostMapping("/inspectionTrackQueryNoPage")
    public ResultRespone<InspectionTrackVo> inspectionTrackQuery(EsQueryDto dto) {
        InspectionTrackVo vo = new InspectionTrackVo();
        // 判断参数是否传入 部门ID 或 用户id
        Long userId = dto.getUserId();
        Long deptId = dto.getDeptId();
        String userIds = disposeDateService.getDeptUsers(userId, deptId);
        dto.setUserIds(userIds);
        // 总里程 km
        BigDecimal totalMileage;
        // 总耗时 h
        BigDecimal totalTimeConsuming;
        // 总平均速度 km/h
        BigDecimal overallAverageSpeed = BigDecimal.ZERO;
        List gpsInfoList;
        // 判断人巡还是车巡
        if ("0".equals(dto.getTrackType())) {
            // 统计
            List<GpsUpload> all = iGpsUploadService.getAll(dto);

            totalMileage = all.stream().map(GpsUpload::getDistance).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP);

            totalTimeConsuming = all.stream()
                    .filter(g -> 0 != BigDecimal.ZERO.compareTo(g.getDistance()))
                    .map(GpsUpload::getGpsTimespan).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(3600), 4, BigDecimal.ROUND_HALF_UP);

            if (0 != BigDecimal.ZERO.compareTo(totalTimeConsuming)) {
                overallAverageSpeed = totalMileage.divide(totalTimeConsuming, 2, BigDecimal.ROUND_HALF_UP);
            }
            gpsInfoList = all;
        }else {
            EsCarGpsUploadQueryDto carDto = new EsCarGpsUploadQueryDto();
            carDto.setStartTime(dto.getStartDate());
            carDto.setEndTime(dto.getEndDate());
            carDto.setCarId(dto.getCarId());
            List<CarGpsUpload> all = iCarGpsUploadService.getGpsCarList(carDto);
            totalMileage = all.stream().map(CarGpsUpload::getDistance).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP);

//            totalTimeConsuming = all.stream()
//                    .filter(g -> 0 != BigDecimal.ZERO.compareTo(g.getDistance()))
//                    .map(CarGpsUpload::getGpsTimespan)
//                    .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(3600), 4, BigDecimal.ROUND_HALF_UP);
//            if (0 != BigDecimal.ZERO.compareTo(totalTimeConsuming)) {
//                overallAverageSpeed = totalMileage.divide(totalTimeConsuming, 2, BigDecimal.ROUND_HALF_UP);
//            }
            // 计算总耗时和总速度
            long startTime = dto.getStartDate().getTime();
            long endTime = dto.getEndDate().getTime();
            totalTimeConsuming = BigDecimal.valueOf(endTime).subtract(BigDecimal.valueOf(startTime)).divide(BigDecimal.valueOf(3600000), 4, RoundingMode.HALF_UP);
            if (0 != BigDecimal.ZERO.compareTo(totalTimeConsuming)) {
                overallAverageSpeed = totalMileage.divide(totalTimeConsuming, 2, RoundingMode.HALF_UP);
            }
            gpsInfoList =  all;
        }
        vo.setTotalMileage(totalMileage);
        vo.setTotalTimeConsuming(totalTimeConsuming);
        vo.setOverallAverageSpeed(overallAverageSpeed);
        vo.setGpsInfoList(gpsInfoList);
        return ResultRespone.success(vo);
    }
}
