package com.slodon.b2b2c.controller.statistics.admin;

import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.ProvinceJson;
import com.slodon.b2b2c.enums.StatsTimeType;
import com.slodon.b2b2c.model.statistics.ProvinceDayModel;
import com.slodon.b2b2c.statistics.example.ProvinceDayExample;
import com.slodon.b2b2c.statistics.pojo.base.ProvinceBase;
import com.slodon.b2b2c.util.StatsModelUtil;
import com.slodon.b2b2c.vo.statistics.ProvinceRiseTrendVO;
import com.slodon.b2b2c.vo.statistics.RegionReportVO;
import com.slodon.b2b2c.vo.statistics.SalesPercentVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Api(tags = "admin-地域分析")
@RestController
@RequestMapping("v3/statistics/admin/region/analysis")
public class AdminRegionAnalysisController extends BaseController {

    @Resource
    private ProvinceDayModel provinceDayModel;
    @Resource
    private StatsModelUtil statsModelUtil;

    @ApiOperation("各省份支付金额占比")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("payAmountPercent")
    public JsonResult<SalesPercentVO> payAmountPercent(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends ProvinceBase> list;
        if (timeType.equals(StatsTimeType.DAY)) {
            ProvinceDayExample example = new ProvinceDayExample();
            example.setStatsTimeAfter(startTime);
            example.setStatsTimeBefore(endTime);
            example.setOrderBy("orderPayAmount desc");
            list = provinceDayModel.getProvincePercentList(example);
        } else {
            list = statsModelUtil.getProvinceList(timeType, startTime, endTime, 1);
        }
        SalesPercentVO vo = getPayAmountPercent(list);
        return SldResponse.success(vo);
    }

