package com.reyun.saas.mob.user.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.reyun.saas.common.model.NoSqlTableName;
import com.reyun.saas.common.restResult.PageParam;
import com.reyun.saas.common.restResult.RestResult;
import com.reyun.saas.common.restResult.ResultCode;
import com.reyun.saas.common.restResult.ResultGenerator;
import com.reyun.saas.common.util.IPUtils;
import com.reyun.saas.mob.user.dao.RtaWhiteListMapper;
import com.reyun.saas.mob.user.dao.UserMapper;
import com.reyun.saas.mob.user.domain.RtaWhiteList;
import com.reyun.saas.mob.user.domain.User;
import com.reyun.saas.mob.user.domain.UserCoreConfig;
import com.reyun.saas.mob.user.service.AuthService;
import com.reyun.saas.mob.user.service.NoSqlService;
import com.reyun.saas.mob.user.service.RtaWhiteListService;
import com.reyun.saas.mob.user.service.UserCoreConfigService;
import com.reyun.saas.mob.util.RoleUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

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

@Slf4j
@Service
@Transactional
public class RtaWhiteListServiceImpl implements RtaWhiteListService {


    /**
     * ddb的rta白名单主键
     */
    private static final String RTA_WHITE_LIST_KEY = "oid";

    /**
     * ddb的rta白名单存放ip的字段名
     */
    private static final String RTA_IPS_FIELD = "ip_whitelist";

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserCoreConfigService userCoreConfigService;

    @Autowired
    private RtaWhiteListMapper rtaWhiteListMapper;

    @Autowired
    private NoSqlService noSqlService;

    @Autowired
    private AuthService authService;


