package com.gci.boot.modules.gis.controller;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.annotation.permission.DataPermission;
import com.gci.boot.common.dict.excel.MyExcelDictHandleImpl;
import com.gci.boot.common.util.DateUtils;
import com.gci.boot.common.util.LimitCheckUtil;
import com.gci.boot.common.util.RedisKey;
import com.gci.boot.common.validated.SaveValidated;
import com.gci.boot.common.vo.Result;
import com.gci.boot.enums.VehicleGpsType;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.gis.entity.GisRoadMileLog;
import com.gci.boot.modules.gis.entity.GisGpsAnalysis;
import com.gci.boot.modules.gis.query.EverydayInfoQuery;
import com.gci.boot.modules.gis.query.EverydayQuery;
import com.gci.boot.modules.gis.service.GisRoadMileLogService;
import com.gci.boot.modules.gis.service.IGisGpsAnalysisService;
import com.gci.boot.modules.gis.vo.EverydayGisVo;
import com.gci.boot.modules.gis.vo.EverydayMileCountVo;
import com.gci.boot.modules.gis.vo.StatisGisVo;
import com.gci.boot.modules.system.shiro.vo.DefContants;
import com.gci.boot.modules.system.util.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 * 车辆gps轨迹信息表 前端控制器
 * </p>
 *
 * @author 2464
 * @since 2023-09-01
 */
@RestController
@RequestMapping("/gis/gpsAnalysis")
public class GisGpsAnalysisController {
    @Autowired
    private IGisGpsAnalysisService iGisGpsAnalysisService;

    @Autowired
    private GisRoadMileLogService gisRoadMileLogService;

    @Autowired
    private ITbVehicleService tbVehicleService;

    @Autowired
    private IGisGpsAnalysisService gisGpsAnalysisService;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @GetMapping(value = "/dmz/gen")
    public Result<?> gpsAnalySisGen(@RequestParam(value = "plateNumber",required = false) String plateNumber,
                                    @RequestParam(value = "vehicleBrand",required = false) String vehicleBrand,
                                    @RequestParam(value = "projectId",required = false) String projectId,
                                    @RequestParam(value = "isEic",required = false,defaultValue = "1") boolean isEic,
                                    @RequestParam("handleDate") String handleDate,
                           HttpServletRequest req) {
        LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(plateNumber),TbVehicle::getPlateNumber,plateNumber);
        queryWrapper.eq(ObjectUtil.isNotEmpty(vehicleBrand),TbVehicle::getVehicleBrand,vehicleBrand);
        queryWrapper.eq(ObjectUtil.isNotEmpty(projectId),TbVehicle::getProjectId,projectId);
        List<TbVehicle> list  = tbVehicleService.list(queryWrapper);
/*        LocalDate date = LocalDate.parse(handleDate);
        LocalDateTime start = LocalDateTime.of(date, LocalTime.of(0, 0, 0));
        LocalDateTime end = LocalDateTime.of(date, LocalTime.of(23, 59, 59));*/

        DateTime parse = DateUtil.parse(handleDate);
        Date startTime = DateUtil.beginOfDay(parse);
        Date endTime = DateUtil.endOfDay(parse);
        list.parallelStream().forEach(vehicle -> {
            try{
                LambdaQueryWrapper<GisGpsAnalysis> removeWrapper = new LambdaQueryWrapper<>();
                removeWrapper.eq(GisGpsAnalysis::getNumberPlate,vehicle.getPlateNumber());
                removeWrapper.eq(GisGpsAnalysis::getOwnDate,parse);
                gisGpsAnalysisService.remove(removeWrapper);
                gisGpsAnalysisService.gpsDataAnalysisByVehicle(vehicle, startTime, endTime,isEic);
            }catch (Exception e){
                e.printStackTrace();
            }
        });
        return Result.ok();
    }

    @GetMapping(value = "/dmz/gen808")
    public Result<?> gpsAnalySisGen808(@RequestParam(value = "plateNumber",required = false) String plateNumber,
                                       @RequestParam(value = "projectId",required = false) String projectId,
                                       @RequestParam(value = "vehicleBrand",required = false) String vehicleBrand,
                                       @RequestParam("handleDate") String handleDate,
                                    HttpServletRequest req) {
        LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(projectId),TbVehicle::getProjectId,projectId);
        queryWrapper.eq(ObjectUtil.isNotEmpty(plateNumber),TbVehicle::getPlateNumber,plateNumber);
        queryWrapper.eq(ObjectUtil.isNotEmpty(vehicleBrand),TbVehicle::getVehicleBrand,vehicleBrand);
        List<TbVehicle> list  = tbVehicleService.list(queryWrapper);
