package com.gic.haoban.manage.web.controller.content.adaptor;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.DataApiUtils;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.enterprise.api.dto.EnterpriseDTO;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.haoban.manage.api.enums.content.MaterialReportType;
import com.gic.haoban.manage.web.qo.content.statistics.MaterialAnalyzeDataQO;
import com.gic.haoban.manage.web.qo.content.statistics.MaterialReportQO;
import com.gic.haoban.manage.web.qo.content.statistics.MaterialStoreAnalyzeDataQO;
import com.gic.haoban.manage.web.qo.content.statistics.MaterialStoreReportQO;
import com.gic.haoban.manage.web.utils.target.DataTargetHttpUtils;
import com.gic.haoban.manage.web.vo.content.statistics.MaterialAreaUsedDataVO;
import com.gic.haoban.manage.web.vo.content.statistics.MaterialClerkUsedDataVO;
import com.gic.haoban.manage.web.vo.content.statistics.MaterialDataOverviewVO;
import com.gic.haoban.manage.web.vo.content.statistics.MaterialStoreUsedDataVO;
import com.gic.haoban.manage.web.vo.content.statistics.bo.MaterialTodayDataBO;
import com.gic.haoban.manage.web.vo.content.statistics.bo.MemberVisitMaterialBO;
import com.gic.haoban.manage.web.vo.content.statistics.report.MaterialPersonalUsedDataVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author MUSI
 * @Date 2023/3/27 10:49 AM
 * @Description
 * @Version 素材数据统计
 **/
@Slf4j
@Component
public class MaterialDataAdaptor {


    /**
     * 素材首页数据统计
     */
    private static final String MATERIAL_INDEX_DATA = "data_matl_haoban_area_stats_real";
    private static final String MATERIAL_OVERVIEW_DATA = "data_matl_haoban_area_stats";
    /**
     * 导购纬度数据统计
     */
    private static final String MATERIAL_CLERK_DATA = "data_matl_haoban_clerk_stats";

    /**
     * 门店纬度数据统计
     */
    private static final String MATERIAL_STORE_DATA = "data_matl_haoban_store_stats";

    /**
     * 素材导购周报数据
     */
    private static final String MATERIAL_CLERK_WEEK_DATA = "data_cms_clerk_week_report_list";

    /**
     * 素材导购月报数据
     */
    private static final String MATERIAL_CLERK_MONTH_DATA = "data_cms_clerk_month_report_list";
    /**
     * 素材门店周报数据
     */
    private static final String MATERIAL_STORE_WEEK_DATA = "data_cms_store_week_report_list";
    /**
     * 素材门店月报数据
     */
    private static final String MATERIAL_STORE_MONTH_DATA = "data_cms_store_month_report_list";

    /**
     * 区经周报数据
     */
    private static final String MATERIAL_AREA_WEEK_DATA = "data_cms_store_week_report_total";

    /**
     * 区经月报数据
     */
    private static final String MATERIAL_AREA_MONTH_DATA = "data_cms_store_month_report_total";

    /**
     * 会员最近30天访问素材总数
     */
    private static final String MEMBER_RECENTLY_30_DAY_VISIT = "data_matl_haoban_user_30day_stats_real";

    @Autowired
    private EnterpriseService enterpriseService;


