package com.gic.haoban.manage.web.utils.data;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.DataApiUtils;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.dto.StoreGroupDTO;
import com.gic.enterprise.api.dto.StoreSearchDTO;
import com.gic.enterprise.api.service.StoreGroupService;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.manage.api.service.StaffApiService;
import com.gic.haoban.manage.web.qo.wechatwork.StoreGroupCommonQO;
import com.gic.haoban.manage.web.vo.wechatwork.DataPageVO;
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.*;
import java.util.stream.Collectors;

/**
 * @Author guojx
 * @Date 2024/5/22 9:44
 */
@Component
@Slf4j
public class StoreAuthUtils {
    @Autowired
    private StoreGroupService storeGroupService;
    @Autowired
    private StaffApiService staffApiService;
    @Autowired
    private StoreService storeService;

    private static final String NO_EXIST_STORE_ID = "no_exist_store_id";

    public void setCommonParam(JSONObject jsonObject, StoreGroupCommonQO storeCommonQO) {
        List<String> storeIds = getAuthStoreId(storeCommonQO);
        if (CollectionUtils.isNotEmpty(storeIds)) {
            jsonObject.put("storeId", storeIds);
        }
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        jsonObject.put("enterpriseId", login.getEnterpriseId());
    }

    public List<String> getAuthStoreId(StoreGroupCommonQO storeCommonQO) {
        String storeGroupId = storeCommonQO.getStoreGroupId();
        String storeSearchParam = storeCommonQO.getStoreSearchParam();
        String storeId = storeCommonQO.getStoreId();

        List<String> storeIdList = new ArrayList<>();
        List<String> statusList = getAllStoreStatus();
        if (StringUtils.isNotBlank(storeId)) {
            storeIdList.addAll(Arrays.stream(storeId.split(",")).collect(Collectors.toList()));
        }

        String nextStoreGroupId = storeCommonQO.getNextStoreGroupId();
        String preStoreGroupId = storeCommonQO.getPreStoreGroupId();
        boolean isSelectStore = storeCommonQO.isSelectStore();

        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        List<String> roleStoreIds = staffApiService.getHaoBanStoreIdsRolesByClerkId(login.getClerkId(), login.getWxEnterpriseId());
        if (CollectionUtils.isEmpty(roleStoreIds)) {
            log.info("登录人无门店权限");
            return getNoExistStore();
        }
        List<String> groupIds = null;
        List<String> storeGroupIds = new ArrayList<>();

        if(StringUtils.isNotBlank(storeGroupId) || StringUtils.isNotBlank(nextStoreGroupId)) {
            if (StringUtils.isNotBlank(storeGroupId)) {
                storeGroupIds = Arrays.stream(storeGroupId.split(",")).collect(Collectors.toList());
            } else if (StringUtils.isNotBlank(nextStoreGroupId)) {
                if (storeCommonQO.isNoBelongStoreGroup()) {
                    storeIdList.addAll(getPreStoreIdList(preStoreGroupId, login.getEnterpriseId()));
                } else if (storeCommonQO.isRecycle()) {
                    statusList.clear();
                    statusList.add("-3");
                } else {
                    storeGroupIds.add(nextStoreGroupId);
                }
            }

            if (CollectionUtils.isNotEmpty(storeGroupIds)) {
                groupIds = storeGroupService.getStoreGroupIdsByParentGroupId(login.getEnterpriseId(), storeGroupIds);
            }
        }
        List<String> searchStoreIdList = getStore(login.getEnterpriseId(), login.getClerkId(), storeSearchParam, groupIds, statusList, storeIdList);
        if (isAllAuth(roleStoreIds)) {
            return searchStoreIdList;
        }
        //交集
        roleStoreIds.retainAll(searchStoreIdList);
        if (CollectionUtils.isEmpty(roleStoreIds)) {
            return getNoExistStore();
        }
        return roleStoreIds;
    }