/*        LocalDate date = LocalDate.parse(handleDate);
        LocalDateTime start = LocalDateTime.of(date, LocalTime.of(0, 0, 0));
        LocalDateTime end = LocalDateTime.of(date, LocalTime.of(23, 59, 59));*/

        DateTime parse = DateUtil.parse(handleDate);
        Date startTime = DateUtil.beginOfDay(parse);
        Date endTime = DateUtil.endOfDay(parse);
        list.parallelStream().forEach(vehicle -> {
            try{
                LambdaQueryWrapper<GisGpsAnalysis> removeWrapper = new LambdaQueryWrapper<>();
                removeWrapper.eq(GisGpsAnalysis::getNumberPlate,vehicle.getPlateNumber());
                removeWrapper.eq(GisGpsAnalysis::getOwnDate,parse);
                gisGpsAnalysisService.remove(removeWrapper);
                gisGpsAnalysisService.gpsDataAnalysisByVehicleBy808(vehicle, startTime, endTime);
            }catch (Exception e){
                e.printStackTrace();
            }
        });
        return Result.ok();
    }


    @GetMapping(value = "/dmz/test")
    public Result<?> gpsAnalySisTest(@RequestParam(value = "plateNumber",required = true) String plateNumber,
                                     @RequestParam("handleDate") String handleDate,
                                    HttpServletRequest req) {
        LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbVehicle::getPlateNumber,plateNumber);
        TbVehicle vehicle = tbVehicleService.getOne(queryWrapper);
        DateTime parse = DateUtil.parse(handleDate);
        Date startTime = DateUtil.beginOfDay(parse);
        Date endTime = DateUtil.endOfDay(parse);
        List<GisGpsAnalysis> gisGpsAnalyses =  gisGpsAnalysisService.gpsTime(vehicle, startTime, endTime);
        BigDecimal ss = gisGpsAnalyses.stream().map(a->a.getMile()).reduce(BigDecimal.ZERO,BigDecimal::add);
        System.out.println("大小:"+gisGpsAnalyses.size()+" 总里程："+ss);
        return Result.ok(gisGpsAnalyses);
    }

    @GetMapping(value = "/dmz/gisSource")
    public Result<?> notIllegalLog(@RequestParam(value = "projectId",required = true) String projectId,
                                   @RequestParam(value = "type",required = true) boolean type,
                                   HttpServletRequest req) {
        //使用32960
        if(type){
            redisTemplate.opsForValue().set(RedisKey.PROJECT_GIS_SOURCE + projectId, "true");
        }else{
            redisTemplate.delete(RedisKey.PROJECT_GIS_SOURCE + projectId);
        }
        return Result.ok();
    }



