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

import com.slodon.b2b2c.core.constant.GoodsConst;
import com.slodon.b2b2c.core.constant.StoreConst;
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.enums.ProvinceJson;
import com.slodon.b2b2c.enums.StatsTimeType;
import com.slodon.b2b2c.enums.WebSiteConstant;
import com.slodon.b2b2c.goods.example.GoodsExample;
import com.slodon.b2b2c.member.example.MemberExample;
import com.slodon.b2b2c.member.pojo.MemberEnquiry;
import com.slodon.b2b2c.model.goods.GoodsModel;
import com.slodon.b2b2c.model.goods.GoodsSearchWordsModel;
import com.slodon.b2b2c.model.member.MemberModel;
import com.slodon.b2b2c.model.member.advich.MemberEnquiryModel;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.model.statistics.StoreDayModel;
import com.slodon.b2b2c.seller.dto.StoreStatisticsDTO;
import com.slodon.b2b2c.seller.example.StoreExample;
import com.slodon.b2b2c.statistics.example.StoreDayExample;
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 java.text.SimpleDateFormat;
import java.util.*;

@Api(tags = "screen-大屏")
@RestController
@RequestMapping("v3/statistics/screen/analysis")
public class ScreenAnalysisController extends BaseController {

    @Resource
    private StatsModelUtil statsModelUtil;

    @Resource
    private MemberEnquiryModel memberEnquiryModel;

    @Resource
    private MemberModel memberModel;

    @Resource
    private StoreModel storeModel;

    @Resource
    private GoodsModel goodsModel;

    @Resource
    private StoreDayModel storeDayModel;

