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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
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());
        jsonObject.put("wxEnterpriseId", login.getWxEnterpriseId());
    }

    public <T> List<T> getOverview(String apolloKey, JSONObject jsonObject, StoreGroupCommonQO storeGroupCommonQO, Class clazz) {
        setCommonParam(jsonObject, storeGroupCommonQO);
        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), apolloKey);
        List<JSONObject> list = DataApiUtils.getDataList(res);
        List<T> voList = JSONArray.parseArray(JSON.toJSONString(list), clazz);
        return voList;
    }

    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();

        List<String> statusListParam = storeCommonQO.getStatusList();
        if (CollectionUtils.isNotEmpty(statusListParam)) {
            statusList.retainAll(statusListParam);
        }
        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());
        jsonObject.put("wxEnterpriseId", login.getWxEnterpriseId());
        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;
    }

    @Deprecated
    public DataPageVO getDataCommon(String searchDataParams, Integer currentPage, String logStr, Integer pageSize, boolean hasCountPerPage) {
        return getDataCommonParent(searchDataParams, currentPage, logStr, pageSize, hasCountPerPage, false);
    }

    public DataPageVO getData(DataApiQO qo) {
        Integer currentPage = qo.getCurrentPage();
        String logStr = qo.getLogStr();
        Integer pageSize = qo.getPageSize();
        String searchDataParams = qo.getSearchDataParams();
        boolean hasCountPerPage = qo.isHasCountPerPage();
        boolean noTotal = qo.isNoTotal();
        Class clazz = qo.getClazz();

        boolean isFirst = currentPage != null && currentPage == 1;
        if (isFirst && StringUtils.isNotBlank(logStr)) {
            log.info(logStr);
        }
        DataPageVO vo = new DataPageVO();
        vo.setPageNum(currentPage);
        vo.setPageSize(pageSize);

        JSONObject jsonObject = qo.getJsonObject();
        if (jsonObject == null) {
            //兼容老接口传参
            jsonObject= JSONObject.parseObject(searchDataParams);
        } else {
            //填充所需参数
            StoreGroupCommonQO storeGroupCommonQO = qo.getStoreGroupCommonQO();
            setStoreGroupJsonParam(jsonObject, storeGroupCommonQO);
        }
        Integer storeGroup = jsonObject.getInteger("storeGroup");
        boolean isStore = storeGroup != null && storeGroup == 7;

        jsonObject.put("pageNum", currentPage);
        jsonObject.put("pageSize", pageSize);

        String apolloKey = qo.getApolloKey();
        if (StringUtils.isBlank(apolloKey)) {
            apolloKey = jsonObject.getString("apolloKey");
        }

        Map<String, Object> res = DataApiUtils.http(jsonObject.toJSONString(), apolloKey);

        Page page = DataApiUtils.getPageData(res);
        List<JSONObject> list = DataApiUtils.getPageList(res);
        Integer totalCount = page.getTotalCount();
        vo.setTotalNum(totalCount);

        if (!noTotal) {
            //调用一次合计
            if (hasCountPerPage || (isFirst && CollectionUtils.isNotEmpty(list))) {
                if (hasCountPerPage && CollectionUtils.isEmpty(list)) {
                    list = new ArrayList<>();
                }
                jsonObject.put("pageNum", 1);

                jsonObject.put("storeGroup", 8);
                JSONObject total = getTotalJson(jsonObject, apolloKey);
                if (total == null) {
                    total = new JSONObject();
                }
                if (isStore) {
                    total.put("storeName", "合计（" + totalCount + "）");
                } else {
                    total.put("storeGroupName", "合计（" + totalCount + "）");
                }
                total.put("storeGroupId", "all");

                list.add(0, total);
            }
        }
        vo.setRows(list);

        if (clazz != null && CollectionUtils.isNotEmpty(vo.getRows())) {
            vo.setRows(JSONArray.parseArray(JSON.toJSONString(vo.getRows()), clazz));
        }
        return vo;
    }

    @Deprecated
    public DataPageVO getDataCommonParent(String searchDataParams, Integer currentPage, String logStr, Integer pageSize, boolean hasCountPerPage, boolean noTotal) {
        return getData(new DataApiQO().setSearchDataParams(searchDataParams)
                .setCurrentPage(currentPage)
                .setLogStr(logStr)
                .setPageSize(pageSize)
                .setHasCountPerPage(hasCountPerPage)
                .setNoTotal(noTotal));
    }

    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) {
        return getPreStoreIdListCommon(preStoreGroupId, enterpriseId, null);
    }

    public List<String> getPreStoreIdListCommon(String preStoreGroupId, String enterpriseId, List<String> statusList) {
        preStoreGroupId = getPreStoreGroupId(preStoreGroupId, enterpriseId);
        String[] queryArr = new String[]{preStoreGroupId};

        List<String> defaultStatusList = getAllStoreStatus();
        if (CollectionUtils.isNotEmpty(statusList)) {
            defaultStatusList.retainAll(statusList);
        }
        List<String> storeIdList = storeService.getStoreIdListByGroupId(queryArr,
                defaultStatusList.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 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;
    }
}
