package com.xueyi.system.intercepts;

import com.xueyi.common.core.constant.digitalman.MessageConstants;
import com.xueyi.common.core.context.SecurityContextHolder;
import com.xueyi.common.core.utils.core.ReflectUtil;
import com.xueyi.common.core.web.tenant.base.TBaseEntity;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanWorktimePo;
import com.xueyi.system.api.digitalmans.domain.po.DmModelPo;
import com.xueyi.system.api.digitalmans.domain.po.DmSkillPo;
import com.xueyi.system.api.staff.domain.po.DmStaffPo;
import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanPo;
import com.xueyi.system.resource.domain.po.DmH5ConfigPo;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;


@Component
@Intercepts( {
        @Signature(method = "update", type = Executor.class, args = {
                MappedStatement.class,
                Object.class
        })
,      @Signature(method = "query", type = Executor.class, args = {
        MappedStatement.class, Object.class,
        RowBounds.class, ResultHandler.class
        })}
)
public class  EntityInterceptor implements Interceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(EntityInterceptor.class);
    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] objects = invocation.getArgs();
        MappedStatement ms = (MappedStatement) objects[0];
        Object paramObject = null;
        if ("INSERT".equalsIgnoreCase(ms.getSqlCommandType().toString())) {
            paramObject = objects[1];

        } else if ("UPDATE".equalsIgnoreCase(ms.getSqlCommandType().toString())) {
            if(objects[1] instanceof MapperMethod.ParamMap) {
                MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)objects[1];
                paramObject = paramMap.get("param1");
            } else if(objects[1] instanceof TBaseEntity){
                paramObject = objects[1];
            }

        }
        String enterpriseId = String.valueOf(SecurityContextHolder.getLocalMap().get("enterprise_id"));
        Long currentTime = System.currentTimeMillis();
        if (null!=paramObject  && paramObject instanceof DmStaffPo) {
            //TODO. 增加权限数据
//            if (redisTemplate.hasKey("group:dgman:" + ((DmStaffPo) paramObject).getEnterpriseId()))
//                redisTemplate.opsForList().set("group:dgman:" + enterpriseId,0,String.valueOf(currentTime));
//            else {
//                String tmp = String.valueOf(currentTime);
//
//            }

//            // 动态修改更新时间，不好用，待研究
//            if ("INSERT".equalsIgnoreCase(ms.getSqlCommandType().toString())) {
//                // 如果是员工类型且为新增
//                ReflectUtil.setFieldValue(invocation.getArgs()[1],"updateTime",LocalDateTime.now());
//                ReflectUtil.setFieldValue(invocation.getArgs()[1],"updateBy",enterpriseId);
//            }
            redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":0",String.valueOf(currentTime));
        } else if (null!=paramObject  && paramObject instanceof ArrayList) {//删除
            if (ms.getId().contains("DmStaffMapper.deleteBatchIds") ||
                    ms.getId().contains("DmVisitorsMapper.deleteBatchIds")) {
                //TODO. 修改对应权限数据
//                if (redisTemplate.hasKey("group:dgman:" + ((DmStaffPo) paramObject).getEnterpriseId()))
//                    redisTemplate.opsForList().set("group:dgman:" + enterpriseId,0,String.valueOf(currentTime));
//                else {
//                    String tmp = String.valueOf(currentTime);
//                    redisTemplate.opsForList().leftPushAll("group:dgman:" + enterpriseId,tmp,tmp,tmp,tmp,tmp);
//                }
                redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.STAFF_SYNC,String.valueOf(currentTime));
            } else if (ms.getId().contains("DmSkillMapper.deleteBatchIds")) {
                redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.SKILL_SYNC,String.valueOf(currentTime));
            }else if (ms.getId().contains("DmDigitalmanMapper.deleteBatchIds")) {
                redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime));
            }else if (ms.getId().contains("DmModelMapper.deleteBatchIds")) {
                redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime));
            }
        }

        if (null!=paramObject  && paramObject instanceof DmSkillPo) {
            redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.SKILL_SYNC,String.valueOf(currentTime));
        }
        if (null!=paramObject  && paramObject instanceof DmDigitalmanPo) {
            redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime));
        }
        if (null!=paramObject  && paramObject instanceof DmModelPo) {
            redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime));
        }
        if (null!=paramObject  && paramObject instanceof DmDigitalmanWorktimePo) {
            redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime));
        }
        if (null!=paramObject  && paramObject instanceof DmH5ConfigPo) {
            DmH5ConfigPo po = (DmH5ConfigPo)paramObject;
            redisTemplate.opsForValue().set("group:dgman:" + po.getEnterpriseId() +":" + MessageConstants.H5_CONFIG_SYNC,String.valueOf(currentTime));
        }

        return invocation.proceed();
    }

}