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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.JSONResponse;
import com.gic.api.base.commons.Page;
import com.gic.clerk.api.dto.AuthorizedUser;
import com.gic.commons.util.DataApiUtils;
import com.gic.commons.util.DateUtil;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.manage.web.handle.WechatWorkLostClerkHandle;
import com.gic.haoban.manage.web.handle.WechatWorkLostDetailHandle;
import com.gic.haoban.manage.web.handle.WechatWorkLostStoreGroupHandle;
import com.gic.haoban.manage.web.qo.wechatwork.*;
import com.gic.haoban.manage.web.utils.AuthorizedUserUtils;
import com.gic.haoban.manage.web.utils.data.ConcurrencyUtils;
import com.gic.haoban.manage.web.utils.data.MapThreadHandlerRequest;
import com.gic.haoban.manage.web.utils.data.StoreAuthUtils;
import com.gic.haoban.manage.web.vo.wechatwork.*;
import com.gic.qcloud.BucketNameEnum;
import com.gic.web.common.controller.NewBaseController;
import com.gic.web.common.download.DownloadTask;
import com.gic.web.common.download.DownloadTaskUtil;
import com.gic.web.common.download.constants.TaskTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企微流失接口
 * @Author guojx
 * @Date 2024/5/21 13:45
 */
@RestController
@Slf4j
@RequestMapping("wechat-work")
public class WechatWorkController extends NewBaseController {
    @Autowired
    private StoreAuthUtils storeAuthUtils;
    @Autowired
    private WechatWorkLostClerkHandle wechatWorkLostClerkHandle;
    @Autowired
    private WechatWorkLostStoreGroupHandle wechatWorkLostStoreGroupHandle;
    @Autowired
    private WechatWorkLostDetailHandle wechatWorkLostDetailHandle;