    @ApiOperation("各省份增长趋势")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("provinceRiseTrend")
    public JsonResult<List<ProvinceRiseTrendVO>> provinceRiseTrend(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends ProvinceBase> list;
        if (timeType.equals(StatsTimeType.DAY)) {
            ProvinceDayExample example = new ProvinceDayExample();
            example.setStatsTimeAfter(startTime);
            example.setStatsTimeBefore(endTime);
            example.setOrderBy("provinceCode asc");
            list = provinceDayModel.getProvincePercentList(example);
        } else {
            list = statsModelUtil.getProvinceList(timeType, startTime, endTime, 1);
        }
        List<ProvinceRiseTrendVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(provinceBase -> {
                ProvinceRiseTrendVO vo = new ProvinceRiseTrendVO();
                vo.setProvinceCode(provinceBase.getProvinceCode());
                vo.setProvinceName(provinceBase.getProvinceName());
                vo.setMemberNum(provinceBase.getNewMemberNum());
                vo.setStoreNum(provinceBase.getNewStoreNum());
                vos.add(vo);
            });
        } else {
            ProvinceJson.provinceMap.forEach((code, name) -> {
                ProvinceRiseTrendVO vo = new ProvinceRiseTrendVO();
                vo.setProvinceCode(code);
                vo.setProvinceName(name);
                vo.setMemberNum(0);
                vo.setStoreNum(0);
                vos.add(vo);
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("地域概况报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "provinceName", value = "省份名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderPayAmount-支付金额;orderSubmitAmount-下单金额;" +
                    "orderPayNum-支付订单数;orderSubmitNum-下单数;newMemberNum-新增会员数;newStoreNum-新增店铺数;" +
                    "returnNum-退单数;returnAmount-退单金额;默认按支付金额降序排序")
    })
    @GetMapping("regionReport")
    public JsonResult<List<RegionReportVO>> regionReport(HttpServletRequest request, Date startTime, Date endTime, String provinceName,
                                                         @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                         @RequestParam(value = "sort", required = false, defaultValue = "orderPayAmount") String sort) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        ProvinceDayExample example = new ProvinceDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setProvinceNameLike(provinceName);
        example.setOrderBy(sort + " " + type);
        List<ProvinceBase> list = provinceDayModel.getProvincePercentList(example);
        List<RegionReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(provinceBase -> {
                vos.add(new RegionReportVO(provinceBase));
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("导出报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "provinceName", value = "省份名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderPayAmount-支付金额;orderSubmitAmount-下单金额;" +
                    "orderPayNum-支付订单数;orderSubmitNum-下单数;newMemberNum-新增会员数;newStoreNum-新增店铺数;" +
                    "returnNum-退单数;returnAmount-退单金额;默认按支付金额降序排序"),
    })
    @GetMapping("export")
    public JsonResult export(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime, String provinceName,
                             @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                             @RequestParam(value = "sort", required = false, defaultValue = "orderPayAmount") String sort) {
        ProvinceDayExample example = new ProvinceDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setProvinceNameLike(provinceName);
        example.setOrderBy(sort + " " + type);
        provinceDayModel.reportExport(request, response, example);
        return null;
    }

    /**
     * 各省份支付金额占比
     *
     * @param list
     * @return
     */
    public SalesPercentVO getPayAmountPercent(List<? extends ProvinceBase> list) {
        SalesPercentVO result = new SalesPercentVO();
        //支付金额列表
        List<SalesPercentVO.OrderPayAmountVO> orderAmountList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总支付金额，用于计算各省份占比
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (ProvinceBase provinceBase : list) {
                totalAmount = totalAmount.add(provinceBase.getOrderPayAmount());
            }
            //如果为0直接返回空数组
            if (totalAmount.compareTo(BigDecimal.ZERO) == 0) {
                return result;
            }

            //循环列表,构造返回数据
            if (list.size() <= 10) {
                //省份少于等于10个，直接记录各省份的支付占比
                for (ProvinceBase provinceBase : list) {
                    if (provinceBase.getOrderPayAmount().compareTo(BigDecimal.ZERO) != 0) {
                        SalesPercentVO.OrderPayAmountVO vo = new SalesPercentVO.OrderPayAmountVO();
                        vo.setProvinceName(provinceBase.getProvinceName());
                        vo.setOrderPayAmount(provinceBase.getOrderPayAmount());
                        BigDecimal per = provinceBase.getOrderPayAmount().multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                        vo.setOrderAmountPercent(per.toString() + "%");
                        orderAmountList.add(vo);
                    }
                }
            } else {
                //省份大于10，记录前10个，剩余记为其他
                //其他省份支付金额
                BigDecimal otherAmount = totalAmount;
                //其他省份占比
                BigDecimal otherPer = new BigDecimal(100);
                for (int i = 0; i < list.size() && i < 10; i++) {
                    ProvinceBase provinceBase = list.get(i);

                    BigDecimal orderPayAmount = provinceBase.getOrderPayAmount();

                    if (orderPayAmount.compareTo(BigDecimal.ZERO) != 0) {
                        SalesPercentVO.OrderPayAmountVO vo = new SalesPercentVO.OrderPayAmountVO();
                        vo.setProvinceName(provinceBase.getProvinceName());
                        vo.setOrderPayAmount(orderPayAmount);
                        BigDecimal per = orderPayAmount.multiply(new BigDecimal(100)).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);
                        vo.setOrderAmountPercent(per.toString() + "%");
                        orderAmountList.add(vo);

                        //数据计算
                        otherAmount = otherAmount.subtract(orderPayAmount);
                        otherPer = otherPer.subtract(per);
                    }
                }
                //其他
                if (otherAmount.compareTo(BigDecimal.ZERO) > 0) {
                    SalesPercentVO.OrderPayAmountVO payAmountVO = new SalesPercentVO.OrderPayAmountVO();
                    payAmountVO.setProvinceName("其他");
                    payAmountVO.setOrderPayAmount(otherAmount);
                    payAmountVO.setOrderAmountPercent(otherPer.toString() + "%");
                    orderAmountList.add(payAmountVO);
                }
            }
            result.setOrderAmountList(orderAmountList);
        }
        return result;
    }
}
