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.gic.api.base.commons.Page;
import com.gic.haoban.manage.api.enums.content.MaterialReportType;
import com.gic.haoban.manage.web.utils.target.DataTargetHttpUtils;
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.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";


    /**
     * 查询素材首页使用数据
     *
     * @param enterpriseId
     * @return
     */
    public MaterialTodayDataBO queryMaterialTodayData(String enterpriseId, List<String> storeIds) {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("inFields", inlineParams);

        inlineParams.put("enterpriseId", enterpriseId);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), MATERIAL_INDEX_DATA);
        if (result.get("data") == null) {
            return MaterialTodayDataBO.empty();
        }
        return JSON.parseObject(JSON.toJSONString(result.get("data")), MaterialTodayDataBO.class);
    }


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

        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), MATERIAL_OVERVIEW_DATA);
        if (result.get("data") == null) {
            return new MaterialDataOverviewVO();
        }
        return JSON.parseObject(JSON.toJSONString(result.get("data")), MaterialDataOverviewVO.class);
    }


    /**
     * 导购纬度数据统计
     *
     * @param enterpriseId
     * @param storeIds
     * @param fixedDateDiff
     * @param order
     * @return
     */
    public Page<MaterialClerkUsedDataVO> queryMaterialClerkUsedData(String enterpriseId, List<String> storeIds, Integer fixedDateDiff,
                                                                    String orderField, Integer order, Integer pageNo, Integer pageSize) {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("pageNo", pageNo);
        params.put("pageSize", pageSize);
        params.put("inFields", inlineParams);
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        if (StringUtils.isNotBlank(orderField)) {
            String orderStr = new Integer(1).equals(order) ? " asc " : " desc ";
            inlineParams.put("orderByField", orderField + orderStr);
        }
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), MATERIAL_CLERK_DATA);
        if (result.get("data") == null) {
            return new Page<>();
        }

        List<MaterialClerkUsedDataVO> dataVOS = JSON.parseArray(JSON.toJSONString(result.get("data")), MaterialClerkUsedDataVO.class);
        Page<MaterialClerkUsedDataVO> pageResult = new Page<>();
        pageResult.setTotalCount(1);
        pageResult.setResult(dataVOS);
        return pageResult;
    }

    /**
     * 门店纬度数据统计
     *
     * @param enterpriseId
     * @param storeIds
     * @param fixedDateDiff
     * @param order
     * @return
     */
    public Page<MaterialStoreUsedDataVO> queryMaterialStoreUsedData(String enterpriseId, List<String> storeIds, Integer fixedDateDiff,
                                                                    String orderField, Integer order, Integer pageNo, Integer pageSize) {
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("pageNo", pageNo);
        params.put("pageSize", pageSize);
        params.put("inFields", inlineParams);

        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("fixedDateDiff", fixedDateDiff);
        if (StringUtils.isNotBlank(orderField)) {
            String orderStr = new Integer(1).equals(order) ? " asc " : " desc ";
            inlineParams.put("orderByField", orderField + orderStr);
        }
        if (CollectionUtil.isNotEmpty(storeIds)) {
            inlineParams.put("storeId", StringUtils.join(storeIds, ","));
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), MATERIAL_CLERK_DATA);
        if (result.get("data") == null) {
            return new Page<>();
        }

        List<MaterialStoreUsedDataVO> dataVOS = JSON.parseArray(JSON.toJSONString(result.get("data")), MaterialStoreUsedDataVO.class);
        Page<MaterialStoreUsedDataVO> pageResult = new Page<>();
        pageResult.setTotalCount(1);
        pageResult.setResult(dataVOS);
        return pageResult;
    }


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

    /**
     * 查询导购素材使用情况
     *
     * @param enterpriseId
     * @param reportType
     * @param storeIds
     * @return
     */
    public Page<MaterialPersonalUsedDataVO> queryMaterialClerkUsedReport(String enterpriseId, String clerkId,
                                                                         Integer reportType, List<String> storeIds,
                                                                         Integer pageNo, Integer pageSize,
                                                                         String orderField, String order) {
        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        int bizDate = 0;
        String apolloKey = MATERIAL_CLERK_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
            bizDate = DateUtil.weekOfYear(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastWeek());
            endTime = DateUtil.endOfMonth(DateUtil.lastWeek());
            bizDate = DateUtil.month(DateUtil.lastMonth());
            apolloKey = MATERIAL_CLERK_MONTH_DATA;
        }
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("pageNo", pageNo);
        params.put("pageSize", pageSize);
        params.put("inFields", inlineParams);
        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, ","));
        }
        if (StringUtils.isNotBlank(orderField)) {
            String orderStr = new Integer(1).equals(order) ? " asc " : " desc ";
            inlineParams.put("orderByField", orderField + orderStr);
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), apolloKey);
        if (result.get("data") == null) {
            return new Page<>();
        }
        Page<MaterialPersonalUsedDataVO> pageResult = new Page<>();
        Object total = result.get("total");
        List<MaterialPersonalUsedDataVO> materialPersonalUsedDataVos = JSON.parseArray(JSON.toJSONString(result.get("data")), MaterialPersonalUsedDataVO.class);
        if (CollectionUtils.isNotEmpty(materialPersonalUsedDataVos)) {
            return new Page<>();
        }
        for (MaterialPersonalUsedDataVO materialPersonalUsedDataVo : materialPersonalUsedDataVos) {
            materialPersonalUsedDataVo.setStartTime(startTime);
            materialPersonalUsedDataVo.setEndTime(endTime);
        }
        pageResult.setResult(materialPersonalUsedDataVos);
        pageResult.setTotalCount(1);
        return pageResult;
    }

    /**
     * 查询门店/区经使用数据
     *
     * @param enterpriseId
     * @param clerkId
     * @param reportType
     * @param storeIds
     * @return
     */
    public Page<MaterialStoreUsedDataVO> queryMaterialStoreUseReport(String enterpriseId, String clerkId,
                                                                     Integer reportType, List<String> storeIds,
                                                                     Integer pageNo, Integer pageSize,
                                                                     String orderField, String order) {

        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        int bizDate = 0;
        String apolloKey = MATERIAL_STORE_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
            bizDate = DateUtil.weekOfYear(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastWeek());
            endTime = DateUtil.endOfMonth(DateUtil.lastWeek());
            bizDate = DateUtil.month(DateUtil.lastMonth());
            apolloKey = MATERIAL_STORE_MONTH_DATA;
        }
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("pageNo", pageNo);
        params.put("pageSize", pageSize);
        params.put("inFields", inlineParams);
        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, ","));
        }
        if (StringUtils.isNotBlank(orderField)) {
            String orderStr = " " + order;
            inlineParams.put("orderByField", orderField + orderStr);
        }
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), apolloKey);
        if (result.get("data") == null) {
            return new Page<>();
        }
        Page<MaterialStoreUsedDataVO> pageResult = new Page<>();
        Object total = result.get("total");
        List<MaterialStoreUsedDataVO> materialStoreUsedDataVOS = JSON.parseArray(JSON.toJSONString(result.get("data")), MaterialStoreUsedDataVO.class);
        if (CollectionUtils.isNotEmpty(materialStoreUsedDataVOS)) {
            return new Page<>();
        }
        for (MaterialStoreUsedDataVO materialStoreUsedDataVO : materialStoreUsedDataVOS) {
            materialStoreUsedDataVO.setStartTime(startTime);
            materialStoreUsedDataVO.setEndTime(endTime);
        }
        pageResult.setResult(materialStoreUsedDataVOS);
        pageResult.setTotalCount(1);
        return pageResult;
    }

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

        // 获取当前时间周期
        DateTime startTime = null;
        DateTime endTime = null;
        int bizDate = 0;
        String apolloKey = MATERIAL_AREA_WEEK_DATA;
        if (MaterialReportType.WEEK.getCode().equals(reportType)) {
            // 周报
            startTime = DateUtil.beginOfWeek(DateUtil.lastWeek());
            endTime = DateUtil.endOfWeek(DateUtil.lastWeek());
            bizDate = DateUtil.weekOfYear(DateUtil.lastWeek());
        } else {
            startTime = DateUtil.beginOfMonth(DateUtil.lastWeek());
            endTime = DateUtil.endOfMonth(DateUtil.lastWeek());
            bizDate = DateUtil.month(DateUtil.lastMonth());
            apolloKey = MATERIAL_AREA_MONTH_DATA;
        }
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("inFields", inlineParams);
        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 = this.doHttp(JSON.toJSONString(params), apolloKey);
        if (result.get("data") == null) {
            return new MaterialStoreUsedDataVO();
        }
        MaterialStoreUsedDataVO materialStoreUsedDataVO = JSON.parseObject(JSON.toJSONString(result), MaterialStoreUsedDataVO.class);
        materialStoreUsedDataVO.setStartTime(startTime);
        materialStoreUsedDataVO.setEndTime(endTime);
        return materialStoreUsedDataVO;
    }


    private Map<String, Object> doHttp(String jsonParam, String apolloKey) {
        try {
            log.info("调用接口 apolloKey：{}, 参数:{}", apolloKey, jsonParam);
            Map<String, Object> result = DataTargetHttpUtils.http(jsonParam, apolloKey);
            if (result == null) {
                return Collections.emptyMap();
            }
            return result;
        } catch (Exception ex) {
            log.info("请求接口失败 apolloKey:{}", apolloKey, ex);
        }
        return Collections.emptyMap();
    }

    /**
     * 会员最近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> params = new HashMap<>();
        Map<String, Object> inlineParams = new HashMap<>();
        params.put("inFields", inlineParams);
        if (StringUtils.isNotBlank(clerkId)) {
            inlineParams.put("clerkId", clerkId);
        }
        inlineParams.put("enterpriseId", enterpriseId);
        inlineParams.put("customerId", StringUtils.join(memberIds, ","));
        Map<String, Object> result = this.doHttp(JSON.toJSONString(params), MEMBER_RECENTLY_30_DAY_VISIT);
        if (result.get("data") == null) {
            return Collections.emptyMap();
        }
        List<MemberVisitMaterialBO> memberVisitMaterialBos = JSON.parseArray(JSON.toJSONString(result.get("data")), 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));
    }

}