    /**
     * 流失数据概览
     * @param qo
     * @return
     */
    @RequestMapping(value = "lost-overview")
    public RestResponse<WechatWorkLostVO> lostOverview(@RequestBody WechatWorkLostOverviewQO qo) {
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(qo);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO().setStoreGroupId(qo.getStoreGroupId()));
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), "data_mbr_scale_haoban_background_loss");
        List<JSONObject> list = DataApiUtils.getDataList(res);
        List<WechatWorkLostVO> voList = JSONArray.parseArray(JSON.toJSONString(list), WechatWorkLostVO.class);
        return RestResponse.successResult(CollectionUtils.isEmpty(voList) ? null : voList.get(0));
    }

    /**
     * 流失数据概览趋势图
     * @param qo
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "lost-overview-trend")
    public RestResponse<List<WechatWorkLostVO>> lostOverviewTrend(@RequestBody WechatWorkLostOverviewQO qo) throws ParseException {
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(qo);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO().setStoreGroupId(qo.getStoreGroupId()));

        List<MapThreadHandlerRequest> list = new ArrayList<>();
        jsonObject.put("groupType", 1);
        list.add(new MapThreadHandlerRequest(jsonObject, "data_mbr_scale_haoban_background_loss_date", "1_onewayFriendNum"));
        jsonObject.put("groupType", 2);
        list.add(new MapThreadHandlerRequest(jsonObject, "data_mbr_scale_haoban_background_loss_date", "2_totalLostNum"));
        jsonObject.put("groupType", 3);
        list.add(new MapThreadHandlerRequest(jsonObject, "data_mbr_scale_haoban_background_loss_date", "3_deleteSalesNum"));
        jsonObject.put("groupType", 4);
        list.add(new MapThreadHandlerRequest(jsonObject, "data_mbr_scale_haoban_background_loss_date", "4_salesDeleteNum"));

        Map<String, List<JSONObject>> map = ConcurrencyUtils.concurrencyDataForMap(list);
        List<JSONObject> resultList = new ArrayList<>();
        if (map != null) {
            map.forEach((k, v) -> {
                if (CollectionUtils.isNotEmpty(v)) {
                    for (JSONObject tempJson : v) {
                        tempJson.put(k.substring(0, 1), tempJson.get(k.substring(2)));
                    }
                    resultList.addAll(v);
                }
            });
        }
        Map<String, List<JSONObject>> voMap = resultList.stream().collect(Collectors.groupingBy(e -> e.getString("bizDate")));

        List<String> dateList = DateUtil.getBetweenDates(qo.getStartDate(), qo.getEndDate());
        List<WechatWorkLostVO> voList = new ArrayList<>();
        for (String date : dateList) {
            WechatWorkLostVO vo = new WechatWorkLostVO();
            vo.setBizDate(date);
            List<JSONObject> mapValue = voMap.get(date);
            if (CollectionUtils.isNotEmpty(mapValue)) {
                for (JSONObject tempJson : mapValue) {
                    if (tempJson.containsKey("1")) {
                        vo.setOnewayFriendNum(tempJson.getInteger("1"));
                    }
                    if (tempJson.containsKey("2")) {
                        vo.setTotalLostNum(tempJson.getInteger("2"));
                    }
                    if (tempJson.containsKey("3")) {
                        vo.setDeleteSalesNum(tempJson.getInteger("3"));
                    }
                    if (tempJson.containsKey("4")) {
                        vo.setSalesDeleteNum(tempJson.getInteger("4"));
                    }
                    if(tempJson.containsKey("5")) {
                        vo.setDelIsSingleNum(tempJson.getInteger("5"));
                    }
                }
            }
            voList.add(vo);
        }
        return RestResponse.successResult(voList);
    }

    /**
     * 流失数据统计-门店分组
     * @param qo
     * @return
     */
    @RequestMapping(value = "lost-store-group")
    public RestResponse<DataPageVO<WechatWorkLostStoreGroupVO>> lostStoreGroup(@RequestBody WechatWorkLostStoreGroupQO qo) {
        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setStoreGroupJsonParam(jsonObject, qo);
        jsonObject.put("apolloKey", "data_mbr_scale_haoban_background_loss_statisti");
        jsonObject.put("groupType", 1);
        DataPageVO vo = storeAuthUtils.getDataCommon(jsonObject.toJSONString(), qo.getPageNum(), "data_mbr_scale_haoban_background_loss_statisti", qo.getPageSize(), true);
        if (CollectionUtils.isNotEmpty(vo.getRows())) {
            vo.setRows(JSONArray.parseArray(JSON.toJSONString(vo.getRows()), WechatWorkLostStoreGroupVO.class));
        }
        return RestResponse.successResult(vo);
    }

    /**
     * 流失数据统计-门店分组导出
     * @param qo
     * @return
     */
    @RequestMapping(value = "export-lost-store-group")
    public RestResponse exportLostStoreGroup(@RequestBody WechatWorkLostStoreGroupQO qo) {

        DownloadTask task = new DownloadTask();
        task.setTaskTypeEnum(TaskTypeEnum.WECHAT_WORK_STORE_GROUP);
        task.setDataType(qo.getDataType());
        task.setUser(getUserInfo());

        task.setTotalCount(lostStoreGroup(qo).getResult().getTotalNum());

        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setStoreGroupJsonParam(jsonObject, qo);
        jsonObject.put("apolloKey", "data_mbr_scale_haoban_background_loss_statisti");
        jsonObject.put("groupType", 1);
        //Excel的标题是字段进行计算
        List<String> indexList = new ArrayList<>();
        List<String> fieldList = new ArrayList<>();

        Integer storeGroup = jsonObject.getInteger("storeGroup");
        boolean isStore = storeGroup != null && storeGroup == 7;

        if (isStore) {
            indexList.add("门店名称");
            fieldList.add("storeName");
            indexList.add("门店code");
            fieldList.add("storeCode");
        } else {
            indexList.add("分组名称");
            fieldList.add("storeGroupName");
        }

        indexList.add("上级分组");
        fieldList.add("parentStoreGroupName");
        indexList.add("删除导购人数");
        fieldList.add("deleteSalesNum");
        indexList.add("导购删除人数");
        fieldList.add("salesDeleteNum");
        indexList.add("非单向好友被删除人数");
        fieldList.add("delIsSingleNum");
        indexList.add("单向好友人数");
        fieldList.add("onewayFriendNum");


        task.setFileName( "流失好友-门店维度数据统计-" + qo.getStartDate() + "_" + qo.getEndDate());
        task.setChannelName("数据-企微数据-流失好友");
        task.setBucketName(BucketNameEnum.REPORT_50000.getName());
        jsonObject.put("indexList", indexList);
        jsonObject.put("fieldList", fieldList);
        task.setSearchDataParams(jsonObject.toJSONString());
        task.setHandler(wechatWorkLostStoreGroupHandle);
        JSONResponse downloadTask = DownloadTaskUtil.createDownloadTask(task);
        return RestResponse.successResult(downloadTask.getResult());
    }

    /**
     * 流失数据统计-导购
     * @param qo
     * @return
     */
    @RequestMapping(value = "lost-clerk")
    public RestResponse<DataPageVO<WechatWorkLostClerkVO>> lostClerk(@RequestBody WechatWorkLostClerkQO qo) {
        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO());
        jsonObject.put("groupType", 2);
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), "data_mbr_scale_haoban_background_loss_statisti");
        Page page = DataApiUtils.getPageData(res);
        DataPageVO vo = new DataPageVO();
        vo.setPageSize(page.getPageSize());
        vo.setPageNum(page.getCurrentPage());

        List<JSONObject> list = page.getResult();

        vo.setTotalNum(page.getTotalCount());

        jsonObject.put("groupType", 1);
        jsonObject.put("storeGroup", 8);
        JSONObject total = storeAuthUtils.getTotalJson(jsonObject, "data_mbr_scale_haoban_background_loss_statisti");
        if (list == null) {
            list = new ArrayList<>();
        }
        if (total != null) {
            total.put("clerkName", "合计（" + list.size() + "）");
            list.add(0, total);
        }
        vo.setRows(list);
        if (CollectionUtils.isNotEmpty(vo.getRows())) {
            vo.setRows(JSONArray.parseArray(JSON.toJSONString(vo.getRows()), WechatWorkLostClerkVO.class));
        }
        return RestResponse.successResult(vo);
    }

    /**
     * 流失数据统计-导购导出
     * @param qo
     * @return
     */
    @RequestMapping(value = "export-lost-clerk")
    public RestResponse exportLostClerk(@RequestBody WechatWorkLostClerkQO qo) {
        DownloadTask task = new DownloadTask();
        task.setTaskTypeEnum(TaskTypeEnum.WECHAT_WORK_CLERK_DETAIL);
        task.setDataType(qo.getDataType());
        task.setUser(getUserInfo());

        task.setTotalCount(lostClerk(qo).getResult().getTotalNum());

        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO());
        jsonObject.put("apolloKey", "data_mbr_scale_haoban_background_loss_statisti");
        jsonObject.put("groupType", 2);
        //Excel的标题是字段进行计算
        List<String> indexList = new ArrayList<>();
        List<String> fieldList = new ArrayList<>();
        indexList.add("导购姓名");
        fieldList.add("clerkName");
        indexList.add("导购code");
        fieldList.add("clerkCode");
        indexList.add("所属门店名称");
        fieldList.add("storeName");
        indexList.add("所属门店code");
        fieldList.add("storeCode");
        indexList.add("所属分组");
        fieldList.add("storeGroupName");
        indexList.add("删除导购人数");
        fieldList.add("deleteSalesNum");
        indexList.add("导购删除人数");
        fieldList.add("salesDeleteNum");
        indexList.add("非单向好友被删除人数");
        fieldList.add("delIsSingleNum");
        indexList.add("单向好友人数");
        fieldList.add("onewayFriendNum");


        task.setFileName( "流失好友-导购维度数据统计-" + qo.getStartDate() + "_" + qo.getEndDate());
        task.setChannelName("数据-企微数据-流失好友");
        task.setBucketName(BucketNameEnum.REPORT_50000.getName());
        jsonObject.put("indexList", indexList);
        jsonObject.put("fieldList", fieldList);
        task.setSearchDataParams(jsonObject.toJSONString());
        task.setHandler(wechatWorkLostClerkHandle);
        JSONResponse downloadTask = DownloadTaskUtil.createDownloadTask(task);
        return RestResponse.successResult(downloadTask.getResult());
    }

    /**
     * 流失明细
     * @param qo
     * @return
     */
    @RequestMapping(value = "lost-detail")
    public RestResponse<DataPageVO<WechatWorkLostDetailVO>> lostDetail(@RequestBody WechatWorkLostDetailQO qo) {
        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO());
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), "data_mbr_scale_haoban_background_loss_detail");
        Page page = DataApiUtils.getPageData(res);
        DataPageVO<WechatWorkLostDetailVO> vo = new DataPageVO();
        vo.setPageSize(page.getPageSize());
        vo.setPageNum(page.getCurrentPage());

        List<JSONObject> list = page.getResult();
        if (CollectionUtils.isNotEmpty(list)) {
            List<WechatWorkLostDetailVO> voList = JSONArray.parseArray(JSON.toJSONString(list), WechatWorkLostDetailVO.class);
            vo.setRows(voList);
        }
        vo.setTotalNum(page.getTotalCount());
        return RestResponse.successResult(vo);
    }

    /**
     * 流失明细-导出
     * @param qo
     * @return
     */
    @RequestMapping(value = "export-lost-detail")
    public RestResponse exportLostDetail(@RequestBody WechatWorkLostDetailQO qo) {
        DownloadTask task = new DownloadTask();
        task.setTaskTypeEnum(TaskTypeEnum.WECHAT_WORK_MEMBER_DETAIL);
        task.setDataType(qo.getDataType());
        task.setUser(getUserInfo());

        task.setTotalCount(lostDetail(qo).getResult().getTotalNum());

        JSONObject jsonObject = new JSONObject();
        qo.dealWithParam(jsonObject);
        storeAuthUtils.setCommonParam(jsonObject, new StoreGroupCommonQO());
        jsonObject.put("apolloKey", "data_mbr_scale_haoban_background_loss_detail");
        //Excel的标题是字段进行计算
        List<String> indexList = new ArrayList<>();
        List<String> fieldList = new ArrayList<>();
        indexList.add("客户姓名");
        fieldList.add("memberName");
        indexList.add("客户昵称");
        fieldList.add("memberNick");
        indexList.add("客户手机号");
        fieldList.add("memberPhone");
        indexList.add("导购姓名");
        fieldList.add("clerkName");
        indexList.add("导购code");
        fieldList.add("clerkCode");
        indexList.add("所属门店名称");
        fieldList.add("storeName");
        indexList.add("所属门店code");
        fieldList.add("storeCode");
        indexList.add("删除类型");
        fieldList.add("deleteType");
        indexList.add("单向好友被删除");
        fieldList.add("delIsSingle");
        indexList.add("留存天数");
        fieldList.add("remainDays");
        indexList.add("添加好友时间");
        fieldList.add("addTime");
        indexList.add("最近消费时间");
        fieldList.add("lastCsmeDate");
        indexList.add("删除时间");
        fieldList.add("deleteTime");


        task.setFileName( "流失好友-流失明细-" + qo.getStartDate() + "_" + qo.getEndDate());
        task.setChannelName("数据-企微数据-流失好友");
        task.setBucketName(BucketNameEnum.REPORT_50000.getName());
        jsonObject.put("indexList", indexList);
        jsonObject.put("fieldList", fieldList);
        task.setSearchDataParams(jsonObject.toJSONString());
        task.setHandler(wechatWorkLostDetailHandle);
        JSONResponse downloadTask = DownloadTaskUtil.createDownloadTask(task);
        return RestResponse.successResult(downloadTask.getResult());
    }

    private AuthorizedUser getUserInfo() {
        return AuthorizedUserUtils.getUserInfo();
    }

}
