package jnpf.store.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jnpf.base.UserInfo;
import jnpf.base.service.SuperServiceImpl;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.entity.StoreEntity;
import jnpf.entity.StoreRegion;
import jnpf.entity.StoreUserEntity;
import jnpf.exception.HandleException;
import jnpf.model.store.*;
import jnpf.model.store.dto.BatchSaveStoreDto;
import jnpf.model.store.dto.StoreUserDto;
import jnpf.model.store.vo.StoreBaseListVO;
import jnpf.model.store.vo.StoreLocationVO;
import jnpf.model.store.vo.StoreUsersVo;
import jnpf.model.store.vo.UserStoreListVo;
import jnpf.model.vo.StoreExecutionVo;
import jnpf.permission.FTBApi;
import jnpf.permission.OrganizeApi;
import jnpf.permission.PositionApi;
import jnpf.permission.UserApi;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.model.organize.OrganizeNewVo;
import jnpf.permission.model.user.*;
import jnpf.store.mapper.StoreMapper;
import jnpf.store.mapper.StoreUserMapper;
import jnpf.store.service.StoreRegionService;
import jnpf.store.service.StoreService;
import jnpf.store.service.StoreUserService;
import jnpf.util.JsonUtil;
import jnpf.util.RandomUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 门店管理
 * 版本： V3.1.0
 * 版权： 引迈信息技术有限公司（https://www.jnpfsoft.com）
 * 作者： JNPF开发平台组
 * 日期： 2023-07-11
 */
@Service
@Slf4j
public class StoreServiceImpl extends SuperServiceImpl<StoreMapper, StoreEntity> implements StoreService {

    @Autowired
    private UserProvider userProvider;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private StoreUserMapper storeUserMapper;

    @Autowired
    private StoreUserService storeUserService;
    @Autowired
    private StoreRegionService storeRegionService;

    @Autowired
    private UserApi userApi;

    @Autowired
    private PositionApi positionApi;

    @Autowired
    private OrganizeApi organizeApi;

    @Autowired
    private FTBApi ftbApi;

    @Autowired
    private UserApiV2Util userApiV2Util;

    private static int calculateLineDistance(double longitude, double latitude, double longitude2, double latitude2) {
        double var2 = longitude;
        double var4 = latitude;
        double var6 = longitude2;
        double var8 = latitude2;
        var2 *= 0.01745329251994329D;
        var4 *= 0.01745329251994329D;
        var6 *= 0.01745329251994329D;
        var8 *= 0.01745329251994329D;
        double var10 = Math.sin(var2);
        double var12 = Math.sin(var4);
        double var14 = Math.cos(var2);
        double var16 = Math.cos(var4);
        double var18 = Math.sin(var6);
        double var20 = Math.sin(var8);
        double var22 = Math.cos(var6);
        double var24 = Math.cos(var8);
        double[] var27 = new double[3];
        double[] var28 = new double[3];
        var27[0] = var16 * var14;
        var27[1] = var16 * var10;
        var27[2] = var12;
        var28[0] = var24 * var22;
        var28[1] = var24 * var18;
        var28[2] = var20;
        float v = (float) (Math.asin(Math.sqrt((var27[0] - var28[0]) * (var27[0] - var28[0]) + (var27[1] - var28[1]) * (var27[1] - var28[1]) + (var27[2] - var28[2]) * (var27[2] - var28[2])) / 2.0D) * 1.27420015798544E7D);
        return Math.round(v);
    }

