package com.zcxk.charge.web.controller;

import com.zcxk.charge.api.dto.AlarmDetailsRealTimeDto;
import com.zcxk.charge.api.dto.MonthRevenueDto;
import com.zcxk.charge.api.dto.MonthSellwaterDto;
import com.zcxk.charge.api.dto.query.RevenueDto;
import com.zcxk.charge.api.dto.query.RevenuePageDto;
import com.zcxk.charge.api.enums.ChargeErrorEnum;
import com.zcxk.charge.api.vo.MonthRevenueVo;
import com.zcxk.charge.api.vo.MonthSellwaterVo;
import com.zcxk.charge.core.entity.MonthRevenueEntity;
import com.zcxk.charge.core.entity.MonthSellwaterEntity;
import com.zcxk.charge.core.entity.WaterPropertyEntity;
import com.zcxk.charge.web.common.Pagination;
import com.zcxk.charge.web.enums.SceneEnum;
import com.zcxk.charge.web.service.RevenueService;
import com.zcxk.charge.web.service.WaterPropertyService;
import com.zcxk.charge.web.util.ExcelUtil;
import com.zcxk.charge.web.util.OrgInfoUtil;
import com.zcxk.charge.web.util.ReportExcelUtil;
import com.zcxk.core.common.enums.RespCodeEnum;
import com.zcxk.core.common.pojo.AjaxMessage;
import com.zcxk.core.common.util.BeanCopyUtils;
import com.zcxk.core.oauth2.pojo.LoginUser;
import com.zcxk.core.oauth2.util.UserUtil;
import com.zcxk.core.utils.export.EasyExcelUtil;
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.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 营收控制层
 *
 * @author yjy
 * @since 2021-2-24
 */
@RestController
@RequestMapping("/revenue")
@Api(tags = "营收信息")
public class RevenueController {

    /**
     * 服务对象
     */
    @Autowired
    private RevenueService revenueService;

    @Autowired
    private OrgInfoUtil orgInfoUtil;

    @Value("${SMS.sys_excel_path}")
    private String baseDir;

    @Autowired
    private WaterPropertyService waterPropertyService;

    @RequestMapping(value = "selectMonthSell", method = RequestMethod.GET)
    @ApiOperation(value = "查询本月售水信息")
    public AjaxMessage selectMonthSell(@ApiParam(value = "公司机构id")@RequestParam(required = false) Integer companyOrgId) {
        return AjaxMessage.success( revenueService.selectMonthSell(companyOrgId));
    }

    @RequestMapping(value = "selectMonthSellTotal", method = RequestMethod.GET)
    @ApiOperation(value = "查询近6个月总售水量")
    public AjaxMessage selectMonthSellTotal( @ApiParam(value = "公司机构id")@RequestParam(required = false) Integer companyOrgId) {
        return AjaxMessage.success( revenueService.selectMonthSellTotal(companyOrgId));
    }

    @RequestMapping(value = "selectMonthRevenue", method = RequestMethod.GET)
    @ApiOperation(value = "查询月营收情况")
    public AjaxMessage selectMonthRevenue(
            @ApiParam(value = "近几月", required = true)@RequestParam Integer months,
            @ApiParam(value = "公司机构id")@RequestParam(required = false) Integer companyOrgId) {
        return AjaxMessage.success( revenueService.selectMonthRevenue(companyOrgId,months));
    }

    @RequestMapping(value = "selectCompanyRevenue", method = RequestMethod.GET)
    @ApiOperation(value = "查询本月各分公司的营收情况")
    public AjaxMessage selectCompanyRevenue() {
        List<MonthRevenueVo> result = revenueService.selectCompanyRevenue();
        for(MonthRevenueVo revenue : result){
            revenue.setCompanyOrgName(orgInfoUtil.getOrgName(revenue.getCompanyOrgId()));
        }
        return AjaxMessage.success(  result);
    }

    @RequestMapping(value = "syncMeterCount", method = RequestMethod.GET)
    @ApiOperation(value = "同步水表数量")
    public AjaxMessage syncMeterCount() {
        revenueService.syncMeterCount();
        return AjaxMessage.success( );
    }

