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

import com.slodon.b2b2c.business.example.OrderExample;
import com.slodon.b2b2c.core.constant.OrderConst;
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.UserUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.enums.StatsTimeType;
import com.slodon.b2b2c.model.business.OrderModel;
import com.slodon.b2b2c.model.statistics.MemberStoreDayModel;
import com.slodon.b2b2c.model.statistics.StoreDayModel;
import com.slodon.b2b2c.seller.pojo.Vendor;
import com.slodon.b2b2c.statistics.example.MemberStoreDayExample;
import com.slodon.b2b2c.statistics.example.StoreDayExample;
import com.slodon.b2b2c.statistics.pojo.StoreDay;
import com.slodon.b2b2c.statistics.pojo.base.GoodsBase;
import com.slodon.b2b2c.statistics.pojo.base.MemberStoreBase;
import com.slodon.b2b2c.statistics.pojo.base.StoreBase;
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.util.*;

@Api(tags = "seller-用户分析")
@RestController
@RequestMapping("v3/statistics/seller/member/analysis")
public class SellerMemberAnalysisController extends BaseController {

    @Resource
    private StoreDayModel storeDayModel;
    @Resource
    private MemberStoreDayModel memberStoreDayModel;
    @Resource
    private StatsModelUtil statsModelUtil;
    @Resource
    private OrderModel orderModel;