    @Override
    public List<Store> getStoreByOrganizeId(String organizeId) {
        // 1.根据organizeId查询出对应的门店列表
        // 2.判断门店列表是否为空
        //  2.1.为空，直接返回
        //  2.2.不为空，查询返回
        List<StoreEntity> storeEntities = storeMapper.getStoresByOrganizeId(organizeId);
        if (storeEntities.size() == 0) {
            return null;
        }
        List<Store> storesList = storeEntities.stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, Store.class)).collect(Collectors.toList());
        List<Store> stores = storesList.stream().map(this::parseStoreDetail).collect(Collectors.toList());
        return stores;
    }

    @Override
    public PageInfo<Store> getStoreByKeyword(String keyword, int currentPage, int pageSize, Integer searchStatus) {

        PageHelper.startPage(currentPage, pageSize);
        PageInfo<StoreEntity> pageEntity = new PageInfo<>(storeMapper.getStoresByPage(keyword, searchStatus));
        List<Store> storesList = pageEntity.getList().stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, Store.class)).collect(Collectors.toList());
        List<Store> stores = storesList.stream().map(this::parseStoreDetail).collect(Collectors.toList());
        PageInfo<Store> page = new PageInfo<>();
        BeanUtils.copyProperties(pageEntity, page);
        stores.forEach(store -> {
            if ("0".equals(store.getDisabled())) {
                store.setDisabled("false");
                store.setDisableStatus("已启用");
            } else if ("1".equals(store.getDisabled())) {
                store.setDisabled("true");
                store.setDisableStatus("已禁用");
            }
        });
        if (CollUtil.isNotEmpty(stores)) {
            stores.sort(Comparator.comparing(Store::getDisabled));
        }
        page.setList(stores);
        return page;
    }

    @Override
    public List<Store> getStoreEnabled() {
        List<StoreEntity> storeEntities = storeMapper.getStoresEnabled();
        if (storeEntities.size() == 0) {
            return new ArrayList<>();
        }
        List<Store> storesList = storeEntities.stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, Store.class)).collect(Collectors.toList());

        //门店的用户 组织信息
        List<String> headUserIds = storesList.stream().map(Store::getStoreHeadUserId).collect(Collectors.toList());
        UserInfoMapByIdsPost userInfoMapByIdsPost = new UserInfoMapByIdsPost();
        userInfoMapByIdsPost.setUserIds(headUserIds);
        //门店负责人用户信息查询
        Map<String, PartUserInfoVo> infoMapByIdsPost = userApi.getInfoMapByIdsPost(userInfoMapByIdsPost);

        //门店组织信息查询
        List<String> orgIdList = new ArrayList<>();
        for (Store store : storesList) {
            String[] orgIdArr = store.getOrganizeId().split(",");
            orgIdList.addAll(ListUtil.toList(orgIdArr));
        }

        List<OrganizeEntity> orgList = organizeApi.getOrganizeByIds(orgIdList);
        Map<String, OrganizeEntity> orgMap = orgList.stream().collect(Collectors.toMap(OrganizeEntity::getId, org -> org));


        for (Store store : storesList) {
            //负责人信息
            PartUserInfoVo partUserInfoVo = infoMapByIdsPost.get(store.getStoreHeadUserId());
            store.setStoreHeadUserName(partUserInfoVo == null ? null : partUserInfoVo.getRealName());

            //组织信息
            String organizeid = store.getOrganizeId();
            if (organizeid.contains(",")) {
                //多个组织
                String[] split = organizeid.split(",");
                List<String> orgNameList = new ArrayList<>();
                for (String orgId : split) {
                    OrganizeEntity organizeEntity = orgMap.get(orgId);
                    if (organizeEntity != null) {
                        orgNameList.add(organizeEntity.getFullName());
                    }
                }
                String orgNameJoin = CollectionUtil.join(orgNameList, "/");
                store.setOrganizeName(orgNameJoin);
            } else {
                //只有一个组织
                OrganizeEntity organizeEntity = orgMap.get(organizeid);
                store.setOrganizeName(organizeEntity == null ? null : organizeEntity.getFullName());
            }
        }
