package com.zcxk.charge.web.controller;
import com.zcxk.charge.api.vo.DeviceWaterSupplyVo;
import com.zcxk.charge.web.service.AppPageReportService;
import com.zcxk.core.common.pojo.AjaxMessage;
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.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description
 * @author  wangbo
 * @data 2021/3/18 10:50
 */
@RestController
@RequestMapping("/appPageReport")
@Api(tags = "App总览报表")
public class AppPageReportController extends BaseController {


    @Autowired
    private AppPageReportService appPageReportService;

    @RequestMapping(value = "getProductionDataForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据(本月)")
    public AjaxMessage getProductionDataForMonth(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        LocalDate localDate = LocalDate.now();
        List<DeviceWaterSupplyVo> intakeWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId, WATER_SOURCE.getMessage(),4,1);
        List<DeviceWaterSupplyVo> makingWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId, WATER_WORKS.getMessage(), 3,1);
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,1);
        List<DeviceWaterSupplyVo> intakeDayList   = appPageReportService.deviceWaterReportForDay(companyOrgId,WATER_SOURCE.getMessage(),4, localDate.getDayOfMonth());
        List<DeviceWaterSupplyVo> makingDayList   = appPageReportService.deviceWaterReportForDay(companyOrgId,WATER_WORKS.getMessage(), 3, localDate.getDayOfMonth());
        Map<String,Object> map = new HashMap<>(3);
        map.put("intake", intakeDayList);
        map.put("making", makingDayList);
        map.put("seller", sellerWaterList);
        appPageReportService.calculationNrw(intakeWaterList, makingWaterList, sellerWaterList,map);
        return AjaxMessage.success(map);
    }

    /**
     * @Author wangbo
     * @Description App生产总览数据-本年数据
     * @param companyOrgId 公司ID
     * @return
     */
    @RequestMapping(value = "getProductionDataForSameYear",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据(本年)")
    public AjaxMessage getProductionDataForSameYear(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        LocalDate localDate = LocalDate.now();
        List<DeviceWaterSupplyVo> supplyWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_SOURCE.getMessage(),4,localDate.getMonthValue());
        List<DeviceWaterSupplyVo> makingWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_WORKS.getMessage(), 3,localDate.getMonthValue());
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,localDate.getMonthValue());
        Map<String,Object> map = new HashMap<String,Object>(3);
        map.put("intake", supplyWaterList);
        map.put("making", makingWaterList);
        map.put("seller", sellerWaterList);
        appPageReportService.calculationNrw(supplyWaterList,makingWaterList,sellerWaterList,map);
        return AjaxMessage.success(map);
    }

    /**
     * @Author wangbo
     * @Description App生产总览数据-近一年数据
     * @param companyOrgId 公司ID
     * @return
     */
    @RequestMapping(value = "getProductionDataFor12Month",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据(近一年)")
    public AjaxMessage getProductionDataFor12Month(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> supplyWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_SOURCE.getMessage(),4,12);
        List<DeviceWaterSupplyVo> makingWaterList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_WORKS.getMessage(), 3,12);
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,12);
        Map<String,Object> map = new HashMap<String,Object>(3);
        map.put("intake", supplyWaterList);
        map.put("making", makingWaterList);
        map.put("seller", sellerWaterList);
        appPageReportService.calculationNrw(supplyWaterList,makingWaterList,sellerWaterList,map);
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getProductionComparisonForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据-取水环比(本月)")
    public AjaxMessage getProductionComparisonForSameMonth(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> intakeComparisonList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_SOURCE.getMessage(), 4,2);
        List<DeviceWaterSupplyVo> makingComparisonList =  appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_WORKS.getMessage(), 3,2);
        List<DeviceWaterSupplyVo> sellerComparisonList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,2);
        Map<String,Object> map = new HashMap<String,Object>(3);
        map.put("intakeComparison",appPageReportService.calculationComparison2(intakeComparisonList,1));
        map.put("makingComparison",appPageReportService.calculationComparison2(makingComparisonList,1));
        map.put("sellerComparison", appPageReportService.calculationComparison2(sellerComparisonList,1));
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getProductionComparisonForSameYear",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据-取水环比、供水环比、售水环比(本年)")
    public AjaxMessage getProductionComparisonForSameYear(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        LocalDate now = LocalDate.now();
        List<DeviceWaterSupplyVo> intakeComparisonList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_SOURCE.getMessage(), 4,now.getMonthValue()+12);
        List<DeviceWaterSupplyVo> makingComparisonList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_WORKS.getMessage(), 3,now.getMonthValue()+12);
        List<DeviceWaterSupplyVo> sellerComparisonList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,now.getMonthValue() + 12);
        Map<String,Object> map = new HashMap<String,Object>(3);
        map.put("intakeComparison",appPageReportService.calculationComparison2(intakeComparisonList,2));
        map.put("makingComparison",appPageReportService.calculationComparison2(makingComparisonList,2));
        map.put("sellerComparison", appPageReportService.calculationComparison2(sellerComparisonList,2));
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getProductionComparisonForLast12Month",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——生产数据-取水环比、供水环比、售水环比(近一年)")
    public AjaxMessage getProductionComparisonForLast12Month(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> intakeComparisonList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_SOURCE.getMessage(),4,24);
        List<DeviceWaterSupplyVo> makingComparisonList = appPageReportService.deviceWaterReportForMonth(companyOrgId,WATER_WORKS.getMessage(), 3,24);
        List<DeviceWaterSupplyVo> sellerComparisonList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,24);
        Map<String,Object> map = new HashMap<String,Object>(3);
        map.put("intakeComparison",appPageReportService.calculationComparison2(intakeComparisonList,3));
        map.put("makingComparison",appPageReportService.calculationComparison2(makingComparisonList,3));
        map.put("sellerComparison", appPageReportService.calculationComparison2(sellerComparisonList,3));
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getBusinessDataForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营业总览应收实收回收率普通用户用量大用户用量数据(本月)")
    public AjaxMessage<Map<String,Object>> getSameMonthBusinessData(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,1);
        BigDecimal sum = sellerWaterList.get(0).getGeneralUserAmount().add(sellerWaterList.get(0).getBigUserAmount());
        BigDecimal generalRate =sum.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:sellerWaterList.get(0).getGeneralUserAmount().
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sum,2, BigDecimal.ROUND_DOWN);
        BigDecimal bigUserRate =sum.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:sellerWaterList.get(0).getBigUserAmount().
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sum,2, BigDecimal.ROUND_DOWN);
        Map<String,Object> map = new HashMap<String,Object>(8);
        map.put("totalReceivable", sellerWaterList.get(0).getReceivableAmount());
        map.put("totalReceived", sellerWaterList.get(0).getReceivedAmount());
        map.put("amountDetails",sellerWaterList);
        map.put("generalUser",sellerWaterList.get(0).getGeneralUserAmount());
        map.put("bigUser",sellerWaterList.get(0).getBigUserAmount());
        map.put("generalUserRate",generalRate);
        map.put("bigUserRate",bigUserRate);
        map.put("recoveryRate", sellerWaterList.get(0).getReceivableAmount().compareTo(BigDecimal.ZERO)==0? 0 : sellerWaterList.get(0).getReceivedAmount().
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).
                divide(sellerWaterList.get(0).getReceivableAmount(),2, BigDecimal.ROUND_DOWN));
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getRevenueDataForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App——营业数据-本月应收实收售水回收率数据(本月)")
    public AjaxMessage<Map<String,Object>> getRevenueDataForSameMonth(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,1);
        List<DeviceWaterSupplyVo> sellerAmountList = appPageReportService.deviceSellerWaterReportForMonth(companyOrgId,1);
        Map<String,Object> map = new HashMap<String,Object>(4);
        map.put("receivableAmount", sellerWaterList.get(0).getReceivableAmount());
        map.put("receivedAmount",  sellerWaterList.get(0).getReceivedAmount());
        map.put("sellerAmount",    sellerAmountList.get(0).getAmount());
        map.put("recoveryRate",    sellerWaterList.get(0).getReceivableAmount().compareTo(BigDecimal.ZERO) == 0? 0 : sellerWaterList.get(0).getReceivedAmount().
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).
                divide(sellerWaterList.get(0).getReceivableAmount(),2, BigDecimal.ROUND_DOWN));
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getBusinessDataForSameYear",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营业总览数据-本月应收实收回收率数据(本年)")
    public AjaxMessage<Map<String,Object>> getBusinessDataForSameYear(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        return AjaxMessage.success(convertMap(appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,LocalDate.now().getMonthValue())));
    }

    @RequestMapping(value = "getBusinessDataForLast12Month",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营业总览数据-近一年应收实收回收率数据(近一年)")
    public AjaxMessage<Map<String,Object>> getBusinessDataForLast12Month(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        return AjaxMessage.success(convertMap(appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,12)));
    }

    @RequestMapping(value = "getSellerComparisonForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营收数据-应收实收环比(本月)")
    public AjaxMessage<Object> getSellerComparisonForSameMonth(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        List<DeviceWaterSupplyVo> sellerWaterList = appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,2);
        BigDecimal receivableComparison = sellerWaterList.get(0).getReceivableAmount().compareTo(BigDecimal.ZERO)==0 ?BigDecimal.ZERO:sellerWaterList.get(1).getReceivableAmount().subtract(sellerWaterList.get(0).getReceivableAmount()).
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sellerWaterList.get(0).getReceivableAmount(),2, BigDecimal.ROUND_DOWN);

        BigDecimal receivedComparison = sellerWaterList.get(0).getReceivedAmount().compareTo(BigDecimal.ZERO)==0 ?BigDecimal.ZERO:sellerWaterList.get(1).getReceivedAmount().subtract(sellerWaterList.get(0).getReceivedAmount()).
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sellerWaterList.get(0).getReceivedAmount(),2, BigDecimal.ROUND_DOWN);
        Map<String,Object> map = new HashMap<String,Object>(2);
        map.put("receivableComparison",receivableComparison);
        map.put("receivedComparison",receivedComparison);
        return AjaxMessage.success(map);
    }

    @RequestMapping(value = "getSellerComparisonForSameYear",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营收数据-应收实收环比(本年)")
    public AjaxMessage getSellerComparisonForSameYear(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        return AjaxMessage.success(convertSellerComparisonMap(appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,12 + LocalDate.now().getMonthValue())));
    }

    @RequestMapping(value = "getSellerComparisonForLast12Month",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——营收数据-应收实收环比(本年)")
    public AjaxMessage getSellerComparisonForLast12Month(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Integer companyOrgId){
        return AjaxMessage.success(convertSellerComparisonMap(appPageReportService.deviceSellerAmountReportForMonth(companyOrgId,24)));
    }

    @RequestMapping(value = "getSceneAmountForSameMonth",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——资产情况本月")
    public AjaxMessage<Object> getSceneAmountForSameMonth(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Long companyOrgId){
        List<Map<String,Object>> amount = appPageReportService.findSceneAmount(companyOrgId,1);
        Map<String,Object> map = new HashMap<String,Object>(2);
        map.put("amount","0");
        map.put("sceneTypeName","大用户表");
        amount.add(map);
        return AjaxMessage.success(amount);
    }

    @RequestMapping(value = "getSceneAmountForSameYear",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——资产情况本年")
    public AjaxMessage<Object> getSceneAmountForSameYear(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Long companyOrgId){
        LocalDate now = LocalDate.now();
        List<Map<String,Object>> amount = appPageReportService.findSceneAmount(companyOrgId,now.getMonthValue());
        Map<String,Object> map = new HashMap<String,Object>(2);
        map.put("amount","0");
        map.put("sceneTypeName","大用户表");
        amount.add(map);
        return AjaxMessage.success(amount);
    }

    @RequestMapping(value = "getSceneAmountForLast12Month",method = RequestMethod.GET)
    @ApiOperation(value = "App总览——资产情况近一年")
    public AjaxMessage<Object> getSceneAmountForLast12Month(@ApiParam(value = "公司id,总公司传空值") @RequestParam(required = false) Long companyOrgId){
        List<Map<String,Object>> amount = appPageReportService.findSceneAmount(companyOrgId,12);
        Map<String,Object> map = new HashMap<String,Object>(2);
        map.put("amount","0");
        map.put("sceneTypeName","大用户表");
        amount.add(map);
        return AjaxMessage.success(amount);
    }

    /**
    * 转换map
    * @author Andy
    * @date 16:37 2021/8/16
    * @param sellerWaterList:
    * @return java.util.Map<java.lang.String,java.lang.Object>
    **/
    private Map<String,Object>  convertMap(List<DeviceWaterSupplyVo> sellerWaterList){
        BigDecimal totalReceivableAmount = new BigDecimal(0);
        BigDecimal totalReceivedAmount = new BigDecimal(0);
        BigDecimal totalGeneralUser = new BigDecimal(0);
        BigDecimal totalBigUser = new BigDecimal(0);
        for(DeviceWaterSupplyVo amount: sellerWaterList){
            totalReceivableAmount =totalReceivableAmount.add(amount.getReceivableAmount());
            totalReceivedAmount=totalReceivedAmount.add(amount.getReceivedAmount());
            totalGeneralUser=totalGeneralUser.add(amount.getGeneralUserAmount());
            totalBigUser=totalBigUser.add(amount.getBigUserAmount());
            amount.setRecoveryRate(totalReceivableAmount.compareTo(BigDecimal.ZERO)==0? BigDecimal.ZERO : totalReceivedAmount.
                    multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(totalReceivableAmount,2, BigDecimal.ROUND_DOWN));
        }

        BigDecimal sum = totalBigUser.add(totalGeneralUser);
        BigDecimal generalRate =sum.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:totalGeneralUser.
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sum,2, BigDecimal.ROUND_DOWN);
        BigDecimal bigUserRate =sum.compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:totalBigUser.
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(sum,2, BigDecimal.ROUND_DOWN);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("totalReceivable", totalReceivableAmount);
        map.put("totalReceived",totalReceivedAmount);
        map.put("amountDetails",sellerWaterList);
        map.put("generalUser",totalGeneralUser);
        map.put("bigUser",totalBigUser);
        map.put("generalUserRate",generalRate);
        map.put("bigUserRate",bigUserRate);
        map.put("recoveryRate", totalReceivableAmount.compareTo(BigDecimal.ZERO)==0? 0 : totalReceivedAmount.
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(totalReceivableAmount,2, BigDecimal.ROUND_DOWN));
        return map;
    }

    /**
    * 数据转换
    * @author Andy
    * @date 16:43 2021/8/16
    * @param sellerWaterList:
    * @return java.util.Map<java.lang.String,java.lang.Object>
    **/
    private Map<String,Object> convertSellerComparisonMap(List<DeviceWaterSupplyVo> sellerWaterList){
        BigDecimal receivedSameYearComparison   = new BigDecimal(0);
        BigDecimal receivedLastYearComparison   = new BigDecimal(0);
        BigDecimal receivableSameYearComparison = new BigDecimal(0);
        BigDecimal receivableLastYearComparison = new BigDecimal(0);
        for(int i= 0 ;i < sellerWaterList.size();i++){
            if (i >= 12){
                receivedSameYearComparison = receivedSameYearComparison.add(sellerWaterList.get(i).getReceivedAmount());
                receivableSameYearComparison =receivableSameYearComparison.add(sellerWaterList.get(i).getReceivableAmount());
            }
            else{
                receivedLastYearComparison = receivedLastYearComparison.add(sellerWaterList.get(i).getReceivedAmount());
                receivableLastYearComparison =receivableLastYearComparison.add(sellerWaterList.get(i).getReceivableAmount());
            }
        }
        BigDecimal receivedComparison = receivedLastYearComparison.compareTo(BigDecimal.ZERO)==0 ? BigDecimal.ZERO:receivedSameYearComparison.subtract(receivedLastYearComparison).
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(receivedLastYearComparison,2, BigDecimal.ROUND_DOWN);
        BigDecimal receivableComparison = receivableLastYearComparison.compareTo(BigDecimal.ZERO)==0 ?BigDecimal.ZERO:receivableSameYearComparison.subtract(receivableLastYearComparison).
                multiply(new BigDecimal(100)).setScale(3,BigDecimal.ROUND_HALF_UP).divide(receivableLastYearComparison,2, BigDecimal.ROUND_DOWN);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("receivableComparison",receivableComparison);
        map.put("receivedComparison",receivedComparison);
        return map;
    }
}
