package com.tax.sign.service.impl;

import com.tax.sign.model.IpModel;
import com.tax.sign.service.api.IpService;
import com.yxcheng.token.common.cache.RedisService;
import com.yxcheng.token.common.enumutil.ResultEnum;
import com.yxcheng.token.common.model.JsonResult;
import com.yxcheng.token.constants.RedisContants;
import com.yxcheng.token.utils.IpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Transactional(rollbackFor = Exception.class)
@Component
@ComponentScan(basePackages = {"com.tax.sign.dao"})
public class IpServiceImpl implements IpService {
    @Autowired
    private RedisService redisService;

    @Override
    public JsonResult<IpModel> saveIpV1(IpModel model, HttpServletRequest request) {
        model.setLevel(IpModel.getV1Name());
        putIp(request,model);
        return new JsonResult<>().successResponse();
    }

    @Override
    public JsonResult<IpModel> saveIpV2(IpModel model, HttpServletRequest request) {
        model.setLevel(IpModel.getV2Name());
        putIp(request,model);
        return new JsonResult<>().successResponse();
    }

    private void putIp(HttpServletRequest request, IpModel model) {
        String ip = IpUtil.getRequestRealIp(request);
        if(IpUtil.ping(ip)){
            IpModel ipModel = redisService.get(RedisContants.SIGN_IP_LIST + model.getLevel(), IpModel.class);
            if(ipModel == null){
                ipModel = new IpModel();
                List<String>list = new ArrayList<String>();
                list.add(ip);
                ipModel.setIpList(list);
            }else{
                if(isUpdateIp(model,ipModel,ip) && !ipModel.getIpList().contains(ip)){
                    ipModel.getIpList().add(ip);
                }
            }
            redisService.set(RedisContants.SIGN_IP_LIST + model.getLevel(),ipModel,IpModel.class);
        }
    }

    private boolean isUpdateIp(IpModel model,IpModel ipModel, String ip) {
        Map<String,String> map = redisService.get(RedisContants.SIGN_IP_LIST + "MAC", Map.class);
        if(map == null){
            map = new HashMap<>();
            map.put(model.getMac(),ip);
            redisService.set(RedisContants.SIGN_IP_LIST + "MAC",map,Map.class);
        }else{
            String oldIp = map.get(model.getMac());
            if(!oldIp.equals(ip)){
                ipModel.getIpList().remove(oldIp);
            }else {
                return false;
            }
        }
        return true;
    }


    @Override
    public JsonResult<IpModel> getIpV1() {
        return new JsonResult<>(getIp(IpModel.getV1Name())).successResponse();
    }

    @Override
    public JsonResult<IpModel> getIpV2() {
        return new JsonResult<>(getIp(IpModel.getV2Name())).successResponse();
    }

    private IpModel getIp(String name) {
        IpModel ipModel = redisService.get(RedisContants.SIGN_IP_LIST + name, IpModel.class);
        if(ipModel != null) {
            ipModel.setLevel(IpModel.getV1Name());
            ipModel.setTtl("-1");
        }
        return ipModel;
    }


}