//        List<Store> stores = storesList.stream().map(this::parseStoreDetail).collect(Collectors.toList());
        return storesList;
    }

    @Override
    public List<Store> getStoreByRange(String organizeId, String longitude, String latitude) {
        // 1.判断organizeId是否为空
        //  1.1.为空，查询所有门店
        //  1.2.不为空，根据organizeId查询门店
        // 2.将门店实体转换为门店模型
        // 3.根据查出的经纬度，和传入的经纬度计算每个门店的距离
        // 4.根据距离排序
        List<StoreEntity> storeEntities = new ArrayList<>();
        if (StringUtils.isEmpty(organizeId)) {
            storeEntities = storeMapper.getStores();
        } else {
            storeEntities = storeMapper.getStoresByOrganizeId(organizeId);
        }
        List<Store> storesList = storeEntities.stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, Store.class)).collect(Collectors.toList());
        List<Store> stores = storesList.stream().map(store -> {
            try {
                if (StringUtils.isNotEmpty(store.getLatitude()) && StringUtils.isNotEmpty(store.getLongitude())) {
                    int distance = this.calculateLineDistance(Double.parseDouble(longitude), Double.parseDouble(latitude), Double.parseDouble(store.getLongitude()), Double.parseDouble(store.getLatitude()));
                    store.setDistance(distance);
                } else {
                    store.setDistance(0);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("查询门店列表 距离计算失败");
                store.setDistance(0);
            }
            return store;
        }).collect(Collectors.toList());
        Collections.sort(stores, Comparator.comparingInt(Store::getDistance));
        return stores;
    }

    @Override
    public Store getInfo(String id) {
        StoreEntity storeEntity = storeMapper.getStoreById(id);
        if (ObjectUtils.isEmpty(storeEntity)) {
            return null;
        }
        List<StoreUserEntity> storeUsers = storeUserService.getUsersByStoreId(id);
        storeEntity.setUsers(storeUsers);
        Store store = JsonUtil.getJsonToBean(storeEntity, Store.class);
        List<StoreUser> users = store.getUsers().stream().map(this::parseStoreUserDetail).collect(Collectors.toList());
        store.setUsers(users);
        store = this.parseStoreDetail(store);
        return store;
    }

    @Override
    public StoreEntity getStoreInfoDutyQuery(String id) {

        return this.getById(id);
    }

    @Override
    @Transactional
    public void create(Store store) throws Exception {
        if (store.getSetRegion().equals(0) && store.getRegionList().size() > 1) {
            if (store.getRegionList().size() > 1) {
                throw new Exception("设置区域开关未打开，区域数量超限");
            }
            if (!store.getRegionList().get(0).getIsDefault().equals(1)) {
                throw new Exception("参数不正确，是否默认数据未打开");
            }
        }
        if (store.getSetRegion().equals(1)) {
            if (store.getRegionList().stream().map(StoreRegionVo::getIsDefault).collect(Collectors.toList()).contains(1)) {
                throw new Exception("参数不正确，设置区域开关已打开，区域列表包含默认数据");
            }
        }
        // 判断门店是否存在
        int count = storeMapper.getStoreByName(store.getStoreName(), null);
        if (count > 0) {
            throw new HandleException("门店已存在");
        }
        StoreEntity storeEntity = JsonUtil.getJsonToBean(store, StoreEntity.class);
        storeEntity = this.initStoreEntity(storeEntity);
        storeEntity.setDisabled(StrUtil.isBlank(store.getDisabled()) ? 0 : 1);
        storeMapper.createStore(storeEntity);
        /** 设置门店区域*/
        storeRegionService.batchSaveOrUpdateOrDelete(storeEntity.getId(), store.getRegionList());
        /** 同步组织门店数量*/
        organizeApi.storeNumAdd(store.getOrganizeId(), 1);
        if (storeEntity.getUsers().size() == 0) {
            return;
        }
        String storeId = storeEntity.getId();
        List<StoreUserEntity> users = storeEntity.getUsers();
        List<StoreUserEntity> storeUserEntities = users.stream().map(storeUserEntity -> this.initStoreUserEntity(storeUserEntity, storeId)).collect(Collectors.toList());
        storeUserService.createStoreUsers(storeUserEntities);
    }

    @Override
    @Transactional
    public void update(String id, Store store) throws Exception {
        int count = storeMapper.getStoreByName(store.getStoreName(), id);
        if (count > 0) {
            throw new Exception("门店已存在");
        }
        String userId = userProvider.get().getUserId();
        StoreEntity storeEntity = JsonUtil.getJsonToBean(store, StoreEntity.class);
        storeEntity.setLastmodifyuserid(userId);
        storeEntity.setLastmodifytime(DateTime.now());
        storeMapper.update(storeEntity.getId(), storeEntity);
        /** 新增、更新、删除门店区域*/
        storeRegionService.batchSaveOrUpdateOrDelete(storeEntity.getId(), store.getRegionList());
    }

    /**
     * 检查门店是否有负责人
     *
     * @param id
     */
    @Override
    public Boolean checkStore(String id) {
        StoreEntity storeEntity = storeMapper.selectById(id);
        return storeEntity != null && StrUtil.isNotBlank(storeEntity.getStoreheaduserid());
    }

    @Override
    public void updateStatus(String id, Boolean disabled) {
        StoreEntity storeEntity = storeMapper.selectById(id);
        storeEntity.setDisabled(disabled ? 1 : 0);
        //如果是禁用门店则清空负责人信息,和组织信息
        if (disabled) {
            storeEntity.setStoreheaduserid("");
            //如果当前组织不存在了,则清空组织信息
            OrganizeEntity organizeEntity = organizeApi.getInfoById(storeEntity.getOrganizeid());
            if (organizeEntity == null) {
                storeEntity.setOrganizeid("");
            }
        }
        storeMapper.updateById(storeEntity);
    }

    @Override
    public String checkForm(Store form, int i) {
        int total = 0;
        boolean isUp = StringUtil.isNotEmpty(form.getId()) && !form.getId().equals("0");
        String id = "";
        String countRecover = "";
        if (isUp) {
            id = form.getId();
        }

        return countRecover;
    }

    @Override
    public List<Store> getStoreList(String organizeId, String storeName) {

        if (StringUtils.isEmpty(organizeId)) {
            // 组织id为空, 查询所有门店
            return storeMapper.getAllStoreList(null, storeName);
        }
        // 组织id不为空, 查询组织及子组织下的门店
        List<String> organizeIds = organizeApi.getChildrenById(organizeId);
        if (organizeIds.isEmpty()) {
            return new ArrayList<>();
        }
        return storeMapper.getAllStoreList(organizeIds, storeName);
    }

    @Override
    public List<Store> getUserStoreList() {

        return storeMapper.getUserStoreList(userProvider.get().getUserId());
    }

    @Override
    public List<Store> getUserStoreListDuty() {
        UserInfo user = UserProvider.getUser();
        List<UserBoundMoreInfoVO> userRelationEntities = userApi.getUserBoundMoreInfosByUserIdsNoToken(List.of(user.getUserId()), user.getTenantId());

        List<String> positionIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(userRelationEntities)) {
            positionIds.addAll(userRelationEntities.stream().map(UserBoundMoreInfoVO::getPositionId).distinct().collect(Collectors.toList()));
        }
        return storeMapper.getUserStoreListDuty(userProvider.get().getUserId(), positionIds);
    }

    @Override
    public List<String> checkUserCantChoose(String currentChoose, String exceptChoose) {

        String[] chooseArray = currentChoose.split(",");
        List<String> chooseList = Arrays.asList(chooseArray);
        List<String> exceptList = new ArrayList<>();
        if (!StringUtils.isEmpty(exceptChoose)) {
            String[] split = exceptChoose.split(",");
            exceptList = Arrays.asList(split);
        }
        return storeMapper.checkUserCantChoose(chooseList, exceptList);
    }

    @Override
    public List<Store> getStoreListByUser(String userId) {

        List<OrganizeInfoVo> organizeList = userApi.getUserOrganizeInfoByUserId(userId);
        if (organizeList.isEmpty()) {
            return new ArrayList<>();
        }
        List<String> organizeIds = organizeList.stream().map(OrganizeInfoVo::getOrganizeId).collect(Collectors.toList());
        return storeMapper.getStoreListByOrganizeIds(organizeIds);
    }

    @Override
    public List<Store> getStoreListByUserNodata(String userId, String tenantId) {

        List<OrganizeInfoVo> organizeList = userApi.getUserOrganizeInfoByUserIdNodata(userId, tenantId);
        if (organizeList.isEmpty()) {
            return new ArrayList<>();
        }
        List<String> organizeIds = organizeList.stream().map(OrganizeInfoVo::getOrganizeId).collect(Collectors.toList());
        return storeMapper.getStoreListByOrganizeIds(organizeIds);
    }

    @Override
    public List<Store> getListByIds(List<String> storeIds) {

        List<StoreEntity> storeList = storeMapper.getStoreByIds(storeIds);
        if (storeList.isEmpty()) {
            return new ArrayList<>();
        }
        List<Store> storesList = JsonUtil.getJsonToList(storeList, Store.class);
        return storesList.stream().map(this::parseStoreDetail).collect(Collectors.toList());
    }

    @Override
    public List<StorePositionInfoVo> getStorePositionInfoList(String storeId, List<String> positionList) {

        List<StorePositionInfoVo> returnList = new ArrayList<>();
        // 查询门店下的用户
        List<String> userIds = storeUserMapper.getStoreUserList(storeId);
        if (userIds.isEmpty()) {
            positionList.forEach(position -> {
                returnList.add(new StorePositionInfoVo(position));
            });
            return returnList;
        }
        // 查询用户岗位信息
        List<PositionInfoVo> userPositionList = ftbApi.getPositionInfoByUserList(userIds);
        Map<String, StorePositionInfoVo> map = new HashMap<>();
        positionList.forEach(position -> {
            StorePositionInfoVo vo = map.get(position);
            if (null == vo) {
                vo = new StorePositionInfoVo(position);
                map.put(position, vo);
            }
            // 筛选岗位下的门店成员
            List<String> userIdList = userPositionList.stream().filter(v -> v.getPositionId().equals(position)).map(PositionInfoVo::getUserId).distinct().collect(Collectors.toList());
            if (!userIdList.isEmpty()) {
                vo.setStoreUserNum(userIdList.size());
                vo.getUserIdList().addAll(userIdList);
            }
        });
        returnList.addAll(map.values());
        return returnList;
    }

    @Override
    public List<StorePositionInfoVo> getStorePositionInfoListNodata(String storeId, List<String> positionList, String tenantId) {

        List<StorePositionInfoVo> returnList = new ArrayList<>();
        // 查询门店下的用户
        List<String> userIds = storeUserMapper.getStoreUserList(storeId);
        if (userIds.isEmpty()) {
            positionList.forEach(position -> {
                returnList.add(new StorePositionInfoVo(position));
            });
            return returnList;
        }
        // 查询用户岗位信息
        List<PositionInfoVo> userPositionList = ftbApi.getPositionInfoByUserListNodata(userIds, tenantId);
        Map<String, StorePositionInfoVo> map = new HashMap<>();
        positionList.forEach(position -> {
            StorePositionInfoVo vo = map.get(position);
            if (null == vo) {
                vo = new StorePositionInfoVo(position);
                map.put(position, vo);
            }
            // 筛选岗位下的门店成员
            List<String> userIdList = userPositionList.stream().filter(v -> v.getPositionId().equals(position)).map(PositionInfoVo::getUserId).distinct().collect(Collectors.toList());
            if (!userIdList.isEmpty()) {
                vo.setStoreUserNum(userIdList.size());
                vo.getUserIdList().addAll(userIdList);
            }
        });
        returnList.addAll(map.values());
        return returnList;
    }

    @Override
    public List<StoreUserNumVo> getUserNum(List<String> storeIds) {
        List<StoreUserNumVo> storeUserNumVos = new ArrayList<>();
        for (String storeId : storeIds) {
            StoreUserNumVo storeUserNumVo = new StoreUserNumVo();
            List<String> userIds = storeUserMapper.getStoreUserList(storeId);
            storeUserNumVo.setId(storeId);
            storeUserNumVo.setUserNum(null == userIds ? 0 : userIds.size());
            storeUserNumVos.add(storeUserNumVo);
        }
        return storeUserNumVos;
    }

    private StoreEntity initStoreEntity(StoreEntity storeEntity) {
        DateTime nowTime = DateTime.now();
        String storeId = RandomUtil.uuId();
        String userId = userProvider.get().getUserId();
        storeEntity.setId(storeId);
        storeEntity.setCreatoruserid(userId);
        storeEntity.setCreatortime(nowTime);
        storeEntity.setLastmodifyuserid(userId);
        storeEntity.setLastmodifytime(nowTime);
        return storeEntity;
    }

    private StoreUserEntity initStoreUserEntity(StoreUserEntity storeUser, String storeId) {
        DateTime nowTime = DateTime.now();
        String userId = userProvider.get().getUserId();
        storeUser.setStoreId(storeId);
        storeUser.setCreatorUserId(userId);
        storeUser.setCreatorTime(nowTime);
        storeUser.setLastModifyUserId(userId);
        storeUser.setLastModifyTime(nowTime);
        return storeUser;
    }

    private Store parseStoreDetail(Store store) {
        UserEntity user = userApi.getInfoById(store.getStoreHeadUserId());
        store.setStoreHeadUserName(Objects.isNull(user) ? "" : user.getRealName());
        if (StringUtils.contains(store.getOrganizeId(), ",")) {
            String[] split = store.getOrganizeId().split(",");
            StringBuilder organizeName = new StringBuilder();
            for (int i = 0; i < split.length; i++) {
                OrganizeEntity organize = organizeApi.getInfoById(split[i]);
                if (Objects.isNull(organize)) {
                    continue;
                }
                organizeName.append(organize.getFullName());
                if (i < split.length - 1) {
                    organizeName.append("/");
                }
            }
            store.setOrganizeName(organizeName.toString());
        } else {
            OrganizeEntity organize = organizeApi.getInfoById(store.getOrganizeId());
            store.setOrganizeName(Objects.isNull(organize) ? "" : organize.getFullName());
        }
        //设置区域信息
        if (Objects.isNull(store.getSetRegion())) {
            store.setSetRegion(0);
        }
        if (store.getSetRegion().equals(0)) {
            StoreRegion storeRegion = this.storeRegionService.lambdaQuery()
                    .eq(StoreRegion::getStoreId, store.getId())
                    .eq(StoreRegion::getIsDefault, 1)
                    .eq(StoreRegion::getDeleteMark, 0)
                    .last("limit 1")
                    .one();
            if (Objects.isNull(storeRegion)) {
                store.setRegionList(List.of(StoreRegionVo.builder()
                        .isDefault(1)
                        .deskCount(0)
                        .seatCount(0)
                        .build()));
            } else {
                store.setRegionList(List.of(StoreRegionVo.builder()
                        .id(storeRegion.getId())
                        .isDefault(storeRegion.getIsDefault())
                        .name(storeRegion.getName())
                        .deskCount(storeRegion.getDeskCount())
                        .seatCount(storeRegion.getSeatCount())
                        .build()));
            }
        } else {
            List<StoreRegion> storeRegionList = this.storeRegionService.lambdaQuery()
                    .eq(StoreRegion::getStoreId, store.getId())
                    .eq(StoreRegion::getIsDefault, 0)
                    .eq(StoreRegion::getDeleteMark, 0)
                    .list();
            if (CollUtil.isNotEmpty(storeRegionList)) {
                store.setRegionList(storeRegionList.stream().map(item -> StoreRegionVo.builder()
                        .id(item.getId())
                        .name(item.getName())
                        .isDefault(item.getIsDefault())
                        .deskCount(item.getDeskCount())
                        .seatCount(item.getSeatCount())
                        .build()).collect(Collectors.toList()));
            }
        }
        return store;
    }