    @RequestMapping(value = "addRevenue", method = RequestMethod.POST)
    @ApiOperation(value = "新增营收数据")
    public AjaxMessage addRevenue(@ApiParam(value = "营收数据", required = true) @RequestBody MonthRevenueDto monthRevenueDto) {
        try{
            //判断该机构是否有该月的数据
            if(revenueService.isExistMonthRevenue(monthRevenueDto.getCompanyOrgId(),monthRevenueDto.getCollectDateString(),null)>0){
                return AjaxMessage.success( ChargeErrorEnum.EXIST_IS_REVENUE_ERROR);
            }
            LoginUser loginUser = UserUtil.getCurrentUser();
            //插入营收数据
            monthRevenueDto.setCreateBy(loginUser.getUsername());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            monthRevenueDto.setCollectDate(sdf.parse(monthRevenueDto.getCollectDateString()));
            monthRevenueDto.setTenantId(loginUser.getTenantId());
            oneConvertWan(monthRevenueDto);

            MonthRevenueEntity revenueEntity = new MonthRevenueEntity();
            BeanCopyUtils.copyProperties(monthRevenueDto, revenueEntity, MonthSellwaterEntity.class);
            revenueService.insert(revenueEntity);
            //插入售水数据
            for (MonthSellwaterDto entity : monthRevenueDto.getMonthSellList()) {
                entity.setTenantId(loginUser.getTenantId());
                entity.setCreateBy(loginUser.getUsername());
                entity.setCompanyOrgId(monthRevenueDto.getCompanyOrgId());
                entity.setCollectDate(monthRevenueDto.getCollectDate());
                if(entity.getWaterUsage() != null){
                    entity.setWaterUsage(entity.getWaterUsage()/10000);
                }
                MonthSellwaterEntity entity1 = new MonthSellwaterEntity();
                BeanCopyUtils.copyProperties(entity, entity1, MonthSellwaterEntity.class);
                revenueService.insertSellWater(entity1);
            }
            return AjaxMessage.success( );
        }catch (Exception e){
            return AjaxMessage.fail(RespCodeEnum.ERROR_500);
        }

    }

    @RequestMapping(value = "updateRevenue", method = RequestMethod.POST)
    @ApiOperation(value = "修改营收数据")
    public AjaxMessage updateRevenue(@ApiParam(value = "营收数据", required = true) @RequestBody MonthRevenueDto monthRevenueDto) {
        try{
            // 判断该机构是否有该月的数据
            if (revenueService.isExistMonthRevenue(monthRevenueDto.getCompanyOrgId(),monthRevenueDto.getCollectDateString(),monthRevenueDto.getId())>0){
                return AjaxMessage.fail(ChargeErrorEnum.EXIST_IS_REVENUE_ERROR);
            }
            LoginUser loginUser = UserUtil.getCurrentUser();
            //修改营收数据
            monthRevenueDto.setUpdateBy(loginUser.getUsername());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            monthRevenueDto.setCollectDate(sdf.parse(monthRevenueDto.getCollectDateString()));
            oneConvertWan(monthRevenueDto);

            MonthRevenueEntity revenueEntity = new MonthRevenueEntity();
            BeanCopyUtils.copyProperties(monthRevenueDto, revenueEntity, MonthSellwaterEntity.class);
            revenueService.updateRevenue(revenueEntity);
            // 修改售水数据
            for (MonthSellwaterDto entity : monthRevenueDto.getMonthSellList()) {
                entity.setUpdateBy(loginUser.getUsername());
                entity.setCollectDate(sdf.parse(monthRevenueDto.getCollectDateString()));
                if(entity.getWaterUsage() != null){
                    entity.setWaterUsage(entity.getWaterUsage()/10000);
                }

                MonthSellwaterEntity entity1 = new MonthSellwaterEntity();
                BeanCopyUtils.copyProperties(entity, entity1, MonthSellwaterEntity.class);
                if(entity.getId() == null){
                    entity1.setTenantId(loginUser.getTenantId());
                    entity1.setCreateBy(loginUser.getUsername());
                    entity1.setCompanyOrgId(monthRevenueDto.getCompanyOrgId());
                    revenueService.insertSellWater(entity1);
                }else{
                    revenueService.updateSellWater(entity1);
                }
            }
            return AjaxMessage.success();
        }catch (Exception e){
            return AjaxMessage.success(RespCodeEnum.ERROR_500);
        }
    }

    public void oneConvertWan(MonthRevenueDto monthRevenueDto){
        if(monthRevenueDto.getBigUserUsage() != null){
            monthRevenueDto.setBigUserUsage(monthRevenueDto.getBigUserUsage()/10000);
        }
        if(monthRevenueDto.getGeneralUserUsage() != null){
            monthRevenueDto.setGeneralUserUsage(monthRevenueDto.getGeneralUserUsage()/10000);
        }
        if(monthRevenueDto.getReceivableTotalAmount() != null){
            monthRevenueDto.setReceivableTotalAmount(monthRevenueDto.getReceivableTotalAmount()/10000);
        }
        if(monthRevenueDto.getBigUserUsageReceived() != null){
            monthRevenueDto.setBigUserUsageReceived(monthRevenueDto.getBigUserUsageReceived()/10000);
        }
        if(monthRevenueDto.getGeneralUserUsageReceived() != null){
            monthRevenueDto.setGeneralUserUsageReceived(monthRevenueDto.getGeneralUserUsageReceived()/10000);
        }
        if(monthRevenueDto.getReceivedTotalAmount() != null){
            monthRevenueDto.setReceivedTotalAmount(monthRevenueDto.getReceivedTotalAmount()/10000);
        }
        if(monthRevenueDto.getMeterReadingUsage() != null){
            monthRevenueDto.setMeterReadingUsage(monthRevenueDto.getMeterReadingUsage()/10000);
        }
    }

