package com.zcxk.order.controller;

import com.zcxk.client.SmsWaterClient;
import com.zcxk.client.UserCenterClient;
import com.zcxk.entity.Message;
import com.zcxk.model.AjaxMessage;
import com.zcxk.model.LoginUser;
import com.zcxk.model.ResultStatus;
import com.zcxk.order.dto.StatisticsDto;
import com.zcxk.order.dto.WorkOrderManageDto;
import com.zcxk.order.service.WorkOrderManageService;
import com.zcxk.util.MessageSendUtil;
import com.zcxk.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

@RestController
@RequestMapping("/order/workOrderStatistics/")
@Api(tags = "工单统计")
public class WorkOrderStatisticsController {

    @Autowired
    WorkOrderManageService workOrderManageService;

    @Autowired
    UserCenterClient userCenterClient;

    @Autowired
    SmsWaterClient smsWaterClient;

    @Autowired
    private MessageSendUtil messageSendUtil;

    @RequestMapping(value = "completionStatistics", method = RequestMethod.GET)
    @ApiOperation(value = "工单完成情况统计")
    public AjaxMessage<Map<String, Object>> completionStatistics(
            @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
            @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计开始日期", required = true) @RequestParam(required = true) String startDate,
            @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
        LocalDate localDate = LocalDate.now();
        //同比日期
        String sameStartDate = null, sameEndDate = null;
        //环比日期
        String chainStartDate = null, chainEndDate = null;
        if (statsType == 0) {
            startDate = String.format("%s-01", startDate);
            endDate = subMonth(startDate, 1);

            sameStartDate = subYear(startDate, -1);
            sameEndDate = subMonth(sameStartDate, 1);

            chainStartDate = subMonth(startDate, -1);
            chainEndDate = subMonth(chainStartDate, 1);
        } else if (statsType == 1) {
            startDate = String.format("%s-01-01", startDate);
            endDate = subYear(startDate, 1);

            sameStartDate = subYear(startDate, -1);
            sameEndDate = subYear(sameStartDate, 1);

            chainStartDate = subYear(startDate, -1);
            chainEndDate = subYear(chainStartDate, 1);
        } else if (statsType == 2) {
            startDate = String.format("%s-01", startDate);
            endDate = String.format("%s-01", endDate);
            if(isCurrentMonth(endDate)==true){
                endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
            }
            else {
                endDate = subMonth(endDate, 1);
            }
        }
        //根据用户编号，获取用户的权限
        LoginUser loginUser = UserUtil.getCurrentUser();
        WorkOrderManageDto workOrderManageDto = new WorkOrderManageDto();
        workOrderManageDto.setStartDate(startDate);
        workOrderManageDto.setEndDate(endDate);
        workOrderManageDto.setTenantId(loginUser.getTenantId());
        workOrderManageDto.setProgramItems(loginUser.getProgramItemList());
        workOrderManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        workOrderManageDto.setPermissonType(loginUser.getPermissonType());
        Map<String, Object> statistics = workOrderManageService.workOrderStatistics(workOrderManageDto);
        if(!statistics.containsKey("工单完成数")){
            statistics.put("工单完成数",0);
        }
        if(!statistics.containsKey("工单完成率")){
            statistics.put("工单完成率",0);
        }
        workOrderManageDto.setStartDate(sameStartDate);
        workOrderManageDto.setEndDate(sameEndDate);
        //同比
        Map<String, Object> sameStatistic = workOrderManageService.workOrderStatistics(workOrderManageDto);
        if(!sameStatistic.containsKey("工单完成数")){
            sameStatistic.put("工单完成数",0);
        }
        if(!sameStatistic.containsKey("工单完成率")){
            sameStatistic.put("工单完成率",0);
        }
        //环比
        workOrderManageDto.setStartDate(chainStartDate);
        workOrderManageDto.setEndDate(chainEndDate);
        Map<String, Object> chainStatistic = workOrderManageService.workOrderStatistics(workOrderManageDto);
        if(!chainStatistic.containsKey("工单完成数")){
            chainStatistic.put("工单完成数",0);
        }
        if(!chainStatistic.containsKey("工单完成率")){
            chainStatistic.put("工单完成率",0);
        }

        DecimalFormat df = new DecimalFormat("#0.00");

        if (sameStatistic.get("工单完成率") == null || sameStatistic.get("工单完成率").toString().equals("0")) {
            statistics.put("工单完成率同比", null);
        } else {
            Double finishedSameRate = (Double.parseDouble(statistics.get("工单完成率").toString()) - Double.parseDouble(sameStatistic.get("工单完成率").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单完成率").toString());
            statistics.put("工单完成率同比", df.format(finishedSameRate));
        }

        if (chainStatistic.get("工单完成率") == null || chainStatistic.get("工单完成率").toString().equals("0")) {
            statistics.put("工单完成率环比", null);
        } else {
            Double finishedChainRate = (Double.parseDouble(statistics.get("工单完成率").toString()) - Double.parseDouble(chainStatistic.get("工单完成率").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单完成率").toString());
            statistics.put("工单完成率环比", df.format(finishedChainRate));
        }
        
        if (sameStatistic.get("工单总数") == null || sameStatistic.get("工单总数").toString().equals("0")) {
            statistics.put("工单总数同比", null);
        } else {
            Double orderSameTotalNumberRate = (Double.parseDouble(statistics.get("工单总数").toString()) - Double.parseDouble(sameStatistic.get("工单总数").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单总数").toString());
            statistics.put("工单总数同比", df.format(orderSameTotalNumberRate));
        }
        if (chainStatistic.get("工单总数") == null || chainStatistic.get("工单总数").toString().equals("0")) {
            statistics.put("工单总数环比", null);
        } else {
            Double orderChainTotalNumberRate = (Double.parseDouble(statistics.get("工单总数").toString()) - Double.parseDouble(chainStatistic.get("工单总数").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单总数").toString());
            statistics.put("工单总数环比", df.format(orderChainTotalNumberRate));
        }

        if (sameStatistic.get("工单完成数") == null || sameStatistic.get("工单完成数").toString().equals("0")) {
            statistics.put("工单完成数同比", null);

        } else {
            Double finishedSameNumber = (Double.parseDouble(statistics.get("工单完成数").toString()) - Double.parseDouble(sameStatistic.get("工单完成数").toString())) * 100 / Double.parseDouble(sameStatistic.get("工单完成数").toString());
            statistics.put("工单完成数同比", df.format(finishedSameNumber));
        }

        if (chainStatistic.get("工单完成数") == null || chainStatistic.get("工单完成数").toString().equals("0")) {
            statistics.put("工单完成数环比", null);
        } else {
            Double finishedChainNumber = (Double.parseDouble(statistics.get("工单完成数").toString()) - Double.parseDouble(chainStatistic.get("工单完成数").toString())) * 100 / Double.parseDouble(chainStatistic.get("工单完成数").toString());
            statistics.put("工单完成数环比", df.format(finishedChainNumber));
        }

        return new AjaxMessage<>(ResultStatus.OK, statistics);
    }

    @RequestMapping(value = "eventStatistics", method = RequestMethod.GET)
    @ApiOperation(value = "事件曲线数据统计展示、人均工单数据统计展示")
    public AjaxMessage<Map<String,Object>> eventStatistics(
            @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
            @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
            @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
        int maintainerCount = 0;
        LocalDate localDate = LocalDate.now();
        Map<String,Object> result = new HashMap<>();
        List<Map<String, Object>> statistics = new ArrayList<>(), average =new ArrayList<>();
        //根据用户编号，获取用户的权限
        LoginUser loginUser = UserUtil.getCurrentUser();
        WorkOrderManageDto workOrderManageDto = new WorkOrderManageDto();
        workOrderManageDto.setTenantId(loginUser.getTenantId());
        workOrderManageDto.setProgramItems(loginUser.getProgramItemList());
        workOrderManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        workOrderManageDto.setPermissonType(loginUser.getPermissonType());
        switch (statsType) {
            case 0:
                maintainerCount = userCenterClient.findMaintainerCount(startDate);
                startDate = String.format("%s-01", startDate);
                if(isCurrentMonth(startDate)==true){
                    endDate = String.format("%s-%s", startDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(startDate, 1);
                }
                break;
            case 1:
                maintainerCount = userCenterClient.findMaintainerCount(String.format("%s-12",startDate));
                startDate = String.format("%s-01-01", startDate);
                if(isCurrentYear(startDate)==true){
                    endDate = String.format("%s-%s-01", localDate.getYear(),localDate.getMonthValue()+1);
                }
                else {
                    endDate = subYear(startDate, 1);
                }
                break;
            case 2:
                maintainerCount = userCenterClient.findMaintainerCount(endDate);
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);
                if(isCurrentMonth(endDate)==true){
                    endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(endDate, 1);
                }
                break;
        }
        workOrderManageDto.setStartDate(startDate);
        workOrderManageDto.setEndDate(endDate);

        if (statsType == 0 || statsType == 2) {
            statistics = workOrderManageService.eventMonthStatistics(workOrderManageDto);
        } else if (statsType == 1) {
            statistics = workOrderManageService.eventYearStatistics(workOrderManageDto);
        }
        int seq=0;
        DecimalFormat df = new DecimalFormat("#0.00");
        for(Map<String,Object> map : statistics){
            seq++;
            double number = 0;
            if(maintainerCount > 0){
                number = Double.parseDouble(map.get("数量").toString())/maintainerCount;
            }
            Map<String,Object> data = new HashMap<>();
            data.put("日期",map.get("日期"));
            data.put("数量",df.format(number));
            data.put("序号",seq);
            average.add(data);
        }
        result.put("事件数量",statistics);
        result.put("人均工单",average);
        return new AjaxMessage<>(ResultStatus.OK, result);
    }

    @RequestMapping(value = "orderDurationStatistics", method = RequestMethod.GET)
    @ApiOperation(value = "工单时长统计展示")
    public AjaxMessage<List<StatisticsDto>> orderDurationStatistics(
            @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
            @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
            @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
        //根据用户编号，获取用户的权限
        LocalDate localDate = LocalDate.now();
        LoginUser loginUser = UserUtil.getCurrentUser();
        WorkOrderManageDto workOrderManageDto = new WorkOrderManageDto();
        workOrderManageDto.setTenantId(loginUser.getTenantId());
        workOrderManageDto.setProgramItems(loginUser.getProgramItemList());
        workOrderManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        workOrderManageDto.setPermissonType(loginUser.getPermissonType());
        switch (statsType) {
            case 0:
                startDate = String.format("%s-01", startDate);
                if(isCurrentMonth(startDate)==true){
                    endDate = String.format("%s-%s", startDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(startDate, 1);
                }
                break;
            case 1:
                startDate = String.format("%s-01-01", startDate);
                endDate = subYear(startDate, 1);
                break;
            case 2:
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);
                if(isCurrentMonth(endDate)==true){
                    endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(endDate, 1);
                }
                break;
        }
        workOrderManageDto.setStartDate(startDate);
        workOrderManageDto.setEndDate(endDate);
        List<StatisticsDto> statistics = workOrderManageService.orderDurationStatistics(workOrderManageDto);
        return new AjaxMessage<>(ResultStatus.OK, statistics);
    }

    @RequestMapping(value = "dispatchTimesStatistics", method = RequestMethod.GET)
    @ApiOperation(value = "派单次数统计")
    public AjaxMessage<List<Map<String,Object>>> dispatchTimesStatistics(
            @ApiParam(value = "场景ID", required = true) @RequestParam(required = true) String scenesId,
            @ApiParam(value = "设备ID", required = true) @RequestParam(required = true) int id,
            @ApiParam(value = "设备或场景标识(1:设备;2:场景)", required = true) @RequestParam(required = true) int sort,
            @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
            @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
            @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
        LocalDate localDate = LocalDate.now();
        LoginUser loginUser = UserUtil.getCurrentUser();
        List<Map<String,Object>> statistics = new ArrayList<Map<String, Object>>();
        WorkOrderManageDto workOrderManageDto = new WorkOrderManageDto();
        workOrderManageDto.setTenantId(loginUser.getTenantId());
        workOrderManageDto.setProgramItems(loginUser.getProgramItemList());
        workOrderManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        workOrderManageDto.setPermissonType(loginUser.getPermissonType());
        switch (statsType) {
            case 0:
                startDate = String.format("%s-01", startDate);
                if(isCurrentMonth(startDate)==true){
                    endDate = String.format("%s-%s", startDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(startDate, 1);
                }
                break;
            case 1:
                startDate = String.format("%s-01-01", startDate);
                if(isCurrentYear(startDate)==true){
                    endDate = String.format("%s-%s-01", localDate.getYear(),localDate.getMonthValue()+1);
                }
                else {
                    endDate = subYear(startDate, 1);
                }
                break;
            case 2:
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);
                if(isCurrentMonth(endDate)==true){
                    endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = subMonth(endDate, 1);
                }
                break;
        }
        List<String> idsList = null;
        workOrderManageDto.setStartDate(startDate);
        workOrderManageDto.setEndDate(endDate);
         if(sort==1){
           workOrderManageDto.setDeviceId(id);
           idsList = new ArrayList<String>();
           String [] ids = scenesId.split(",");
           idsList = Arrays.asList(ids);
        } else if (sort ==2){
             workOrderManageDto.setScenesId(Integer.parseInt(scenesId));
         }
        if(statsType ==0 || statsType ==2) {
            statistics = workOrderManageService.dispatchTimesMonthStatistics(workOrderManageDto, idsList);
        }
        else if(statsType == 1){
            statistics =  workOrderManageService.dispatchTimesYearStatistics(workOrderManageDto,idsList);
        }
        return new AjaxMessage<>(ResultStatus.OK, statistics);
    }

    @RequestMapping(value = "distributionStatistics", method = RequestMethod.GET)
    @ApiOperation(value = "上报类型、工单类型、工单状态统计")
    public AjaxMessage<Map<String, Object>> distributionStatistics(
            @ApiParam(value = "统计类型:0-按月统计,1-按年统计,2-自定义统计", required = true) @RequestParam(required = true) int statsType,
            @ApiParam(value = "统计时间:月格式(yyyy-MM),年格式(yyyy),自定义统计时间开始日期", required = true) @RequestParam(required = true) String startDate,
            @ApiParam(value = "统计时间:年月统计不用传入此参数,自定义统计截至日期", required = false) @RequestParam(required = false) String endDate) throws ParseException {
        LocalDate localDate = LocalDate.now();
        Map<String, Object> result = new HashMap<>();
        //根据用户编号，获取用户的权限
        LoginUser loginUser = UserUtil.getCurrentUser();
        WorkOrderManageDto workOrderManageDto = new WorkOrderManageDto();
        workOrderManageDto.setTenantId(loginUser.getTenantId());
        workOrderManageDto.setProgramItems(loginUser.getProgramItemList());
        workOrderManageDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        workOrderManageDto.setPermissonType(loginUser.getPermissonType());
        if (statsType == 0) {
            startDate = String.format("%s-01", startDate);
            endDate = subMonth(startDate, 1);

        } else if (statsType == 1) {
            startDate = String.format("%s-01-01", startDate);
            endDate = subYear(startDate, 1);
        } else if (statsType == 2) {
            startDate = String.format("%s-01", startDate);
            endDate = String.format("%s-01", endDate);
            if(isCurrentMonth(endDate)==true){
                endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
            }
            else {
                endDate = subMonth(endDate, 1);
            }
        }
        workOrderManageDto.setStartDate(startDate);
        workOrderManageDto.setEndDate(endDate);
        result.put("上报类型", CalculatePercentage(workOrderManageService.reportStatistics(workOrderManageDto)));
        result.put("工单状态", CalculatePercentage(workOrderManageService.orderStatusStatistics(workOrderManageDto)));
        result.put("工单类型", CalculatePercentage(workOrderManageService.orderTypeStatistics(workOrderManageDto)));
        return new AjaxMessage<>(ResultStatus.OK, result);
    }

    @RequestMapping(value = "reminder", method = RequestMethod.GET)
    @ApiOperation(value = "催单")
    public AjaxMessage<Object> reminder(
            @ApiParam(value = "用户ID,多个用户ID之间用豆号隔开", required = true) @RequestParam(required = true) String ids,
            @ApiParam(value = "消息内容", required = true) @RequestParam(required = true) String content){
        try {
            String [] userIdArray = ids.split(",");
            List<String> idList = Arrays.asList(userIdArray);
            //sendMessage(idList, content, 8,0);//channel:0 pc
            sendMessage(idList, content, 9,1); //channel:1 app
            return new AjaxMessage<>(ResultStatus.OK);
        }catch (Exception ex){
        }
        return new AjaxMessage<>(ResultStatus.ERROR);
    }

    /**
     * pc渠道为0，app渠道为1
     * @param idList 用户ID
     * @param content 消息内容
     * @param messageType:pc消息类型为8,app消息类型为9
     * @param channel:pc渠道为0，app渠道为1
     */
    private void sendMessage(List<String> idList, String content,int messageType,int channel){
        Message message=new Message();
        message.setStatus(1);
        LoginUser currentUser = UserUtil.getCurrentUser();
        message.setCreateBy(currentUser.getId().toString());
        message.setTenantId(currentUser.getTenantId());
        message.setMessageContent(content);
        message.setMessageId(UUID.randomUUID().toString());
        message.setMessageType(messageType);
        message.setUrl(null);
        message.setMessageTemplateId(null);
        message.setChannel(channel);
        for(String id : idList) {
            message.setUserId(Integer.parseInt(id));
            messageSendUtil.send(message);
        }
    }

    private List<StatisticsDto> CalculatePercentage(List<StatisticsDto> list) {
        double total = 0;
        DecimalFormat df = new DecimalFormat("#0.00");
        for (StatisticsDto statisticsDto : list) {
            if (statisticsDto.getStatisticsValue() != null) {
                total += statisticsDto.getStatisticsValue();
            }
        }
        for (StatisticsDto statisticsDto : list) {
            double d = statisticsDto.getStatisticsValue() * 100 / total;
            BigDecimal b = new BigDecimal(d);
            statisticsDto.setStatisticsValue(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
        return list;
    }

    /**
     * 日期增加一年
     */
    private String subYear(String date, int n) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(date);
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        rightNow.add(Calendar.YEAR, n);
        Date dt1 = rightNow.getTime();
        String reStr = sdf.format(dt1);
        return reStr;
    }

    /**
     * 日期增加一月
     */
    private String subMonth(String date, int n) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(date);
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        rightNow.add(Calendar.MONTH, n);
        Date dt1 = rightNow.getTime();
        String reStr = sdf.format(dt1);
        return reStr;
    }

    /**
     * 日期是否当前月份
     */
    public boolean isCurrentMonth(String date) throws ParseException {
        LocalDate localDate = LocalDate.now();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(date);
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        int y = rightNow.get(Calendar.YEAR);
        int m =rightNow.get(Calendar.MONTH)+1;
        if( y== localDate.getYear() &&  m == localDate.getMonthValue()){
            return true;
        }
        return false;
    }

    /**
     * 日期是否当前月份
     */
    public boolean isCurrentYear(String date) throws ParseException {
        LocalDate localDate = LocalDate.now();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(date);
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(dt);
        int y = rightNow.get(Calendar.YEAR);
        if( y== localDate.getYear()){
            return true;
        }
        return false;
    }
}
