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.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.StatsTimeType;
import com.slodon.b2b2c.model.statistics.PlatformDayModel;
import com.slodon.b2b2c.model.statistics.StoreDayModel;
import com.slodon.b2b2c.model.statistics.TerminalDayModel;
import com.slodon.b2b2c.statistics.example.PlatformDayExample;
import com.slodon.b2b2c.statistics.example.StoreDayExample;
import com.slodon.b2b2c.statistics.example.TerminalDayExample;
import com.slodon.b2b2c.statistics.pojo.PlatformDay;
import com.slodon.b2b2c.statistics.pojo.base.GoodsBase;
import com.slodon.b2b2c.statistics.pojo.base.PlatformBase;
import com.slodon.b2b2c.statistics.pojo.base.StoreBase;
import com.slodon.b2b2c.statistics.pojo.base.TerminalBase;
import com.slodon.b2b2c.util.StatsModelUtil;
import com.slodon.b2b2c.vo.statistics.*;
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/flow/analysis")
public class AdminFlowAnalysisController extends BaseController {

    @Resource
    private PlatformDayModel platformDayModel;
    @Resource
    private TerminalDayModel terminalDayModel;
    @Resource
    private StoreDayModel storeDayModel;
    @Resource
    private StatsModelUtil statsModelUtil;