    @ApiOperation("用户总览(用户总数)")
    @GetMapping("memberNum")
    public JsonResult memberNum(HttpServletRequest request,@RequestParam(name = "webSite", required = false,defaultValue ="1") String webSite) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        //查询用户总数，在本店有过支付行为的会员数
        OrderExample example = new OrderExample();
        example.setOrderStateIn(OrderConst.ORDER_STATE_20 + "," + OrderConst.ORDER_STATE_30 + "," + OrderConst.ORDER_STATE_40);
        example.setStoreId(vendor.getStoreId());
        Map<String, Integer> map = new HashMap<>();
        map.put("memberNum", orderModel.countGroupFieldsByExample("member_id", example));
        return SldResponse.success(map);
    }

    @ApiOperation("用户总览")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点")
    })
    @GetMapping("goodsOverview")
    public JsonResult<MemberOverviewVO> goodsOverview(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(name = "webSite", required = false,defaultValue = "1") String webSite) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        MemberOverviewVO vo = new MemberOverviewVO();
        List<? extends StoreBase> list = statsModelUtil.getStoreList(timeType, startTime, endTime, webSite, 1, "sale", vendor.getStoreId(), null);
        if (!CollectionUtils.isEmpty(list)) {
            StoreBase storeBase = list.get(0);
            //上期数据
            StoreBase previousData = null;
            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);
            }
            if (preStartTime != null) {
                List<? extends StoreBase> previousList = statsModelUtil.getStoreList(timeType, preStartTime, preEndTime, webSite,1, "sale", vendor.getStoreId(), null);
                if (!CollectionUtils.isEmpty(previousList)) {
                    previousData = previousList.get(0);
                }
            }
            if (storeBase != null) {
                vo = new MemberOverviewVO(storeBase, previousData);
            }
        }
        return SldResponse.success(vo);
    }

    @ApiOperation("变化趋势")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点")
    })
    @GetMapping("changeTrend")
    public JsonResult<List<SalesTrendVO>> changeTrend(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(value = "webSite",required = false,defaultValue = "1") String webSite) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
        List<MovableGoodsVO> list = statsModelUtil.getStoreTrendList(timeType, startTime, endTime, webSite, vendor.getStoreId());
        List<SalesTrendVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(goodsVO -> {
                vos.add(new SalesTrendVO(goodsVO.getStatsTime(), goodsVO.getNewMemberNum(), goodsVO.getVisitorNum(),
                        goodsVO.getOrderSubmitMemberNum(), goodsVO.getOrderPayMemberNum(), goodsVO.getCollectionStoreNum()));
            });
        }
        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-收藏数；2-支付订单数 默认不传按浏览量降序")
    })
    @GetMapping("preferGoodsRank")
    public JsonResult<List<GoodsRankVO>> preferGoodsRank(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(value = "webSite",required = false,defaultValue = "1") String webSite, Integer sort) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, false);
        List<? extends GoodsBase> list = statsModelUtil.getGoodsList(timeType, startTime, endTime,webSite, sort, "prefer", vendor.getStoreId());
        List<GoodsRankVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(goodsBase -> {
                //浏览量、收藏数和订单数三者必须有一个满足条件
                if (goodsBase.getViewNum() > 0 || goodsBase.getCollectionNum() > 0 || goodsBase.getOrderPayNum() > 0) {
                    vos.add(new GoodsRankVO(goodsBase.getGoodsId(), goodsBase.getGoodsName(), goodsBase.getGoodsImage(),
                            goodsBase.getViewNum(), goodsBase.getCollectionNum(), goodsBase.getOrderPayNum()));
                }
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("支付客单价变化趋势")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点")

    })
    @GetMapping("orderPayTrend")
    public JsonResult<List<OrderPayTrendVO>> orderPayTrend(HttpServletRequest request, Date startTime, Date endTime,@RequestParam(value = "webSite",required = false,defaultValue = "1") String webSite) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
        List<MovableGoodsVO> list = statsModelUtil.getStoreTrendList(timeType, startTime, endTime, webSite, vendor.getStoreId());
        List<OrderPayTrendVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(trendVO -> {
                OrderPayTrendVO vo = new OrderPayTrendVO();
                vo.setStatsTime(trendVO.getStatsTime());
                vo.setOrderPayAtv(trendVO.getOrderPayAtv());
                vos.add(vo);
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("会员报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;new_member_num-新增用户数;visitor_num-店铺访客数;" +
                    "order_submit_member_num-下单人数;order_pay_member_num-支付人数;collection_store_num-关注店铺人数;默认按时间降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("dayReport")
    public JsonResult<PageVO<MemberDayReportVO>> dayReport(HttpServletRequest request, 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) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        StoreDayExample example = new StoreDayExample();
        example.setStoreId(vendor.getStoreId());
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        List<StoreDay> list = storeDayModel.getStoreDayList(example, pager);
        List<MemberDayReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(storeDay -> {
                vos.add(new MemberDayReportVO(storeDay));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("会员报表(按会员)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "memberName", value = "会员名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderSubmitNum-下单数;orderSubmitAmount-下单金额;orderPayNum-支付订单数;" +
                    "orderPayAmount-支付金额;returnNum-退单数;returnAmount-退款金额;默认按下单数降序排序"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("memberReport")
    public JsonResult<PageVO<MemberStoreReportVO>> memberReport(HttpServletRequest request, Date startTime, Date endTime,
                                                                @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                                String memberName,
                                                                @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                                @RequestParam(value = "sort", required = false, defaultValue = "orderSubmitNum") String sort) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        MemberStoreDayExample example = new MemberStoreDayExample();
        example.setStoreId(vendor.getStoreId());
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setMemberNameLike(memberName);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        List<MemberStoreBase> list = memberStoreDayModel.getMemberStoreList(example, pager);
        List<MemberStoreReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(memberStoreBase -> {
                vos.add(new MemberStoreReportVO(memberStoreBase));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("导出报表(按天)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:stats_time-时间;new_member_num-新增用户数;visitor_num-店铺访客数;" +
                    "order_submit_member_num-下单人数;order_pay_member_num-支付人数;collection_store_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) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        StoreDayExample example = new StoreDayExample();
        example.setStoreId(vendor.getStoreId());
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        storeDayModel.memberReportExport(request, response, example);
        return null;
    }

    @ApiOperation("导出报表(按会员)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "webSite", value = "站点"),
            @ApiImplicitParam(name = "memberName", value = "会员名称"),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:orderSubmitNum-下单数;orderSubmitAmount-下单金额;orderPayNum-支付订单数;" +
                    "orderPayAmount-支付金额;returnNum-退单数;returnAmount-退款金额;默认按下单数降序排序")
    })
    @GetMapping("memberExport")
    public JsonResult memberExport(HttpServletRequest request, HttpServletResponse response, Date startTime, Date endTime,
                                   @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                   String memberName,
                                   @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                   @RequestParam(value = "sort", required = false, defaultValue = "orderSubmitNum") String sort) {
        Vendor vendor = UserUtil.getUser(request, Vendor.class);

        MemberStoreDayExample example = new MemberStoreDayExample();
        example.setStoreId(vendor.getStoreId());
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setMemberNameLike(memberName);
        example.setWebSite(webSite);
        example.setOrderBy(sort + " " + type);
        memberStoreDayModel.memberReportExport(request, response, example);
        return null;
    }

}