    /**
     * 查询素材首页使用数据
     *
     * @param enterpriseId
     * @return
     */
    public MaterialTodayDataBO queryMaterialTodayData(String enterpriseId, List<String> storeIds) {
        Map<String, Object> inlineParams = new HashMap<>();
        inlineParams.put("enterpriseId", enterpriseId);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), MATERIAL_INDEX_DATA);
        if (result.get("data") == null) {
            return MaterialTodayDataBO.empty();
        }
        List<MaterialTodayDataBO> datas = DataApiUtils.parseDataList(result, MaterialTodayDataBO.class);
        if (CollectionUtils.isEmpty(datas)) {
            return MaterialTodayDataBO.empty();
        }
        return datas.get(0);
    }


    /**
     * 店长/区经
     * 查询数据概览
     *
     * @param enterpriseId
     * @param storeIds
     * @param fixedDateDiff
     * @return
     */
    public MaterialDataOverviewVO queryMaterialDataOverview(String enterpriseId, List<String> storeIds, Integer fixedDateDiff) {
        Map<String, Object> inlineParams = new HashMap<>();

        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), MATERIAL_OVERVIEW_DATA);
        List<MaterialDataOverviewVO> datas = DataApiUtils.parseDataList(result, MaterialDataOverviewVO.class);
        if (CollectionUtils.isEmpty(datas)) {
            return new MaterialDataOverviewVO();
        }
        return datas.get(0);
    }


    /**
     * 导购纬度数据统计
     *
     * @param storeIds
     * @return
     */
    public Page<MaterialClerkUsedDataVO> queryMaterialClerkUsedData(MaterialAnalyzeDataQO dataQO,List<String> storeIds) {
        int pageNum = dataQO.getPageNum();
        int pageSize = dataQO.getPageSize();
        String enterpriseId = dataQO.getEnterpriseId();
        Integer fixedDateDiff = dataQO.getFixedDateDiff();
        String orderByField = dataQO.getOrderByField();
        String order = dataQO.getOrder();
        Map<String, Object> inlineParams = new HashMap<>();
        inlineParams.put("pageNum", pageNum);
        inlineParams.put("pageSize", pageSize);
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        int orderByFields = DataApiUtils.getOrderByFields(orderByField, "enterpriseId", dataQO.getFieldsOrder());
        inlineParams.put("orderByFields", orderByFields);
        inlineParams.put("orderByType", DataApiUtils.getOrderByType(order));
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), MATERIAL_CLERK_DATA);
        Page<MaterialClerkUsedDataVO> pageData = DataApiUtils.getPageData(result, MaterialClerkUsedDataVO.class);
        return pageData;
    }

    /**
     * 门店纬度数据统计
     *
     * @param enterpriseId
     * @param storeIds
     * @param fixedDateDiff
     * @param orderStr
     * @return
     */
    public Page<MaterialStoreUsedDataVO> queryMaterialStoreUsedData(MaterialStoreAnalyzeDataQO dataQO, List<String> storeIds) {
        int pageNum = dataQO.getPageNum();
        int pageSize = dataQO.getPageSize();
        String enterpriseId = dataQO.getEnterpriseId();
        Integer fixedDateDiff = dataQO.getFixedDateDiff();
        String order = dataQO.getOrder();
        String orderByField = dataQO.getOrderByField();
        Map<String, Object> inlineParams = new HashMap<>();
        inlineParams.put("pageNum", pageNum);
        inlineParams.put("pageSize", pageSize);
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        inlineParams.put("orderByFields", DataApiUtils.getOrderByFields(orderByField, "enterpriseId", dataQO.getFieldsOrder()));
        inlineParams.put("orderByType", DataApiUtils.getOrderByType(order));
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), MATERIAL_STORE_DATA);
        Page<MaterialStoreUsedDataVO> pageData = DataApiUtils.getPageData(result, MaterialStoreUsedDataVO.class);
        return pageData;
    }


    // --------------- 周报/月报 ---------------

    /**
     * 查询导购素材使用情况
     *
     * @param storeIds
     * @return
     */
    public Page<MaterialPersonalUsedDataVO> queryMaterialClerkUsedReport(MaterialReportQO materialReportQO, List<String> storeIds) {
        Integer reportType = materialReportQO.getReportType();
        Integer pageNo = materialReportQO.getPageNum();
        Integer pageSize = materialReportQO.getPageSize();
        String clerkId = materialReportQO.getClerkId();
        String enterpriseId = materialReportQO.getEnterpriseId();
        String orderByField = materialReportQO.getOrderByField();
        String order = materialReportQO.getOrder();
        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        String bizDate = materialReportQO.getBizDate();
        String apolloKey = MATERIAL_CLERK_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastMonth());
            endTime = DateUtil.endOfMonth(DateUtil.lastMonth());
            apolloKey = MATERIAL_CLERK_MONTH_DATA;
        }
        Map<String, Object> inlineParams = new HashMap<>();
        inlineParams.put("pageNum", pageNo);
        inlineParams.put("pageSize", pageSize);
        if (StringUtils.isNotBlank(clerkId)) {
            inlineParams.put("clerkId", clerkId);
        }
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("bizDate", bizDate);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        inlineParams.put("orderByFields", DataApiUtils.getOrderByFields(orderByField, "enterpriseId", materialReportQO.getFieldsOrder()));
        inlineParams.put("orderByType", DataApiUtils.getOrderByType(order));
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), apolloKey);
        Page<MaterialPersonalUsedDataVO> pageData = DataApiUtils.getPageData(result, MaterialPersonalUsedDataVO.class);
        for (MaterialPersonalUsedDataVO materialPersonalUsedDataVo : pageData.getResult()) {
            materialPersonalUsedDataVo.setStartTime(startTime);
            materialPersonalUsedDataVo.setEndTime(endTime);
        }
        return pageData;
    }

    /**
     * 查询门店/区经使用数据
     *
     * @param storeIds
     * @return
     */
    public Page<MaterialStoreUsedDataVO> queryMaterialStoreUseReport(MaterialStoreReportQO materialReportQO, List<String> storeIds) {

        Integer reportType = materialReportQO.getReportType();
        Integer pageNo = materialReportQO.getPageNum();
        Integer pageSize = materialReportQO.getPageSize();
        String clerkId = materialReportQO.getClerkId();
        String enterpriseId = materialReportQO.getEnterpriseId();
        String orderByField = materialReportQO.getOrderByField();
        String order = materialReportQO.getOrder();
        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        String bizDate = materialReportQO.getBizDate();
        String apolloKey = MATERIAL_STORE_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastMonth());
            endTime = DateUtil.endOfMonth(DateUtil.lastMonth());
            apolloKey = MATERIAL_STORE_MONTH_DATA;
        }
        Map<String, Object> inlineParams = new HashMap<>();
        inlineParams.put("pageNum", pageNo);
        inlineParams.put("pageSize", pageSize);
        if (StringUtils.isNotBlank(clerkId)) {
            inlineParams.put("clerkId", clerkId);
        }
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("bizDate", bizDate);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        inlineParams.put("orderByFields", DataApiUtils.getOrderByFields(orderByField, "enterpriseId", materialReportQO.getFieldsOrder()));
        inlineParams.put("orderByType", DataApiUtils.getOrderByType(order));
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), apolloKey);
        Page pageData = DataApiUtils.getPageData(result);
        List<JSONObject> jsonObjects = (List<JSONObject>) pageData.getResult();
        if (CollectionUtils.isEmpty(jsonObjects)) {
            return new Page<>();
        }
        List<MaterialStoreUsedDataVO> materialStoreUsedDataVOS = jsonObjects.stream()
                .map(item -> {
                    MaterialStoreUsedDataVO temp = JSONObject.parseObject(item.toJSONString(), MaterialStoreUsedDataVO.class);
                    temp.setDayAvgUseRate(item.getBigDecimal("dayAvgUseBindProportion"));
                    temp.setClickUserNum(item.getInteger("userClickNum"));
                    temp.setConvSalesNmt(item.getBigDecimal("convSalesAmt"));
                    return temp;
                })
                .collect(Collectors.toList());
        for (MaterialStoreUsedDataVO materialStoreUsedDataVO : materialStoreUsedDataVOS) {
            materialStoreUsedDataVO.setStartTime(startTime);
            materialStoreUsedDataVO.setEndTime(endTime);
        }
        pageData.setResult(materialStoreUsedDataVOS);
        return pageData;
    }

    /**
     * 取经数据概览数据
     *
     * @return
     */
    public MaterialAreaUsedDataVO queryMaterialAreaOverviewData(String enterpriseId, String clerkId,
                                                                Integer reportType, List<String> storeIds, String bizDate) {

        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        String apolloKey = MATERIAL_AREA_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastMonth());
            endTime = DateUtil.endOfMonth(DateUtil.lastMonth());
            apolloKey = MATERIAL_AREA_MONTH_DATA;
        }

        EnterpriseDTO enterpriseDTO = enterpriseService.getEnterpriseById(enterpriseId);
        if (enterpriseDTO == null) {
            MaterialAreaUsedDataVO materialAreaUsedDataVO = new MaterialAreaUsedDataVO();
            materialAreaUsedDataVO.setStartTime(startTime);
            materialAreaUsedDataVO.setEndTime(endTime);
            log.info("企业{}不存在", enterpriseId);
            return materialAreaUsedDataVO;
        }


        Map<String, Object> inlineParams = new HashMap<>();
        if (StringUtils.isNotBlank(clerkId)) {
            inlineParams.put("clerkId", clerkId);
        }
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("bizDate", bizDate);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), apolloKey);
        if (result.get("data") == null) {
            MaterialAreaUsedDataVO materialAreaUsedDataVO = new MaterialAreaUsedDataVO();
            materialAreaUsedDataVO.setStartTime(startTime);
            materialAreaUsedDataVO.setEndTime(endTime);
            materialAreaUsedDataVO.setBrandName(enterpriseDTO.getBrandName());
            return materialAreaUsedDataVO;
        }
        List<JSONObject> jsonObjects = DataApiUtils.getDataList(result);
        if (CollectionUtils.isEmpty(jsonObjects)) {
            MaterialAreaUsedDataVO materialAreaUsedDataVO = new MaterialAreaUsedDataVO();
            materialAreaUsedDataVO.setStartTime(startTime);
            materialAreaUsedDataVO.setEndTime(endTime);
            materialAreaUsedDataVO.setBrandName(enterpriseDTO.getBrandName());
            return materialAreaUsedDataVO;
        }
        List<MaterialAreaUsedDataVO> areaUsedDataVOS = jsonObjects.stream()
                .map(item -> {
                    MaterialAreaUsedDataVO temp = JSONObject.parseObject(item.toJSONString(), MaterialAreaUsedDataVO.class);
                    temp.setDayAvgUseRate(item.getBigDecimal("dayAvgUseBindProportion"));
                    temp.setClickUserNum(item.getInteger("userClickNum"));
                    temp.setConvSalesNmt(item.getBigDecimal("convSalesAmt"));
                    return temp;
                })
                .collect(Collectors.toList());
        MaterialAreaUsedDataVO materialAreaUsedDataVO = areaUsedDataVOS.get(0);
        materialAreaUsedDataVO.setStartTime(startTime);
        materialAreaUsedDataVO.setEndTime(endTime);
        materialAreaUsedDataVO.setBrandName(enterpriseDTO.getBrandName());
        return materialAreaUsedDataVO;
    }

    /**
     * 会员最近30天的浏览素材数量
     *
     * @param enterpriseId
     * @param storeId
     * @param clerkId
     * @param memberIds
     * @return
     */
    public Map<String, Integer> queryMemberVisitMap(String enterpriseId, String storeId, String clerkId, List<String> memberIds) {

        Map<String, Object> inlineParams = new HashMap<>();
        if (StringUtils.isNotBlank(clerkId)) {
            inlineParams.put("clerkId", clerkId);
        }
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("customerId", StringUtils.join(memberIds, ","));
        Map<String, Object> result = DataApiUtils.http(JSON.toJSONString(inlineParams), MEMBER_RECENTLY_30_DAY_VISIT);
        List<MemberVisitMaterialBO> memberVisitMaterialBos = DataApiUtils.parseDataList(result, MemberVisitMaterialBO.class);
        if (CollectionUtils.isEmpty(memberVisitMaterialBos)) {
            return Collections.emptyMap();
        }
        return memberVisitMaterialBos
                .stream()
                .collect(Collectors.toMap(MemberVisitMaterialBO::getCustomerId, item -> Optional.ofNullable(item.getMatlNum30Day())
                        .map(Integer::new).orElse(0), (v1, v2) -> v1));
    }
}