//    private static int calculateDistance(double lon1, double lat1, double lon2, double lat2) {
//        GeometryFactory geometryFactory = new GeometryFactory();
//        Coordinate coord1 = new Coordinate(lon1, lat1);
//        Coordinate coord2 = new Coordinate(lon2, lat2);
//        Point point1 = geometryFactory.createPoint(coord1);
//        Point point2 = geometryFactory.createPoint(coord2);
//
//        double distance = point1.distance(point2);
//        return (int) Math.round(distance);
//    }

    private StoreUser parseStoreUserDetail(StoreUser storeUser) {
        List<PartUserInfoVo> list = userApi.getInfoByIds(Stream.of(storeUser.getUserid()).collect(Collectors.toList()));
        if (!list.isEmpty()) {
            PartUserInfoVo user = list.get(0);
            storeUser.setMobilenum(user.getMobilePhone());
            storeUser.setUsername(user.getRealName());
            storeUser.setPosition(user.getPositionName());
            storeUser.setOrganizeName(user.getOrganizeName());
            storeUser.setAccount(user.getAccount());
        }
        return storeUser;
    }

    /**
     * 批量新增门店
     *
     * @param batchSaveStoreDto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchSaveStore(BatchSaveStoreDto batchSaveStoreDto) throws HandleException {
        String organizeid = batchSaveStoreDto.getOrganizeid();
        QueryWrapper<StoreEntity> checkIsExistStoreWrapper = new QueryWrapper<>();
        checkIsExistStoreWrapper.lambda()
                .eq(StoreEntity::getOrganizeid, organizeid);
        List<StoreEntity> storeListByOrgId = storeMapper.selectList(checkIsExistStoreWrapper);
        if (CollectionUtil.isNotEmpty(storeListByOrgId)) {
            return;
        }
        if (StrUtil.isBlank(batchSaveStoreDto.getOrganizeid())) {
            throw new HandleException("请选择组织");
        }

        /** 门店批量新增*/
        List<Store> storeList = batchSaveStoreDto.getStoreList();
        List<String> hasStore = new ArrayList<>();
        List<StoreEntity> storeEntityList = new ArrayList<>();
        List<StoreRegion> storeRegionList = new ArrayList<>();
        List<StoreUserEntity> storeUserList = new ArrayList<>();
        for (Store store : storeList) {
            if (store.getSetRegion().equals(0) && store.getRegionList().size() > 1) {
                if (store.getRegionList().size() > 1) {
                    throw new HandleException("设置区域开关未打开，区域数量超限");
                }
                if (!store.getRegionList().get(0).getIsDefault().equals(1)) {
                    throw new HandleException("参数不正确，是否默认数据未打开");
                }
            }
            if (store.getSetRegion().equals(1)) {
                if (store.getRegionList().stream().map(StoreRegionVo::getIsDefault).collect(Collectors.toList()).contains(1)) {
                    throw new HandleException("参数不正确，设置区域开关已打开，区域列表包含默认数据");
                }
            }
            // 判断门店是否存在
            int count = storeMapper.getStoreByNameAndOrgId(store.getStoreName(), organizeid);
            if (count > 0) {
                hasStore.add(store.getStoreName());
                break;
            }
            StoreEntity storeEntity = JsonUtil.getJsonToBean(store, StoreEntity.class);
            storeEntity = this.initStoreEntity(storeEntity);
            storeEntity.setDisabled(1);
            storeEntity.setOrganizeid(batchSaveStoreDto.getOrganizeid());
            storeEntityList.add(storeEntity);
            /** 门店与值班人员id关联*/
            List<StoreUser> users = store.getUsers();
            List<StoreUserEntity> storeUserEntityList = JsonUtil.getJsonToList(users, StoreUserEntity.class);
            if (CollectionUtil.isNotEmpty(users)) {
                for (StoreUserEntity user : storeUserEntityList) {
                    user.setStoreId(storeEntity.getId());
                    initStoreUserEntity(user, storeEntity.getId());
                }
            }
            storeUserList.addAll(storeUserEntityList);
            List<StoreRegion> regionList = storeRegionService.getStoreRegionList(storeEntity.getId(), store.getRegionList());
            if (CollUtil.isNotEmpty(regionList)) {
                storeRegionList.addAll(regionList);
            }
        }
        if (CollectionUtil.isNotEmpty(hasStore)) {
            throw new HandleException("门店" + CollectionUtil.join(hasStore, ",") + "已存在");
        }
        /** 批量新增门店信息*/
        if (CollUtil.isNotEmpty(storeEntityList)) {
            saveBatch(storeEntityList);
        }
        /** 批量新增门店区域列表*/
        if (CollUtil.isNotEmpty(storeRegionList)) {
            storeRegionService.saveOrUpdateBatch(storeRegionList);
        }
        organizeApi.storeNumAdd(batchSaveStoreDto.getOrganizeid(), CollectionUtil.size(storeEntityList));
        if (CollectionUtil.isEmpty(storeUserList)) {
            return;
        }
        /** 批量新增门店值班人员*/
        storeUserService.saveBatch(storeUserList);
    }

    @Override
    public List<UserStoreListVo> getAllUserStores() {
        List<UserStoreListVo> userStoreListVos = new ArrayList<>();
        List<FtbUserOrgVo> allUserOrgList = userApi.getAllUserOrgList();
        if (null != allUserOrgList && allUserOrgList.size() > 0) {
            // 查询所有门店
            List<Store> allStore = storeMapper.getAllStore();
            Map<String, List<Store>> storeMap;
            if (null != allStore && allStore.size() > 0) {
                storeMap = allStore.stream().collect(Collectors.groupingBy(Store::getOrganizeId));
            } else {
                storeMap = null;
            }
            allUserOrgList.forEach(v -> {
                UserStoreListVo userStoreListVo = new UserStoreListVo();
                userStoreListVo.setUserId(v.getUserId());
                if (null != storeMap) {
                    List<Store> list = new ArrayList<>();
                    for (String orgId : v.getOrgIds().split(",")) {
                        List<Store> store = storeMap.get(orgId);
                        if (null != store) {
                            list.addAll(store);
                        }
                    }
                    userStoreListVo.setStores(list);
                }
                userStoreListVos.add(userStoreListVo);
            });
        }
        return userStoreListVos;
    }

    @Override
    public PageInfo<StoreUsersVo> getUsersByStore(String keyword, int currentPage, int pageSize) {
        PageHelper.startPage(currentPage, pageSize);
        PageInfo<StoreEntity> pageEntity = new PageInfo<>(storeMapper.getStoresByStorePage(keyword));
        List<StoreUsersVo> storesList = pageEntity.getList().stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, StoreUsersVo.class)).collect(Collectors.toList());
        List<String> collect = storesList.stream().map(StoreUsersVo::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)) {
            PageInfo<StoreUsersVo> page = new PageInfo<>();
            page.setTotal(pageEntity.getTotal());
            page.setPageNum(currentPage);
            page.setPageSize(pageSize);
            page.setList(storesList);
            return page;
        }
        List<StoreUserEntity> usersByStoreId = storeUserService.getUsersByStoreId(collect);
        if (CollUtil.isEmpty(usersByStoreId)) {
            PageInfo<StoreUsersVo> page = new PageInfo<>();
            page.setTotal(pageEntity.getTotal());
            page.setPageNum(currentPage);
            page.setPageSize(pageSize);
            page.setList(storesList);
            return page;
        }
        List<StoreUser> storeUsers = BeanUtil.copyToList(usersByStoreId, StoreUser.class);
        List<String> userIds = usersByStoreId.stream().map(StoreUserEntity::getUserId).collect(Collectors.toList());
        List<PartUserInfoVo> list = userApi.getInfoByIds(userIds);
        Map<String, PartUserInfoVo> collect2 = list.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, vo -> vo));
        // 查询岗位信息
        List<String> organizeIds = usersByStoreId.stream().map(StoreUserEntity::getOrganizeId).collect(Collectors.toList());
        List<OrganizeInfoVo> organizeList = userApi.getOrganizeListByIds(organizeIds);
        // 查询岗位信息
        List<String> positionIds = usersByStoreId.stream().map(StoreUserEntity::getPositionId).collect(Collectors.toList());
        List<PositionInfoVo> positionList = userApi.getPositionListByIds(positionIds);
        // 查询组织信息
        List<String> gradeIds = usersByStoreId.stream().map(StoreUserEntity::getGradeId).collect(Collectors.toList());
        List<GradeInfoVo> gradeList = userApi.getGradeListByIds(gradeIds);
        // 补全信息
        storeUsers.forEach(storeUser -> {
            PartUserInfoVo user = collect2.get(storeUser.getUserid());
            if (Objects.isNull(user)) {
                return;
            }
            OrganizeInfoVo organize = organizeList.stream().filter(v -> v.getOrganizeId().equals(storeUser.getOrganizeId())).findFirst().orElse(null);
            PositionInfoVo position = positionList.stream().filter(v -> v.getPositionId().equals(storeUser.getPositionId())).findFirst().orElse(null);
            GradeInfoVo grade = gradeList.stream().filter(v -> v.getGradeId().equals(storeUser.getGradeId())).findFirst().orElse(null);
            storeUser.setMobilenum(user.getMobilePhone());
            storeUser.setUsername(user.getRealName());
            storeUser.setAccount(user.getAccount());
            storeUser.setOrganizeName(null == organize ? "" : organize.getOrganizeName());
            storeUser.setPosition(null == position ? "" : position.getPositionName());
            storeUser.setGradeName(null == grade ? "" : grade.getGradeName());
        });
        Map<String, List<StoreUser>> collect1 = storeUsers.stream().collect(Collectors.groupingBy(StoreUser::getStoreid));
        storesList.forEach(vo -> {
            List<StoreUser> orDefault = collect1.getOrDefault(vo.getId(), CollUtil.newArrayList());
            vo.setUsers(orDefault.stream().filter(user -> StringUtil.isNotEmpty(user.getUsername())).collect(Collectors.toList()));
        });
        PageInfo<StoreUsersVo> page = new PageInfo<>();
        BeanUtils.copyProperties(pageEntity, page);
        page.setList(storesList);
        return page;
    }

    @Override
    public void updateStoreUsers(StoreUserDto storeUserDto) {
        storeUserService.delete(storeUserDto.getStoreId());
        if (CollectionUtils.isEmpty(storeUserDto.getUsers())) {
            return;
        }
        List<StoreUserEntity> storeUserEntities = BeanUtil.copyToList(storeUserDto.getUsers(), StoreUserEntity.class);
        List<StoreUserEntity> storeUsers = storeUserEntities.stream().map(storeUser ->
                initStoreUserEntity(storeUser, storeUserDto.getStoreId())
        ).collect(Collectors.toList());
        storeUserService.saveBatch(storeUsers);
    }

    @Override
    public PageInfo<StoreExecutionVo> getStorePageByIds(String storeIds, String storeName, Integer currentPage, Integer pageSize, Integer sortNum) {

        List<String> storeIdList = new ArrayList<>();
        if (!storeIds.equals("0")) {
            String[] split = storeIds.split(",");
            storeIdList.addAll(Arrays.asList(split));
        }
        // 查询全部
        PageHelper.startPage(currentPage, pageSize);
        return new PageInfo<>(storeMapper.getStorePageByIds(storeIdList, storeName, sortNum));
    }

    @Override
    public List<String> getAbnormalStoreIds(List<String> storeIds) {

        if (null == storeIds || storeIds.isEmpty()) {
            return new ArrayList<>();
        }
        return storeMapper.getAbnormalStoreIds(storeIds);
    }

    @Override
    public List<Store> getStoreListByOrganizeList(List<String> organizeIdList) {

        List<Store> storeList = storeMapper.getAllStoreList(organizeIdList, null);
        //设置组织名称
        if (CollectionUtil.isNotEmpty(storeList)) {
            List<String> organizeIds = storeList.stream().map(Store::getOrganizeId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(organizeIds)) {
                List<OrganizeEntity> organizeName = organizeApi.getOrganizeName(organizeIds);
                if (CollectionUtil.isNotEmpty(organizeName)) {
                    for (Store store : storeList) {
                        Optional<OrganizeEntity> organizeEntity = organizeName.stream().filter(item -> item.getId().equals(store.getOrganizeId())).findFirst();
                        organizeEntity.ifPresent(organize -> store.setOrganizeName(organize.getFullName()));
                    }
                }
            }
        }
        return storeList;
    }

    @Override
    public List<Store> getOrgStoreList(String organizeId, List<String> queryStoreIds) {

        // 组织id不为空, 查询组织及子组织下的门店
        List<OrganizeNewVo> childrenOrgById = organizeApi.getChildrenOrgById(organizeId);
        if (null == childrenOrgById || childrenOrgById.isEmpty()) {
            return new ArrayList<>();
        }
        List<String> organizeIds = childrenOrgById.stream().map(OrganizeNewVo::getOrganizeId).distinct().collect(Collectors.toList());
        List<Store> allStoreList = storeMapper.getAllStoreListNew(organizeIds, null, queryStoreIds);
        if (null != allStoreList && !allStoreList.isEmpty()) {
            Map<String, OrganizeNewVo> orgMap = childrenOrgById.stream().collect(Collectors.toMap(OrganizeNewVo::getOrganizeId, a -> a));
            allStoreList.forEach(v -> {
                OrganizeNewVo organizeNewVo = orgMap.get(v.getOrganizeId());
                if (null != organizeNewVo) {
                    v.setOrganizeName(organizeNewVo.getOrganizeName());
                    v.setParentOrganizeId(organizeNewVo.getParentOrganizeId());
                    v.setParentOrganizeName(organizeNewVo.getParentOrganizeName());
                }
            });

        }
        return allStoreList;
    }

    @Override
    public PageInfo<StoreExecutionVo> getStorePageByIds(String storeIds, Integer currentPage, Integer pageSize) {

        List<String> storeIdList = new ArrayList<>();
        if (!storeIds.equals("0")) {
            String[] split = storeIds.split(",");
            storeIdList.addAll(Arrays.asList(split));
        }
        // 查询全部
        PageHelper.startPage(currentPage, pageSize);
        return new PageInfo<>(storeMapper.getStorePageByIds(storeIdList));
    }

    @Override
    public boolean checkStoreUser(String userId) {
        return storeMapper.checkStoreUser(userId) > 0;
    }

    @Override
    public List<StoreBaseListVO> getStoreListByOrganizeIdAndChildOrganize(String organizeId, Boolean disabled) {
        List<StoreBaseListVO> vos = new ArrayList<>();
        List<String> organizeIds = organizeApi.getChildrenById(organizeId);
        if (CollUtil.isEmpty(organizeIds)) {
            return vos;
        }
        this.list(Wrappers.<StoreEntity>lambdaQuery()
                .eq(StoreEntity::getDisabled, disabled)
                .in(StoreEntity::getOrganizeid, organizeIds)
        ).forEach(storeEntity -> {
            vos.add(new StoreBaseListVO(storeEntity.getId(),
                    storeEntity.getStorename(),
                    storeEntity.getOrganizeid(),
                    storeEntity.getStoreheaduserid(),
                    storeEntity.getAddress(),
                    storeEntity.getDisabled(),
                    storeEntity.getLongitude(),
                    storeEntity.getLatitude()
            ));
        });

        return vos;
    }

    @Override
    public StoreLocationVO getStoreLocation(String storeId) {
        if (StringUtils.isEmpty(storeId)) {
            return null;
        }
        LambdaQueryWrapper<StoreEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(StoreEntity::getLongitude, StoreEntity::getLatitude, StoreEntity::getAddress);
        queryWrapper.eq(StoreEntity::getId, storeId);
        queryWrapper.last("limit 1");
        StoreEntity storeEntity = storeMapper.selectOne(queryWrapper);
        return StoreLocationVO.convert(storeEntity);
    }

    @Override
    public List<Store> getAllStoreByOrganizeId(String organizeId) {

        List<StoreEntity> storeEntities = storeMapper.getAllStoreByOrganizeId(organizeId);
        if (storeEntities.isEmpty()) {
            return null;
        }
        List<Store> storesList = storeEntities.stream().map(storeEntity -> JsonUtil.getJsonToBean(storeEntity, Store.class)).collect(Collectors.toList());
        return storesList.stream().map(this::parseStoreDetail).collect(Collectors.toList());
    }

    /**
     * 删除组织下所有门店
     *
     * @param organizeId
     */
    private void deleteStore(String organizeId) {
        /** 先删除该组织下所有门店*/
        QueryWrapper<StoreEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StoreEntity::getOrganizeid, organizeId);
        List<StoreEntity> storeEntities = storeMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(storeEntities)) {
            List<String> storeIds = storeEntities.stream().map(StoreEntity::getId).collect(Collectors.toList());
            /** 删除门店关联的值班用户*/
            UpdateWrapper<StoreUserEntity> deleteStoreUser = new UpdateWrapper<>();
            deleteStoreUser.lambda()
                    .in(StoreUserEntity::getStoreId, storeIds);
            storeUserMapper.delete(deleteStoreUser);
        }
        UpdateWrapper<StoreEntity> deleteStoreWrapper = new UpdateWrapper<>();
        deleteStoreWrapper.lambda()
                .eq(StoreEntity::getOrganizeid, organizeId);
        int deleteNum = storeMapper.delete(deleteStoreWrapper);
        organizeApi.storeNumDecr(organizeId, deleteNum);
    }

}
