package com.zcxk.controller;

import com.zcxk.dto.*;
import com.zcxk.entity.*;
import com.zcxk.model.AjaxMessage;
import com.zcxk.model.LoginUser;
import com.zcxk.model.Pagination;
import com.zcxk.model.ResultStatus;
import com.zcxk.service.RevenueService;
import com.zcxk.service.WaterPropertyService;
import com.zcxk.util.ExcelUtil;
import com.zcxk.util.OrgInfoUtil;
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.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

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;

    @Autowired
    private RestTemplate restTemplate;

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

    @Autowired
    private WaterPropertyService waterPropertyService;
    /**
     * 查询本月售水信息
     *
     * @param companyOrgId
     * @return
     */
    @RequestMapping(value = "selectMonthSell", method = RequestMethod.GET)
    @ApiOperation(value = "查询本月售水信息")
    public AjaxMessage<List<MonthSellwaterDto>> selectMonthSell(
            @ApiParam(value = "公司机构id", required = false)@RequestParam(required = false) Integer companyOrgId) {
        List<MonthSellwaterDto> result = revenueService.selectMonthSell(companyOrgId);
        return new AjaxMessage<>(ResultStatus.OK, result);
    }
    /**
     * 查询近6个月总售水量
     *
     * @param companyOrgId
     * @return
     */
    @RequestMapping(value = "selectMonthSellTotal", method = RequestMethod.GET)
    @ApiOperation(value = "查询近6个月总售水量")
    public AjaxMessage<List<MonthSellwaterDto>> selectMonthSellTotal(
            @ApiParam(value = "公司机构id", required = false)@RequestParam(required = false) Integer companyOrgId) {
        List<MonthSellwaterDto> result = revenueService.selectMonthSellTotal(companyOrgId);
        return new AjaxMessage<>(ResultStatus.OK, result);
    }
    /**
     * 查询月营收情况
     *
     * @param companyOrgId
     * @return
     */
    @RequestMapping(value = "selectMonthRevenue", method = RequestMethod.GET)
    @ApiOperation(value = "查询月营收情况")
    public AjaxMessage<List<MonthRevenueDto>> selectMonthRevenue(
            @ApiParam(value = "近几月", required = true)@RequestParam Integer months,
            @ApiParam(value = "公司机构id", required = false)@RequestParam(required = false) Integer companyOrgId) {
        List<MonthRevenueDto> result = revenueService.selectMonthRevenue(companyOrgId,months);
        return new AjaxMessage<>(ResultStatus.OK, result);
    }
    /**
     * 查询本月各分公司的营收情况
     *
     * @return
     */
    @RequestMapping(value = "selectCompanyRevenue", method = RequestMethod.GET)
    @ApiOperation(value = "查询本月各分公司的营收情况")
    public AjaxMessage<List<MonthRevenueDto>> selectCompanyRevenue() {
        List<MonthRevenueDto> result = revenueService.selectCompanyRevenue();
        for(MonthRevenueDto revenue : result){
            revenue.setCompanyOrgName(orgInfoUtil.getOrgName(revenue.getCompanyOrgId()));
        }
        return new AjaxMessage<>(ResultStatus.OK, result);
    }
    /**
     * 同步水表数量
     *
     * @return
     */
    @RequestMapping(value = "syncMeterCount", method = RequestMethod.GET)
    @ApiOperation(value = "同步水表数量")
    public AjaxMessage<Integer> syncMeterCount() {
        revenueService.syncMeterCount();
        return new AjaxMessage<>(ResultStatus.OK);
    }
    /**
     * 新增营收数据
     *
     * @return
     */
    @RequestMapping(value = "addRevenue", method = RequestMethod.POST)
    @ApiOperation(value = "新增营收数据")
    public AjaxMessage<Integer> addRevenue(
            @ApiParam(value = "营收数据", required = true) @RequestBody MonthRevenueDto monthRevenueDto) {
        try{
            //判断该机构是否有该月的数据
            if(revenueService.isExistMonthRevenue(monthRevenueDto.getCompanyOrgId(),monthRevenueDto.getCollectDateString(),null)>0){
                return new AjaxMessage<>(ResultStatus.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);
            revenueService.insert(monthRevenueDto);
            //插入售水数据
            for (MonthSellwaterEntity 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);
                }
                revenueService.insertSellWater(entity);
            }
            return new AjaxMessage<>(ResultStatus.OK);
        }catch (Exception e){
            return new AjaxMessage<>(ResultStatus.ERROR);
        }

    }
    /**
     * 修改营收数据
     *
     * @return
     */
    @RequestMapping(value = "updateRevenue", method = RequestMethod.POST)
    @ApiOperation(value = "修改营收数据")
    public AjaxMessage<Integer> updateRevenue(
            @ApiParam(value = "营收数据", required = true) @RequestBody MonthRevenueDto monthRevenueDto) {
        try{
            //判断该机构是否有该月的数据
            if(revenueService.isExistMonthRevenue(monthRevenueDto.getCompanyOrgId(),monthRevenueDto.getCollectDateString(),monthRevenueDto.getId())>0){
                return new AjaxMessage<>(ResultStatus.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);
            revenueService.updateRevenue(monthRevenueDto);
            //修改售水数据
            for (MonthSellwaterEntity entity : monthRevenueDto.getMonthSellList()) {
                entity.setUpdateBy(loginUser.getUsername());
                entity.setCollectDate(sdf.parse(monthRevenueDto.getCollectDateString()));
                if(entity.getWaterUsage() != null){
                    entity.setWaterUsage(entity.getWaterUsage()/10000);
                }
                if(entity.getId() == null){
                    entity.setTenantId(loginUser.getTenantId());
                    entity.setCreateBy(loginUser.getUsername());
                    entity.setCompanyOrgId(monthRevenueDto.getCompanyOrgId());
                    revenueService.insertSellWater(entity);
                }else{
                    revenueService.updateSellWater(entity);
                }
            }
            return new AjaxMessage<>(ResultStatus.OK);
        }catch (Exception e){
            return new AjaxMessage<>(ResultStatus.ERROR);
        }
    }
    /**
     * 将营收数据转换成万
     *
     */
    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);
        }
    }
    /**
     * 查询营收数据列表
     *
     * @return
     */
    @RequestMapping(value = "selectList", method = RequestMethod.GET)
    @ApiOperation(value = "查询营收数据列表")
    public AjaxMessage<List<MonthRevenueDto>> selectList(
            @ApiParam(value = "公司机构id", required = true)@RequestParam Integer companyOrgId,
            @ApiParam(value = "开始日期(yyyy-MM)", required = true)@RequestParam String startDate,
            @ApiParam(value = "结束日期(yyyy-MM)", required = true)@RequestParam String endDate) {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(companyOrgId);
        monthRevenueDto.setStartDate(startDate);
        monthRevenueDto.setEndDate(endDate);
        List<MonthRevenueDto> result = revenueService.selectList(monthRevenueDto);
        return new AjaxMessage<>(ResultStatus.OK, result);
    }
    /**
     * 分页查询营收数据列表
     *
     * @return
     */
    @RequestMapping(value = "selectPage", method = RequestMethod.GET)
    @ApiOperation(value = "分页查询营收数据列表")
    public AjaxMessage<Pagination<MonthRevenueDto>> selectPage(
            @ApiParam(value = "页数", required = true) @RequestParam Integer pageNum,
            @ApiParam(value = "条数", required = true) @RequestParam Integer pageSize,
            @ApiParam(value = "公司机构id", required = true)@RequestParam Integer companyOrgId,
            @ApiParam(value = "开始日期(yyyy-MM)", required = true)@RequestParam String startDate,
            @ApiParam(value = "结束日期(yyyy-MM)", required = true)@RequestParam String endDate) {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(companyOrgId);
        monthRevenueDto.setStartDate(startDate);
        monthRevenueDto.setEndDate(endDate);
        List<MonthRevenueDto> result = revenueService.selectList(monthRevenueDto);
        Pagination<MonthRevenueDto> pages = new Pagination<>();
        pages.setTotal(result.size());
        if((pageNum-1)*pageSize<result.size()){
            pages.setList(result.subList((pageNum-1)*pageSize,pageNum*pageSize<result.size()?pageNum*pageSize:result.size()));
        }
        return new AjaxMessage<>(ResultStatus.OK, pages);
    }
    /**
     * 导出营收数据
     *
     * @return
     */
    @RequestMapping(value = "exportList", method = RequestMethod.GET)
    @ApiOperation(value = "导出营收数据")
    public AjaxMessage<String> exportList(
            @ApiParam(value = "公司机构id", required = true)@RequestParam Integer companyOrgId,
            @ApiParam(value = "开始日期(yyyy-MM)", required = true)@RequestParam String startDate,
            @ApiParam(value = "结束日期(yyyy-MM)", required = true)@RequestParam String endDate) {
        MonthRevenueDto monthRevenueDto=new MonthRevenueDto();
        monthRevenueDto.setCompanyOrgId(companyOrgId);
        monthRevenueDto.setStartDate(startDate);
        monthRevenueDto.setEndDate(endDate);
        List<MonthRevenueDto> result = revenueService.selectList(monthRevenueDto);
        List<WaterPropertyEntity> waterPropertyList=waterPropertyService.select(companyOrgId);

        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(MonthRevenueDto 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<MonthSellwaterEntity> sellWaterList = item.getMonthSellList().stream().filter((MonthSellwaterEntity 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);
        }
        String filePath = ExcelUtil.writeSimpleExcelWithHeader(baseDir,"营收报表",reportTitle,excelResult);
        return new AjaxMessage<>(ResultStatus.OK, filePath);
    }
}