    @ApiOperation("流量总览")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "terminalType", value = "终端类型：Android,IOS,pc,H5,xcx 默认全部不传")
    })
    @GetMapping("flowOverview")
    public JsonResult<FlowOverviewVO> flowOverview(HttpServletRequest request, String webSite, Date startTime, Date endTime, String terminalType) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        //上期开始时间和结束时间
        Date preStartTime;
        Date preEndTime;
        int differentDay = StatsTimeType.getDifferentDay(startTime, endTime);
        if (timeType == StatsTimeType.DAY && differentDay != 1) {
            preStartTime = StatsTimeType.getPreStartTime(startTime, differentDay);
            preEndTime = StatsTimeType.getPreEndTime(endTime, differentDay);
        } else {
            preStartTime = StatsTimeType.getStartTime(startTime, timeType);
            preEndTime = StatsTimeType.getEndTime(endTime, timeType);
        }
        FlowOverviewVO vo = new FlowOverviewVO();
        if (!StringUtil.isEmpty(terminalType)) {
            //终端类型不为空，查询终端数据
            List<? extends TerminalBase> list = statsModelUtil.getTerminalList(timeType, startTime, endTime, terminalType);
            if (!CollectionUtils.isEmpty(list)) {
                TerminalBase terminalBase = list.get(0);
                //上期数据
                TerminalBase previousData = null;
                if (preStartTime != null) {
                    List<? extends TerminalBase> previousList = statsModelUtil.getTerminalList(timeType, preStartTime, preEndTime, terminalType);
                    if (!CollectionUtils.isEmpty(previousList)) {
                        previousData = previousList.get(0);
                    }
                }
                if (terminalBase != null) {
                    vo = new FlowOverviewVO(terminalBase, previousData);
                }
            }
        } else {
            //终端类型为空，查询平台数据
            List<? extends PlatformBase> list = statsModelUtil.getPlatformList(timeType,webSite, startTime, endTime);
            if (!CollectionUtils.isEmpty(list)) {
                PlatformBase platformBase = list.get(0);
                //上期数据
                PlatformBase previousData = null;
                if (preStartTime != null) {
                    List<? extends PlatformBase> previousList = statsModelUtil.getPlatformList(timeType,webSite, preStartTime, preEndTime);
                    if (!CollectionUtils.isEmpty(previousList)) {
                        previousData = previousList.get(0);
                    }
                }
                if (platformBase != null) {
                    vo = new FlowOverviewVO(platformBase, previousData);
                }
            }
        }
        return SldResponse.success(vo);
    }

    @ApiOperation("各终端浏览量占比")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("terminalViewNumPercent")
    public JsonResult<List<TerminalPercentVO>> terminalViewNumPercent(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends TerminalBase> list;
        if (timeType.equals(StatsTimeType.DAY)) {
            TerminalDayExample example = new TerminalDayExample();
            example.setStatsTimeAfter(startTime);
            example.setStatsTimeBefore(endTime);
            list = terminalDayModel.getTerminalPercentList(example);
        } else {
            list = statsModelUtil.getTerminalList(timeType, startTime, endTime, null);
        }
        List<TerminalPercentVO> vos = getTerminalViewNumPercent(list);
        return SldResponse.success(vos);
    }

    @ApiOperation("各终端访客数占比")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true)
    })
    @GetMapping("terminalVisitorNumPercent")
    public JsonResult<List<TerminalPercentVO>> terminalVisitorNumPercent(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends TerminalBase> list;
        if (timeType.equals(StatsTimeType.DAY)) {
            TerminalDayExample example = new TerminalDayExample();
            example.setStatsTimeAfter(startTime);
            example.setStatsTimeBefore(endTime);
            list = terminalDayModel.getTerminalPercentList(example);
        } else {
            list = statsModelUtil.getTerminalList(timeType, startTime, endTime, null);
        }
        List<TerminalPercentVO> vos = getTerminalVisitorNumPercent(list);
        return SldResponse.success(vos);
    }

    @ApiOperation("店铺流量排行-TOP10")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "sort", value = "排序:1-浏览量；2-访客数 默认不传按浏览量降序")
    })
    @GetMapping("storeFlowRank")
    public JsonResult<List<StoreRankVO>> storeFlowRank(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(name = "webSite", required = false,defaultValue = "1") String webSite, Integer sort) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        //默认查询前十条数据
        PagerInfo pager = new PagerInfo(10, 1);
        List<? extends StoreBase> list = statsModelUtil.getStoreList(timeType, startTime, endTime, webSite, sort, "flow", null, pager);
        List<StoreRankVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(storeBase -> {
                //浏览量和访客数二者必须有一个满足条件
                if (storeBase.getViewNum() > 0 || storeBase.getVisitorNum() > 0) {
                    vos.add(new StoreRankVO(storeBase.getStoreId(), storeBase.getStoreName(), storeBase.getViewNum(), storeBase.getVisitorNum()));
                }
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("商品流量排行-TOP10")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "sort", value = "排序:1-浏览量；2-访客数 默认不传按浏览量降序")
    })
    @GetMapping("goodsFlowRank")
    public JsonResult<List<GoodsRankVO>> goodsFlowRank(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(name = "webSite", required = false,defaultValue = "1") String webSite,Integer sort) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends GoodsBase> list = statsModelUtil.getGoodsList(timeType, startTime, endTime, webSite, sort, "flow", null);
        List<GoodsRankVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(goodsBase -> {
                //浏览量和访客数二者必须有一个满足条件
                if (goodsBase.getViewNum() > 0 || goodsBase.getVisitorNum() > 0) {
                    vos.add(new GoodsRankVO(goodsBase.getGoodsId(), goodsBase.getGoodsName(), goodsBase.getGoodsImage(), goodsBase.getViewNum(), goodsBase.getVisitorNum()));
                }
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("流量报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;visitor_num-平台访客数;view_num-平台浏览量;" +
                    "store_visitor_num-店铺访客数;store_view_num-店铺浏览量;goods_visitor_num-商品访客数;goods_view_num-商品浏览量;默认按时间降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("flowReport")
    public JsonResult<PageVO<FlowReportVO>> flowReport(HttpServletRequest request,
                                                       @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                       Date startTime, Date endTime,
                                                       @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                       @RequestParam(value = "sort", required = false, defaultValue = "stats_time") String sort) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        PlatformDayExample example = new PlatformDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setOrderBy(sort + " " + type);
        example.setWebSite(webSite);
        List<PlatformDay> list = platformDayModel.getPlatformDayList(example, pager);
        List<FlowReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(platformDay -> {
                vos.add(new FlowReportVO(platformDay));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("流量报表(按店铺)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "storeName", value = "店铺名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:visitorNum-店铺访客数;viewNum-店铺浏览量;goodsVisitorNum-商品访客数;" +
                    "goodsViewNum-商品浏览量;默认按店铺访客数降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("storeReport")
    public JsonResult<PageVO<AdminFlowReportVO>> storeReport(HttpServletRequest request, Date startTime, Date endTime, String storeName,
                                                             @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                             @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                             @RequestParam(value = "sort", required = false, defaultValue = "visitorNum") String sort) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        StoreDayExample example = new StoreDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setStoreNameLike(storeName);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        List<StoreBase> list = storeDayModel.getStoreList(example, pager);
        List<AdminFlowReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(storeBase -> {
                vos.add(new AdminFlowReportVO(storeBase));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("导出报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;visitor_num-平台访客数;view_num-平台浏览量;" +
                    "store_visitor_num-店铺访客数;store_view_num-店铺浏览量;goods_visitor_num-商品访客数;goods_view_num-商品浏览量;默认按时间降序排序")
    })
    @GetMapping("dayExport")
    public JsonResult dayExport(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime,
                                @RequestParam(value = "webSite", required = false, defaultValue = "1")String webSite,
                                @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                @RequestParam(value = "sort", required = false, defaultValue = "stats_time") String sort) {
        PlatformDayExample example = new PlatformDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        platformDayModel.flowReportExport(request, response, example);
        return null;
    }

    @ApiOperation("导出报表(按店铺)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "storeName", value = "店铺名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:visitorNum-店铺访客数;viewNum-店铺浏览量;goodsVisitorNum-商品访客数;" +
                    "goodsViewNum-商品浏览量;默认按店铺访客数降序排序")
    })
    @GetMapping("storeExport")
    public JsonResult storeExport(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime, String storeName,
                                  @RequestParam(value = "webSite", required = false, defaultValue = "1")String webSite,
                                  @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                  @RequestParam(value = "sort", required = false, defaultValue = "visitorNum") String sort) {
        StoreDayExample example = new StoreDayExample();
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setStoreNameLike(storeName);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        storeDayModel.storeFlowReportExport(request, response, example);
        return null;
    }

    /**
     * 各终端访客数占比
     *
     * @param list
     * @return
     */
    public List<TerminalPercentVO> getTerminalVisitorNumPercent(List<? extends TerminalBase> list) {
        List<TerminalPercentVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总访客数，用于计算各终端占比
            Integer totalNum = 0;
            for (TerminalBase terminalBase : list) {
                totalNum += terminalBase.getVisitorNum();
            }
            //如果为0直接返回空数组
            if (totalNum == 0) {
                return result;
            }
            for (TerminalBase terminalBase : list) {
                TerminalPercentVO vo = new TerminalPercentVO();
                vo.setTerminalName(terminalBase.getTerminalName());
                vo.setVisitorNum(terminalBase.getVisitorNum());
                BigDecimal numPer = new BigDecimal(terminalBase.getVisitorNum()).multiply(new BigDecimal(100)).divide(new BigDecimal(totalNum), 2, BigDecimal.ROUND_HALF_UP);
                vo.setVisitorNumPercent(numPer.toString() + "%");
                result.add(vo);
            }
        }
        return result;
    }

    /**
     * 各终端浏览量占比
     *
     * @param list
     * @return
     */
    public List<TerminalPercentVO> getTerminalViewNumPercent(List<? extends TerminalBase> list) {
        List<TerminalPercentVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            //总浏览量，用于计算各终端占比
            Integer totalNum = 0;
            for (TerminalBase terminalBase : list) {
                totalNum += terminalBase.getViewNum();
            }
            //如果为0直接返回空数组
            if (totalNum == 0) {
                return result;
            }
            for (TerminalBase terminalBase : list) {
                TerminalPercentVO vo = new TerminalPercentVO();
                vo.setTerminalName(terminalBase.getTerminalName());
                vo.setViewNum(terminalBase.getViewNum());
                BigDecimal numPer = new BigDecimal(terminalBase.getViewNum()).multiply(new BigDecimal(100)).divide(new BigDecimal(totalNum), 2, BigDecimal.ROUND_HALF_UP);
                vo.setViewNumPercent(numPer.toString() + "%");
                result.add(vo);
            }
        }
        return result;
    }
}