    public void setStoreGroupJsonParam(JSONObject jsonObject, StoreGroupCommonQO qo) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        jsonObject.put("enterpriseId", login.getEnterpriseId());
        Integer storeGroup = getStoreGroupLevel(qo);
        jsonObject.put("storeGroup", storeGroup);
        List<String> storeIds = getAuthStoreId(qo);
        if (CollectionUtils.isNotEmpty(storeIds)) {
            jsonObject.put("storeId", storeIds);
        }
    }

    public boolean needRecycleStoreWhenAllStoreGroup(String enterpriseId, StoreGroupCommonQO qo) {
        if (qo.isSelectStore()) {
            return true;
        }
        return StringUtils.isBlank(qo.getStoreGroupId()) || qo.getStoreGroupId().contains(initGroupId(enterpriseId)) || qo.isRecycle();
    }

    public int getStoreGroupLevel(StoreGroupCommonQO qo) {
        if (qo.isSelectStore()) {
            return 7;
        }
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String enterpriseId = login.getEnterpriseId();
        String storeGroupId = qo.getStoreGroupId();
        if (StringUtils.isNotBlank(storeGroupId)) {
            List<StoreGroupDTO> list = storeGroupService
                    .listStoreGroup(Arrays.stream(storeGroupId.split(",")).toArray(String[]::new), enterpriseId);
            int min = list.stream().map(e -> e.getGroupLevel()).min(Integer::compareTo).get();
            return min == 0 ? 1 : min;
        }
        //1：分组1,2：分组2,3：分组3,4：分组4,5：分组5,6：分组6,7：门店,8：区经)
        String nextStoreGroupId = qo.getNextStoreGroupId();
        if (StringUtils.isNotBlank(nextStoreGroupId)) {
            if (qo.isNoBelongStoreGroup() || "-3".equals(nextStoreGroupId)) {
                //无归属门店
                return 7;
            }
            //如果是叶子结点的分组，下面没有层级了，就展示门店
            List<StoreGroupDTO> childList = storeGroupService.getStoreGroupList(enterpriseId, null, nextStoreGroupId);
            if (CollectionUtils.isEmpty(childList)) {
                return 7;
            }
            StoreGroupDTO storeGroupDTO = storeGroupService.getStoreGroupById(nextStoreGroupId);
            return storeGroupDTO.getGroupLevel() + 1;
        }
        //如果是门店筛选，则直接显示门店
        if (StringUtils.isNotBlank(qo.getStoreId())) {
            return 7;
        }
        return 1;
    }

    public DataPageVO getDataCommon(String searchDataParams, Integer currentPage, String logStr, Integer pageSize, boolean hasCountPerPage) {
        boolean isFirst = currentPage != null && currentPage == 1;
        if (isFirst) {
            log.info(logStr);
        }
        DataPageVO vo = new DataPageVO();
        vo.setPageNum(currentPage);
        vo.setPageSize(pageSize);

        JSONObject jsonObject = JSONObject.parseObject(searchDataParams);
        Integer storeGroup = jsonObject.getInteger("storeGroup");
        boolean isStore = storeGroup != null && storeGroup == 7;
        boolean isRecycle = storeGroup == null || storeGroup == 8;
        boolean isFirstGroup = storeGroup != null && storeGroup == 1;
        jsonObject.put("pageNum", currentPage);
        jsonObject.put("pageSize", pageSize);
        String apolloKey = jsonObject.getString("apolloKey");
        String allApolloKey = jsonObject.getString("allApolloKey");

        if (isRecycle) {
            jsonObject.put("storeGroup", 8);
            JSONObject recycle = getTotalJson(jsonObject, apolloKey);
            if (recycle == null) {
                recycle = new JSONObject();
                recycle.put("storeGroupName", "合计（0）");
                vo.setTotalNum(0);
            } else {
                recycle.put("storeGroupName", "合计（1）");

                vo.setTotalNum(1);
            }
            recycle.put("storeGroupId", "all");
            List<JSONObject> list = new ArrayList<>();
            setChannelGroupList(recycle);
            list.add(recycle);
            JSONObject temp = JSONObject.parseObject(recycle.toJSONString());
            temp.remove("channelGroupList");
            temp.put("storeGroupName", "回收站门店");
            temp.put("storeGroupId", "-3");

            setChannelGroupList(temp);
            list.add(temp);

            vo.setRows(list);
            return vo;
        }

        List<String> getRecycleStore = null;
        List<String> storeIdListParam = (List<String>) jsonObject.get("storeId");
        boolean hasRecycle = jsonObject.getInteger("recycleFlag") != null &&  jsonObject.getInteger("recycleFlag") == 1;
        if (hasRecycle) {
            getRecycleStore = (List<String>) jsonObject.get("recycleStoreIdList");
        }

        jsonObject.put("pageSize", Integer.MAX_VALUE);
        jsonObject.put("pageNum", 1);

        List<JSONObject> list = DataApiUtils.getCirclePageData(jsonObject, apolloKey, true);
        Integer totalCount = (CollectionUtils.isEmpty(list) ? 0 : list.size());
        vo.setTotalNum(totalCount);

        vo.setPageSize(pageSize);
        vo.setPageNum(currentPage);

        String channelMapKey = jsonObject.containsKey("orderChannel") ? "orderChannel" : "mbrChannel";

        if (CollectionUtils.isNotEmpty(list)) {
            vo.setPageSize(pageSize);
            vo.setPageNum(currentPage);
            Map<String, List<JSONObject>> jsonGroup = new HashMap<>();
            List<String> idList = new ArrayList<>();
            for (JSONObject tempMap : list) {
                String id = tempMap.getString(isStore ? "storeId" : "storeGroupId");
                if (jsonGroup.containsKey(id)) {
                    jsonGroup.get(id).add(tempMap);
                } else {
                    idList.add(id);
                    List<JSONObject> mapJson = new ArrayList<>();
                    mapJson.add(tempMap);
                    jsonGroup.put(id, mapJson);
                }
            }

            vo.setTotalNum(jsonGroup.size());
            int totalPage = (vo.getTotalNum() % pageSize != 0 ? (vo.getTotalNum() / pageSize + 1)  : (vo.getTotalNum() / pageSize));
            int start = (currentPage - 1) * pageSize;
            int end = currentPage * pageSize;
            if (end > idList.size()) {
                end = idList.size();
            }

            List<JSONObject> tempList = new ArrayList<>();
            Set<String> tempSet = new HashSet<>();
            for (int i = start; i < end; i ++) {
                String indexId = idList.get(i);
                if (tempSet.contains(indexId)) {
                    continue;
                }
                List<JSONObject> channelGroupList = jsonGroup.get(indexId);
                JSONObject copyJson = JSONObject.parseObject(channelGroupList.get(0).toJSONString());
                copyJson.put("channelGroupList", sortChannel(channelGroupList, (List<String>) jsonObject.get(channelMapKey)));
                tempSet.add(indexId);
                tempList.add(copyJson);
            }
            list = tempList;
        }

        //调用一次合计
        if (hasCountPerPage || (isFirst && CollectionUtils.isNotEmpty(list))) {
            if (hasCountPerPage && CollectionUtils.isEmpty(list)) {
                list = new ArrayList<>();
            }
            jsonObject.put("pageNum", 1);
            if (hasRecycle) {
                //回收站门店，加回去
                storeIdListParam.addAll(getRecycleStore);
                jsonObject.put("storeId", storeIdListParam.stream().collect(Collectors.joining(",")));
            }
            jsonObject.put("storeGroup", 8);
            String totalApolloKey = apolloKey;
            if (StringUtils.isNotBlank(allApolloKey)) {
                totalApolloKey = allApolloKey;
            }
            JSONObject total = getTotalJson(jsonObject, totalApolloKey);
            if (total == null) {
                total = new JSONObject();
            }
            if (isStore) {
                total.put("storeName", "合计（" + (hasCountPerPage ? vo.getTotalNum() : totalCount) + "）");
            } else {
                total.put("storeGroupName", "合计（" + (hasCountPerPage ? vo.getTotalNum() : totalCount) + "）");
            }
            total.put("storeGroupId", "all");
            setChannelGroupList(total);
            list.add(0, total);

            if (hasRecycle) {
                jsonObject.put("storeId", getRecycleStore.stream().collect(Collectors.joining(",")));
                JSONObject recycle = getTotalJson(jsonObject, apolloKey);
                if (recycle == null) {
                    recycle = new JSONObject();
                }
                recycle.put("storeGroupName", "回收站门店");
                recycle.put("storeGroupId", "-3");

                setChannelGroupList(recycle);
                list.add(1, recycle);
            }
        }
        vo.setRows(list);
        return vo;
    }

    private List<String> getStore(String enterpriseId, String userId, String search, List<String> storeGroupIdList, List<String> status, List<String> storeIdList) {
        StoreSearchDTO storeSearchDTO = new StoreSearchDTO();
        storeSearchDTO.setEnterpriseId(enterpriseId);
        if (StringUtils.isNotBlank(search)) {
            storeSearchDTO.setSearchName(search);
        }
        if (CollectionUtils.isNotEmpty(status)) {
            storeSearchDTO.setStatusAnyIn(status);
            if (status.contains("-3")) {
                storeSearchDTO.setStatusIn("-3");
            }
        }
        if (CollectionUtils.isNotEmpty(storeIdList)) {
            storeSearchDTO.setStoreIdList(storeIdList);
        }
        storeSearchDTO.setUserId(userId);
        if (CollectionUtils.isNotEmpty(storeGroupIdList)) {
            storeSearchDTO.setStoreGroupIdList(storeGroupIdList);
        }
        Page pageStore = new Page<>();
        //-1代表不分页
        pageStore.setCurrentPage(-1);
        Page resultPage = storeService.storeListPage(pageStore, storeSearchDTO);
        List<StoreDTO> storeDTOList = resultPage.getResult();
        if (CollectionUtils.isEmpty(storeDTOList)) {
            return getNoExistStore();
        }
        return storeDTOList.stream().map(e -> e.getStoreId()).collect(Collectors.toList());
    }

    public List<String> getPreStoreIdList(String preStoreGroupId, String enterpriseId) {
        preStoreGroupId = getPreStoreGroupId(preStoreGroupId, enterpriseId);
        String[] queryArr = new String[]{preStoreGroupId};
        List<String> storeIdList = storeService.getStoreIdListByGroupId(queryArr,
                getAllStoreStatus().stream().mapToInt(e -> Integer.parseInt(e)).boxed().collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(storeIdList)) {
            storeIdList.add(NO_EXIST_STORE_ID);
        }
        return storeIdList;
    }

    private String getPreStoreGroupId(String preStoreGroupId, String enterpriseId) {
        if (isAllStoreGroup(preStoreGroupId)) {
            return initGroupId(enterpriseId);
        }
        return preStoreGroupId;
    }

    private static boolean isAllStoreGroup(String preStoreGroupId) {
        if (StringUtils.isBlank(preStoreGroupId) || "preStoreGroupId".equals(preStoreGroupId)) {
            return true;
        }
        return false;
    }

    private static boolean isAllAuth(List<String> roleStoreIds) {
        return roleStoreIds.size() == 1 && "-1".equals(roleStoreIds.get(0));
    }

    public String initGroupId(String enterpriseId) {
        List<StoreGroupDTO> groups = storeGroupService.getStoreGroupList(enterpriseId, null, "0");
        if (groups != null && groups.size() > 0 && groups.get(0) != null) {
            return groups.get(0).getStoreGroupId();
        } else {
            return null;
        }
    }

    private static List<String> getAllStoreStatus() {
        List<String> list = new ArrayList<>();
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("6");
        list.add("7");
        //好办不要回收站
        //list.add("-3");
        return list;
    }

    private static List<String> getNoExistStore() {
        List<String> list = new ArrayList<>(1);
        list.add(NO_EXIST_STORE_ID);
        return list;
    }

    public void setChannelGroupList(JSONObject jsonObject) {
        jsonObject.put("channelGroupList", Arrays.asList(JSONObject.parseObject(jsonObject.toJSONString())));
    }

    public JSONObject getTotalJson(JSONObject param, String apolloKey) {
        Map<String, Object> totalRes = DataApiUtils.http(param.toJSONString(), apolloKey);
        List<JSONObject> totalList = DataApiUtils.getPageList(totalRes);
        if (CollectionUtils.isEmpty(totalList)) {
            return null;
        }
        JSONObject total = totalList.get(0);
        return total;
    }


    public static List<JSONObject> sortChannel(List<JSONObject> channelGroupList, List<String> mbrChannel) {
        if (CollectionUtils.isNotEmpty(channelGroupList)) {
            for (JSONObject temp : channelGroupList) {
                if ("c_all".equals(temp.getString("channelCode")) && StringUtils.isBlank(temp.getString("channelName"))) {
                    temp.put("channelName", "全渠道");
                } else if (!temp.containsKey("channelCode")) {
                    temp.put("channelName", "全渠道");
                }
            }
            if (channelGroupList.stream().noneMatch(e -> e.containsKey("channelCode"))) {
                return channelGroupList;
            }
        }
        if (CollectionUtils.isEmpty(mbrChannel)) {
            return channelGroupList;
        }

        List<JSONObject> result = new ArrayList<>();
        for (String str : mbrChannel) {
            for (JSONObject jsonObject : channelGroupList) {
                if (str.equals(jsonObject.getString("channelCode"))) {
                    result.add(jsonObject);
                }
            }
        }
        return result;
    }
}