    @Override
    public RestResult create(Map<String, Object> map, Long loginUserId) {

        if (map.get("ips") == null) {
            return ResultGenerator.genFailResult("参数错误");
        }

        User loginUser = userMapper.selectByPrimaryKey(loginUserId);
        //如果不是主账号也不是管理员禁止修改rat ip白名单
        if(!RoleUtil.isSuperUserOrManager(loginUser)){
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        String ipsStr = (String) map.get("ips");
        String serverRemarks =  (String) map.get("serverRemarks");
        if (StringUtils.isEmpty(serverRemarks)) {
            serverRemarks = "未命名";
        }
        //从文本域传过来字符串中提取ip 并且校验ip
        Set<String> ipSet = IPUtils.getStrIps(ipsStr);
        for (String ip : ipSet) {
            if (!IPUtils.iPCheck(ip)) {
                return new RestResult(ResultCode.IP_FORMAT_ERORR);
            }
        }

        //查询当前用户的rta白名单ip
        Example rtaExample = new Example(RtaWhiteList.class);
        rtaExample.and().andEqualTo("oid", loginUser.getOid());
        rtaExample.and().andEqualTo("delFlag", false);
        List<RtaWhiteList> rtaWhiteLists = rtaWhiteListMapper.selectByExample(rtaExample);


        //区分历史重复的ip 和 新的ip
        List<String> repetitiveIps = new LinkedList<>();
        List<String> cteateIp = new LinkedList<>();
        if (!CollectionUtils.isEmpty(rtaWhiteLists)) {
            //收集用户已创建的白名单ip
            Set<String> userRtaIps = rtaWhiteLists.stream().map(RtaWhiteList::getIp).collect(Collectors.toSet());
            //收集重复的ip
            repetitiveIps = ipSet.stream().filter(userRtaIps::contains).collect(Collectors.toList());
            //收集需要创建的ip
            cteateIp = ipSet.stream().filter(v -> !userRtaIps.contains(v)).collect(Collectors.toList());
        } else {
            //如果这个用户一个rta白名单也没有则全为添加
            cteateIp.addAll(ipSet);
        }

        //查询用户的rta白名单ip数量上限
        UserCoreConfig rootCoreConfig = userCoreConfigService.findRootCoreConfig(loginUser);
        Integer rtaipNum =rootCoreConfig.getRtaipNum();

        //rta白名单IP数量达到上限
        if ((cteateIp.size() + rtaWhiteLists.size()) > rtaipNum) {
            return new RestResult(ResultCode.IP_NUM_REACH_MAX);
        }

        //本次添加的ip全部已存在
        if (repetitiveIps.size() == ipSet.size()) {
            return new RestResult(ResultCode.IP_EXIST);
        }

        for (String ip : cteateIp) {
            RtaWhiteList build = RtaWhiteList.builder()
                    .active(true)
                    .delFlag(false)
                    .createTime(new Date())
                    .createUser(loginUserId)
                    .ip(ip)
                    .oid(loginUser.getOid())
                    .serverRemarks(serverRemarks)
                    .build();
            rtaWhiteListMapper.insertSelective(build);
        }

        //同步ddb  如果发生异常会回滚
        syncRtaIp(loginUser);

        Map<String, Object> repetitiveIP = new HashMap<>();
        repetitiveIP.put("repetitiveIp", repetitiveIps);
        return ResultGenerator.genSuccessResult(repetitiveIP);
    }

    @Override
    public RestResult update(RtaWhiteList source, Long loginUserId) {

        RtaWhiteList rtaWhiteList = rtaWhiteListMapper.selectByPrimaryKey(source.getId());
        User loginUser = userMapper.selectByPrimaryKey(loginUserId);

        //如果不是主账号也不是管理员禁止修改rat ip白名单
        if(!RoleUtil.isSuperUserOrManager(loginUser)){
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        //todo 校验该此次操作的合法性  后续如果有其他的角色请留意这部分
        if (!rtaWhiteList.getOid().equals(loginUser.getOid())) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        //前端传ip为改ip
        String ip = source.getIp();
        boolean isUpdateIp = !StringUtils.isEmpty(ip);
        if (isUpdateIp) {
            //校验ip格式
            if(!IPUtils.iPCheck(ip)){
                return ResultGenerator.genResult(ResultCode.IP_FORMAT_ERORR);
            }
            //查询该ip是否已存在
            Example example = new Example(RtaWhiteList.class);
            example.and().andEqualTo("oid", loginUser.getOid());
            example.and().andEqualTo("ip", ip);
            example.and().andEqualTo("delFlag",false);
            List<RtaWhiteList> rtaWhiteLists = rtaWhiteListMapper.selectByExample(example);
            if (rtaWhiteLists != null && rtaWhiteLists.size() > 0) {
                return new RestResult(ResultCode.IP_EXIST);
            }
        }

        if (isUpdateIp) {
            rtaWhiteList.setIp(ip);
        } else {//前端不传ip为改名
            rtaWhiteList.setServerRemarks(source.getServerRemarks());
        }
        rtaWhiteList.setModifyTime(new Date());
        rtaWhiteList.setModifyUser(loginUserId);
        rtaWhiteListMapper.updateByPrimaryKeySelective(rtaWhiteList);

        //改ip时 需要同步ddb
        if (isUpdateIp) {
             syncRtaIp(loginUser);
        }

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public RestResult updateActive(Long rtaId, Boolean status, Long loginUserId) {


        User loginUser = userMapper.selectByPrimaryKey(loginUserId);
        RtaWhiteList rtaWhiteList = rtaWhiteListMapper.selectByPrimaryKey(rtaId);

        //如果不是主账号也不是管理员禁止修改rat ip白名单
        if(!RoleUtil.isSuperUserOrManager(loginUser)){
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        //校验该此次操作的合法性
        if (!rtaWhiteList.getOid().equals(loginUser.getOid())) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }


        //如果当前rtaip已经被删除 则无法修改
        if (rtaWhiteList.getDelFlag()) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        RtaWhiteList build = RtaWhiteList.builder()
                .active(status)
                .id(rtaId)
                .modifyUser(loginUserId)
                .modifyTime(new Date())
                .build();
        rtaWhiteListMapper.updateByPrimaryKeySelective(build);

        //同步ddb
        syncRtaIp(loginUser);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public RestResult deleteRta(Long rtaId, Long loginUserId) {


        User loginUser = userMapper.selectByPrimaryKey(loginUserId);
        RtaWhiteList rtaWhiteList = rtaWhiteListMapper.selectByPrimaryKey(rtaId);


        //如果不是主账号也不是管理员禁止修改rat ip白名单
        if(!RoleUtil.isSuperUserOrManager(loginUser)){
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        //校验该此次操作的合法性
        if (!rtaWhiteList.getOid().equals(loginUser.getOid())) {
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }
        //删除rta白名单ip
        RtaWhiteList build = RtaWhiteList.builder()
                .id(rtaId)
                .delFlag(true)
                .active(false)
                .modifyTime(new Date())
                .modifyUser(loginUserId)
                .build();
        rtaWhiteListMapper.updateByPrimaryKeySelective(build);

        //同步ddb
        syncRtaIp(loginUser);

        return ResultGenerator.genSuccessResult();
    }

    @Override
    public RestResult list(PageParam pageParam, Long loginUserId) {

        User loginUser = userMapper.selectByPrimaryKey(loginUserId);

        //如果不是主账号也不是管理员禁止修改rat ip白名单
        if(!RoleUtil.isSuperUserOrManager(loginUser)){
            return ResultGenerator.genResult(ResultCode.FORBID_OPERATION);
        }

        Example example = new Example(RtaWhiteList.class);
        example.and().andEqualTo("oid", loginUser.getOid());
        example.and().andEqualTo("delFlag",false);
        PageHelper.startPage(pageParam.getPage(), pageParam.getSize(), pageParam.getOrderBy());
        List<RtaWhiteList> rtaWhiteLists = rtaWhiteListMapper.selectByExample(example);
        PageInfo<RtaWhiteList> result = new PageInfo<>(rtaWhiteLists);
        return ResultGenerator.genSuccessResult(result);
    }


    /**
     * 同步tra白名单
     */
    private void syncRtaIp(User user) {
        if (user == null) {
            throw new RuntimeException("user is null");
        }
        List<RtaWhiteList> rtaByOid = findRtaByOid(user.getOid());
        Set<String> collect = rtaByOid.stream().map(RtaWhiteList::getIp).collect(Collectors.toSet());
        noSqlService.putSet(NoSqlTableName.RTA_WHITELIST,RTA_WHITE_LIST_KEY,user.getOid(),RTA_IPS_FIELD,collect);
    }

    /**
     * 根据用户oid查询rta白名单
     */
    private List<RtaWhiteList> findRtaByOid(String oid) {
        //查询当前用户的rta白名单ip
        Example example = new Example(RtaWhiteList.class);
        example.and().andEqualTo("oid", oid);
        example.and().andEqualTo("active",true);
        example.and().andEqualTo("delFlag", false);
        return rtaWhiteListMapper.selectByExample(example);
    }

}