    @Resource
    private GoodsSearchWordsModel goodsSearchWordsModel;
    @ApiOperation("流量趋势")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
    })
    @GetMapping("flowTrend")
    public JsonResult<ScreenFlowTrendVO> flowTrend(HttpServletRequest request, Date startTime, Date endTime) {
        StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);
        ScreenFlowTrendVO vo = new ScreenFlowTrendVO();

        // 处理海外用户数据
        List<MovableGoodsVO> overseasList = statsModelUtil.getPlatformTrendList(
                timeType, startTime, endTime, WebSiteConstant.MEMBER_OVERSEA);

        List<ScreenFlowTrendVO.VisitorNumVO> visitorNumList = new ArrayList<>();
        List<ScreenFlowTrendVO.ViewNumVO> viewNumList = new ArrayList<>();

        populateVisitorAndViewData(overseasList, visitorNumList, viewNumList);

        vo.setVisitorNumList(visitorNumList);
        vo.setViewNumList(viewNumList);

        // 处理分销商数据
        List<MovableGoodsVO> distributorList = statsModelUtil.getPlatformTrendList(
                timeType, startTime, endTime, WebSiteConstant.MEMBER_DISTRIBUTOR);

        List<ScreenFlowTrendVO.VisitorNumVO> visitorCNNumList = new ArrayList<>();
        List<ScreenFlowTrendVO.ViewNumVO> viewNumCNList = new ArrayList<>();

        populateVisitorAndViewData(distributorList, visitorCNNumList, viewNumCNList);

        vo.setVisitorNumCNList(visitorCNNumList);
        vo.setViewNumCNList(viewNumCNList);

        return SldResponse.success(vo);
    }


    private void populateVisitorAndViewData(List<MovableGoodsVO> list,
                                            List<ScreenFlowTrendVO.VisitorNumVO> visitorList,
                                            List<ScreenFlowTrendVO.ViewNumVO> viewList) {
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(trendVO -> {
                // 访客数
                ScreenFlowTrendVO.VisitorNumVO visitorNumVO = new ScreenFlowTrendVO.VisitorNumVO();
                visitorNumVO.setStatsTime(trendVO.getStatsTime());
                visitorNumVO.setVisitorNum(trendVO.getVisitorNum());
                visitorList.add(visitorNumVO);

                // 访问量
                ScreenFlowTrendVO.ViewNumVO viewNumVO = new ScreenFlowTrendVO.ViewNumVO();
                viewNumVO.setStatsTime(trendVO.getStatsTime());
                viewNumVO.setViewNum(trendVO.getViewNum());
                viewList.add(viewNumVO);
            });
        }
    }


    /**
     * 询盘趋势
     *
     * @param request
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping("enquiryTrend")
    public JsonResult<ScreenEnquiryTrendVO> getEnquiryTrend(HttpServletRequest request, Date startTime, Date endTime) throws Exception {
        ScreenEnquiryTrendVO vo = new ScreenEnquiryTrendVO();

        if (startTime != null && endTime != null) {
            StatsTimeType timeType = StatsTimeType.checkTimeType(startTime, endTime, true);

            // 处理海外用户询盘数据
            List<MemberEnquiry> overseasList = memberEnquiryModel.getAdminEnquiryTrendList(
                    timeType, startTime, endTime, WebSiteConstant.MEMBER_OVERSEA);
            List<ScreenEnquiryTrendVO.EnquiryNumVO> enquiryNumVOList = new ArrayList<>();
            populateEnquiryData(overseasList, enquiryNumVOList);
            vo.setEnquiryTrendList(enquiryNumVOList);

            // 处理分销商询盘数据
            List<MemberEnquiry> distributorList = memberEnquiryModel.getAdminEnquiryTrendList(
                    timeType, startTime, endTime, WebSiteConstant.MEMBER_DISTRIBUTOR);
            List<ScreenEnquiryTrendVO.EnquiryNumVO> enquiryNumVOCNList = new ArrayList<>();
            populateEnquiryData(distributorList, enquiryNumVOCNList);
            vo.setEnquiryTrendCNList(enquiryNumVOCNList);
        }

        return SldResponse.success(vo);
    }

    private void populateEnquiryData(List<MemberEnquiry> list, List<ScreenEnquiryTrendVO.EnquiryNumVO> targetList) {
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(memberEnquiry -> {
                ScreenEnquiryTrendVO.EnquiryNumVO enquiryNumVO = new ScreenEnquiryTrendVO.EnquiryNumVO();
                enquiryNumVO.setStatsTime(memberEnquiry.getEnquiryDay());
                enquiryNumVO.setViewNum(memberEnquiry.getEnquiryNum());
                targetList.add(enquiryNumVO);
            });
        }
    }

    /**
     * 询盘地域分布
     * @param request
     * @param webSite
     * @return
     */
    @GetMapping("enquiryDistribution")
    @ApiOperation("询盘地域分布")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "webSite", value = "站点"),
    })
    public JsonResult<List<ScreenEnquiryDistribution>> getEnquiryDistribution(HttpServletRequest request, @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
        return SldResponse.success(memberEnquiryModel.getEnquiryDistribution(webSite));
    }


    @ApiOperation("供应链企业分布")
    @GetMapping("regionDistribution")
    public JsonResult<List<ProvincePercentVO>> regionDistribution(HttpServletRequest request) {
        StoreExample example = new StoreExample();
        example.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
        example.setOrderBy("storeNum DESC");
        List<StoreStatisticsDTO> list = storeModel.getStoreStatisticList(example);
        List<ProvincePercentVO> vos = getRegionDistributionPercent(list);
        return SldResponse.success(vos);
    }

    /**
     * 地域分布
     *
     * @param list
     * @return
     */
    public List<ProvincePercentVO> getRegionDistributionPercent(List<StoreStatisticsDTO> list) {
        List<ProvincePercentVO> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        //查询总店铺数，用于计算各省份占比
        StoreExample example = new StoreExample();
        example.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
        int totalNum = storeModel.getStoreCount(example);
        //key为省份名称，value为店铺数量
        Map<String, Integer> dataMap = new HashMap<>();
        for (StoreStatisticsDTO dto : list) {
            String provinceCode = dto.getProvinceCode();
            //如果编码为空，按未知处理
            if (StringUtil.isEmpty(dto.getProvinceCode())) {
                provinceCode = ProvinceJson.defaultProvinceCode;
            }
            //如果省份为空，按未知处理
            String provinceName = ProvinceJson.provinceMap.getOrDefault(provinceCode, ProvinceJson.defaultProvinceName);
            //店铺数量
            Integer storeNum = dto.getStoreNum();
            if (dataMap.containsKey(provinceName)) {
                dataMap.put(provinceName, dataMap.get(provinceName) + storeNum);
            } else {
                dataMap.put(provinceName, storeNum);
            }
        }
        List<Map.Entry<String, Integer>> mapList = new ArrayList<>(dataMap.entrySet());
        //排序
        Collections.sort(mapList, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
        //只取前5个省份数据
        int count = 0;
        int otherNum = totalNum;
        for (Map.Entry<String, Integer> entry : mapList) {
            if (count >= 5) {
                //累加第5名之后的所有店铺数量到"其他"
                otherNum -= entry.getValue();
                continue;
            }

            ProvincePercentVO vo = new ProvincePercentVO();
            vo.setProvinceName(entry.getKey());
            vo.setStoreNum(entry.getValue());
            result.add(vo);
            //数据计算
            otherNum -= entry.getValue();
            count++;
        }

        //如果有其他省份数据，添加"其他"项
        if (otherNum > 0 && mapList.size() > 5) {
            ProvincePercentVO vo = new ProvincePercentVO();
            vo.setProvinceName("其他");
            vo.setStoreNum(otherNum);
            result.add(vo);
        }

        return result;
    }


    /**
     * 平台数据汇总
     * @param request
     * @return
     */
    @GetMapping("dataSummary")
    @ApiOperation("平台数据汇总")
    public JsonResult<ScreenDataSummary> getDataSummary(HttpServletRequest request) {
        ScreenDataSummary vo = new ScreenDataSummary();
        MemberExample memberExample = new MemberExample();
        memberExample.setWebSite(WebSiteConstant.MEMBER_OVERSEA);
        vo.setMemberNum(memberModel.getMemberCount(memberExample));
        memberExample.setWebSite(WebSiteConstant.MEMBER_DISTRIBUTOR);
        vo.setDistributorNum(memberModel.getMemberCount(memberExample));
        StoreExample storeExample = new StoreExample();
        storeExample.setStateNotEquals(StoreConst.STORE_STATE_DELETE);
        vo.setStoreNum(storeModel.getStoreCount(storeExample));
        GoodsExample goodsExample = new GoodsExample();
//        goodsExample.setWebSite(WebSiteConstant.MEMBER_OVERSEA);
        goodsExample.setState(GoodsConst.GOODS_STATE_UPPER);
        vo.setProductNum(goodsModel.getGoodsCount(goodsExample));
        vo.setServiceProviderNum(999);
        return SldResponse.success(vo);
    }


    /**
     * 会员地域分布
     * @param request
     * @return
     */
    @GetMapping("memberDistribution")
    @ApiOperation("会员地域分布")
    public JsonResult<List<ScreenMemberDistribution>> getMemberDistribution(HttpServletRequest request,@RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
        return SldResponse.success(memberModel.getMemberDistribution(webSite));
    }


    /**
     * 会员新增趋势
     * @param request
     * @return
     */
    @GetMapping("memberTrend")
    @ApiOperation("会员新增趋势")
    public JsonResult<List<ScreenMemberTrendVO>> memberTrend(HttpServletRequest request,
                                                             @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                             @RequestParam(value = "startTime", required = true) Date startTime,
                                                             @RequestParam(value = "endTime", required = true) Date endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return SldResponse.success(memberModel.getMemberTrend(webSite,sdf.format(startTime),sdf.format(endTime)));
    }


    /**
     * 商品新增趋势
     * @param request
     * @return
     */
    @GetMapping("goodsTrend")
    @ApiOperation("商品新增趋势")
    public JsonResult<List<ScreenGoodsTrendVO>> goodsTrend(HttpServletRequest request,@RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite) {
        return SldResponse.success(goodsModel.getGoodsTrend(webSite));
    }


    /**
     * 搜索词排行
     * @param request
     * @return
     */
    @GetMapping("searchRank")
    @ApiOperation("搜索词排行")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "webSite", value = "站点"),
    })
    public JsonResult<List<String>> searchRank(HttpServletRequest request, Date startTime, Date endTime,
                                                           @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                           @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                           @RequestParam(value = "pageSize", required =false,defaultValue = "10") Integer pageSize,
                                                           @RequestParam(value = "current", required =false,defaultValue = "1") Integer current) {
        PagerInfo pager = new PagerInfo(pageSize, current);
        List<String> list = goodsSearchWordsModel.getSearchWordsRank(startTime, endTime, type, webSite, pager);
        return SldResponse.success(list);
    }



    /**
     * 店铺流量排行
     *
     * @param request
     * @param startTime
     * @param endTime
     * @param type
     * @param webSite
     * @return
     */
    @ApiOperation("店铺流量排行")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", required = true),
            @ApiImplicitParam(name = "type", value = "排序类型；desc-降序;asc-升序;默认类型为降序"),
            @ApiImplicitParam(name = "sort", value = "排序:viewNum-店铺浏览量;visitorNum-店铺访客数"),
            @ApiImplicitParam(name = "webSite", value = "站点"),
    })
    @GetMapping("storeFlowRank")
    public JsonResult<PageVO<StoreReportVO>> storeFlowRank(HttpServletRequest request, Date startTime, Date endTime,
                                                           @RequestParam(value = "type", required = false, defaultValue = "desc") String type,
                                                           @RequestParam(value = "webSite", required = false, defaultValue = "1") String webSite,
                                                           @RequestParam(value = "pageSize", required =false,defaultValue = "10") Integer pageSize,
                                                           @RequestParam(value = "current", required =false,defaultValue = "1") Integer current) {
        PagerInfo pager = new PagerInfo(pageSize, current);
        StoreDayExample example = new StoreDayExample();
        example.setWebSite(webSite);
        example.setStatsTimeAfter(startTime);
        example.setStatsTimeBefore(endTime);
        example.setOrderBy("viewNum " + type + " ,visitorNum " + type);
        List<StoreBase> list = storeDayModel.getStoreList(example, pager);
        List<StoreReportVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(storeBase -> {
                vos.add(new StoreReportVO(storeBase));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }


}