    @RequestMapping(value = "selectList", method = RequestMethod.POST)
    @ApiOperation(value = "查询营收数据列表")
    public AjaxMessage selectList(@RequestBody @Valid RevenueDto dto) {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(dto.getCompanyOrgId());
        monthRevenueDto.setStartDate(dto.getStartDate());
        monthRevenueDto.setEndDate(dto.getEndDate());
        return AjaxMessage.success( revenueService.selectList(monthRevenueDto));
    }

    @RequestMapping(value = "selectPage", method = RequestMethod.POST)
    @ApiOperation(value = "分页查询营收数据列表")
    public AjaxMessage selectPage(@RequestBody @Valid RevenuePageDto dto) {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(dto.getCompanyOrgId());
        monthRevenueDto.setStartDate(dto.getStartDate());
        monthRevenueDto.setEndDate(dto.getEndDate());
        List<MonthRevenueVo> result = revenueService.selectList(monthRevenueDto);
        Pagination<MonthRevenueVo> pages = new Pagination<>();
        pages.setTotal(result.size());
        if((dto.getPageNum()-1) * dto.getPageSize() < result.size()){
            pages.setList(result.subList((dto.getPageNum()-1)*dto.getPageSize(),dto.getPageNum()*dto.getPageSize()<result.size()?dto.getPageNum()*dto.getPageSize():result.size()));
        }
        return AjaxMessage.success(pages);
    }

    @RequestMapping(value = "exportList", method = RequestMethod.GET)
    @ApiOperation(value = "导出营收数据")
    public void exportList(RevenueDto dto, HttpServletResponse response) throws Exception {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(dto.getCompanyOrgId());
        monthRevenueDto.setStartDate(dto.getStartDate());
        monthRevenueDto.setEndDate(dto.getEndDate());
        List<MonthRevenueVo> result = revenueService.selectList(monthRevenueDto);
        List<WaterPropertyEntity> waterPropertyList=waterPropertyService.select(dto.getCompanyOrgId());
        String[] title = {"NO.","时间","售水(m³):总售水","应收(元):总计","应收(元):大用户","应收(元):普通用户","实收(元):总计","实收(元):大用户","实收(元):普通用户"};
        List<List<String>> reportTitle =new ArrayList<>();
        for(String item : title){
            List<String> list=new ArrayList<>();
            if(item.contains(":")){
                list.add(item.split(":")[0]);
                list.add(item.split(":")[1]);
                reportTitle.add(list);
                if(item.contains("售水")){
                    for(WaterPropertyEntity water :waterPropertyList){
                        list=new ArrayList<>();
                        list.add(item.split(":")[0]);
                        list.add(water.getPropertyName());
                        reportTitle.add(list);
                    }
                }
            }else{
                list.add(item);
                reportTitle.add(list);
            }
        }
        int no=1;
        List<List<String>> excelResult=new  ArrayList<>();
        DecimalFormat df = new DecimalFormat("0.###");
        for(MonthRevenueVo item : result){
            List<String> datalist=new ArrayList<>();
            datalist.add(String.valueOf(no++));
            datalist.add(item.getCollectDateString().replace("-","年")+"月");
            datalist.add(item.getMeterReadingUsage()==null?"-":df.format(item.getMeterReadingUsage()));
            for(WaterPropertyEntity water :waterPropertyList){
                List<MonthSellwaterVo> sellWaterList = item.getMonthSellList().stream().filter((MonthSellwaterVo m)
                        -> m.getPropertyId().equals(water.getId())).collect(Collectors.toList());
                if(sellWaterList.size()>0){
                    datalist.add(sellWaterList.get(0).getWaterUsage()==null?"-":df.format(sellWaterList.get(0).getWaterUsage()));
                }else{
                    datalist.add("-");
                }
            }
            datalist.add(item.getReceivableTotalAmount()==null?"-":df.format(item.getReceivableTotalAmount()));
            datalist.add(item.getBigUserUsage()==null?"-":df.format(item.getBigUserUsage()));
            datalist.add(item.getGeneralUserUsage()==null?"-":df.format(item.getGeneralUserUsage()));
            datalist.add(item.getReceivedTotalAmount()==null?"-":df.format(item.getReceivedTotalAmount()));
            datalist.add(item.getBigUserUsageReceived()==null?"-":df.format(item.getBigUserUsageReceived()));
            datalist.add(item.getGeneralUserUsageReceived()==null?"-":df.format(item.getGeneralUserUsageReceived()));
            excelResult.add(datalist);
        }
        EasyExcelUtil.excelWriteWithHeader(response, "营收报表", reportTitle, excelResult);
    }
}