//    @GetMapping(value = "/dmz/track")
    public Result<?> track(String plateNumber,String handleDate,
            HttpServletRequest req) {
        List<TbVehicle> list = new ArrayList<>();
        if(StringUtils.isBlank(plateNumber)){
        list = tbVehicleService.list();
        }else{
            LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TbVehicle::getPlateNumber,plateNumber);
            list = tbVehicleService.list(queryWrapper);
        }
        LocalDate date = LocalDate.parse(handleDate);
        LocalDateTime start = LocalDateTime.of(date, LocalTime.of(0, 0, 0));
        LocalDateTime end = LocalDateTime.of(date, LocalTime.of(23, 59, 59));

        Date startTime = DateUtils.convertLocalDateTimeToDate(start);
        Date endTime = DateUtils.convertLocalDateTimeToDate(end);
        list.parallelStream().forEach(vehicle -> {
            try{
                LambdaQueryWrapper<GisRoadMileLog> removeWrapper = new LambdaQueryWrapper<>();
                removeWrapper.eq(GisRoadMileLog::getNumberPlate,vehicle.getPlateNumber());
                removeWrapper.eq(GisRoadMileLog::getOwnDate,handleDate);
                gisRoadMileLogService.remove(removeWrapper);
                gisRoadMileLogService.coverGpsToRoadMile(vehicle, startTime, endTime);
            }catch (Exception e){
                e.printStackTrace();
            }
        });
        return Result.ok();
    }

    /**
     * 分页列表查询
     *
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
//    @GetMapping(value = "/list")
    public Result<?> queryPageList(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            HttpServletRequest req) {
        Page<GisGpsAnalysis> page = new Page<GisGpsAnalysis>(pageNo, pageSize);
        LambdaQueryWrapper<GisGpsAnalysis> lambdaQueryWrapper = new LambdaQueryWrapper<GisGpsAnalysis>();
        IPage<GisGpsAnalysis> pageList = iGisGpsAnalysisService.page(page, lambdaQueryWrapper);
        return Result.ok(pageList);
    }


    @GetMapping(value = "/everydayGisInfoList")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.selectPage"})
    public Result<?> everydayGisInfoList(@Validated({SaveValidated.class}) EverydayInfoQuery query,
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            HttpServletRequest req) {
        String token = req.getHeader(DefContants.X_ACCESS_TOKEN);
        String username = JwtUtil.getUsername(token);
        LimitCheckUtil.check(req,username,token);
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(VehicleGpsType.Stopped_Work.getValue());
        integers.add(VehicleGpsType.Driving_Work.getValue());
        Page<GisGpsAnalysis> page = new Page<GisGpsAnalysis>(pageNo, pageSize);
        LambdaQueryWrapper<GisGpsAnalysis> lambdaQueryWrapper = new LambdaQueryWrapper<GisGpsAnalysis>();
        lambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(query.getNumberPlate()),GisGpsAnalysis::getNumberPlate,query.getNumberPlate())
                .eq(GisGpsAnalysis::getOwnDate,query.getTime())
                .in(GisGpsAnalysis::getRecordType,integers)
                .isNotNull(GisGpsAnalysis::getEndTime)
                .orderByAsc(GisGpsAnalysis::getStartTime);
        IPage<GisGpsAnalysis> pageList = iGisGpsAnalysisService.page(page, lambdaQueryWrapper);
        for (GisGpsAnalysis record : page.getRecords()) {
            if (ObjectUtil.isAllNotEmpty(record.getStartTime(),record.getEndTime())) {
                record.setFormatBetween(DateUtil.formatBetween(record.getStartTime(),record.getEndTime(), BetweenFormatter.Level.SECOND));
            }
        }
        return Result.ok(pageList);
    }

    /**
     * 获取车辆每日统计
     * @param query
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @GetMapping(value = "/everydayGis")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.selectList"})
    public Result<?> everydayGis(EverydayQuery query,
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                 HttpServletRequest req) {
        Page<EverydayGisVo> page = new Page<EverydayGisVo>(pageNo, pageSize);
        String token = req.getHeader(DefContants.X_ACCESS_TOKEN);
        String username = JwtUtil.getUsername(token);
        LimitCheckUtil.check(req,username,token);
        IPage<EverydayGisVo> pageList = iGisGpsAnalysisService.everydayGis(page, query);
        return Result.ok(pageList);
    }

    /**
     * 导出
     */
    @GetMapping("/everydayGis/export")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.selectList","com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.everydayMileCount"})
    public Result<?> everydayGisExport(HttpServletResponse response, EverydayQuery query) {
        try (OutputStream output = response.getOutputStream()) {
            String fileName = "模板导出测试.xlsx";
            try {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
            Page<EverydayGisVo> page = new Page<EverydayGisVo>(1, 50000);
            IPage<EverydayGisVo> pageList = iGisGpsAnalysisService.everydayGis(page, query);
            EverydayMileCountVo everydayMileCount = iGisGpsAnalysisService.everydayMileCount(query);
            TemplateExportParams templateExportParams = new TemplateExportParams("excelTemplate/车辆作业导出模板.xlsx");
            templateExportParams.setDictHandler(new MyExcelDictHandleImpl());
            HashMap<String, Object> stringOverrideHashMap = new HashMap<>();
            List<EverydayGisVo> records = pageList.getRecords();
            for (int i = 0; i < records.size(); i++) {
                EverydayGisVo everydayGisVo = records.get(i);
                everydayGisVo.setIndex(i+1);
            }
            stringOverrideHashMap.put("list", records);
            stringOverrideHashMap.put("totalMile",everydayMileCount.getTotalMile());
            stringOverrideHashMap.put("workMile",everydayMileCount.getWorkMile());
            Workbook sheets = ExcelExportUtil.exportExcel(templateExportParams,stringOverrideHashMap);
            sheets.write(output);
        } catch (IOException e) {
            return Result.error("导出错误！");
        }
        return Result.ok();
    }

    @GetMapping(value = "/statisGis")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.selectList"})
    public Result<?> statisGis(EverydayQuery query,
                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                 HttpServletRequest req) {
        Page<StatisGisVo> page = new Page<StatisGisVo>(pageNo, pageSize);
        IPage<StatisGisVo> pageList = iGisGpsAnalysisService.statisGis(page, query);
        return Result.ok(pageList);
    }

    /**
     * 导出
     */
    @GetMapping("/statisGis/export")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.selectPage","com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.everydayMileCount"})
    public Result<?> statisGisExport(HttpServletResponse response, EverydayQuery query) {
        try (OutputStream output = response.getOutputStream()) {
            String fileName = "模板导出测试2.xlsx";
            try {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
            Page<StatisGisVo> page = new Page<StatisGisVo>(1, 50000);
            IPage<StatisGisVo> pageList = iGisGpsAnalysisService.statisGis(page, query);
            EverydayMileCountVo everydayMileCount = iGisGpsAnalysisService.everydayMileCount(query);
            TemplateExportParams templateExportParams = new TemplateExportParams();
            if ("1".equals(query.getStatisType())) {
                templateExportParams.setTemplateUrl("excelTemplate/车辆作业综合分析日报导出模板.xlsx");
            } else if ("2".equals(query.getStatisType())) {
                templateExportParams.setTemplateUrl("excelTemplate/车辆作业综合分析周报导出模板.xlsx");
            } else if ("3".equals(query.getStatisType())) {
                templateExportParams.setTemplateUrl("excelTemplate/车辆作业综合分析月报导出模板.xlsx");
            } else {
                templateExportParams.setTemplateUrl("excelTemplate/车辆作业综合分析日报导出模板.xlsx");
            }
            templateExportParams.setDictHandler(new MyExcelDictHandleImpl());
            HashMap<String, Object> stringOverrideHashMap = new HashMap<>();
            List<StatisGisVo> records = pageList.getRecords();
            for (int i = 0; i < records.size(); i++) {
                StatisGisVo statisGisVo = records.get(i);
                statisGisVo.setIndex(i+1);
            }
            stringOverrideHashMap.put("list", records);
            stringOverrideHashMap.put("totalMile",everydayMileCount.getTotalMile());
            stringOverrideHashMap.put("workMile",everydayMileCount.getWorkMile());
            Workbook sheets = ExcelExportUtil.exportExcel(templateExportParams,stringOverrideHashMap);
            sheets.write(output);
        } catch (IOException e) {
            return Result.error("导出错误！");
        }
        return Result.ok();
    }

    /**
     * 获取车辆每日统计
     * @return
     */
    @GetMapping(value = "/everydayMileCount")
    @DataPermission(item="tb_gis_gps_analysis.projectId", sqlIds = {"com.gci.boot.modules.gis.mapper.GisGpsAnalysisMapper.everydayMileCount"})
    public Result<?> everydayMileCount(EverydayQuery query,
                                 HttpServletRequest req) {
        EverydayMileCountVo everydayMileCount = iGisGpsAnalysisService.everydayMileCount(query);
        return Result.ok(everydayMileCount);
    }

    /**
     * 添加
     */
//    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody GisGpsAnalysis gisGpsAnalysis) {
        iGisGpsAnalysisService.save(gisGpsAnalysis);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     */
//    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody GisGpsAnalysis gisGpsAnalysis) {
        iGisGpsAnalysisService.updateById(gisGpsAnalysis);
        return Result.ok("编辑成功！");
    }

    /**
     * 删除
     */
//    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        iGisGpsAnalysisService.removeById(id);
        return Result.ok("删除成功！");
    }

    /**
     * 批量删除
     */
//    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        iGisGpsAnalysisService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功！");
    }
}
