package com.yeejoin.amos.boot.biz.config;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.yeejoin.amos.boot.biz.common.annotation.FillCommonUserField;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author Dell
 */
@Component
public class MetaHandler implements MetaObjectHandler {

    @Autowired
    private RedisUtils redisUtils;

    protected String getToken() {
        String authToken = RequestContext.getToken();
//		if (authToken == null) {
//			authToken = request.getHeader("X-Access-Token");
//		}
        return authToken;
    }

    /**
     * 新增数据拦截
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        Date currentDate = new Date();
        Class clazz = metaObject.getOriginalObject().getClass();
        FillCommonUserField annotation = (FillCommonUserField) clazz.getAnnotation(FillCommonUserField.class);
        if (annotation == null || annotation.isAutoFill()) {
            autoFillUser(metaObject, metaObject.getOriginalObject());
        }
        //如果有上传创建时间，不需要修改
//		if(metaObject.getValue("createDate")==null){
//		}
        this.setFieldValByName("createDate", currentDate, metaObject);
    }

    private void autoFillUser(MetaObject metaObject, Object entity) {
        //获取用户信息 以及当前用户登录公司部门，角色
        String userId = RequestContext.getExeUserId();
        ReginParams reginParams =
                JSONObject.parseObject(null != redisUtils.get(RedisKey.buildReginKey(userId, getToken())) ?
                        redisUtils.get(RedisKey.buildReginKey(userId, getToken())).toString() : null, ReginParams.class);
        if (ObjectUtils.isEmpty(reginParams)) {
            return;
        }
        AgencyUserModel agencyUserModel = reginParams.getUserModel();

        if (ObjectUtils.isEmpty(reginParams) || ObjectUtils.isEmpty(agencyUserModel)) {
            return;
        }

        // 更新rec字段
        recInfoUpdate(metaObject, agencyUserModel);

        if (isExistField("allotmentTime", entity)) {
            Date currentDate = new Date();
            this.setFieldValByName("recDate", currentDate, metaObject);
        }
        //以下为装备中转移过来的
        if (isExistField("userId", entity) && isStringField(metaObject,"userId")) {
            this.setFieldValByName("userId", String.valueOf(agencyUserModel.getUserId()), metaObject);
        }
        if (isExistField("creatorId", entity)) {
            this.setFieldValByName("creatorId", Long.valueOf(agencyUserModel.getUserId()), metaObject);
        }
        if (isExistField("userName", entity)) {
            this.setFieldValByName("userName", agencyUserModel.getRealName(), metaObject);
        }
        if (isExistField("companyName", entity)) {
            this.setFieldValByName("companyName", reginParams.getCompany().getCompanyName(), metaObject);
        }
        if (isExistField("orgCode", entity)) {
            this.setFieldValByName("orgCode", reginParams.getCompany().getOrgCode(), metaObject);
        }
        if (isExistField("departmentName", entity)) {
            this.setFieldValByName("departmentName", ObjectUtils.isEmpty(reginParams.getDepartment()) ? "" : reginParams.getDepartment().getDepartmentName(), metaObject);
        }
        if (isExistField("departmentOrgcode", entity)) {
            this.setFieldValByName("departmentOrgcode", ObjectUtils.isEmpty(reginParams.getDepartment()) ? "" : reginParams.getDepartment().getOrgCode(), metaObject);
        }
    }

    private void recInfoUpdate(MetaObject metaObject, AgencyUserModel agencyUserModel) {
        this.setFieldValByName("recUserId", agencyUserModel.getUserId(), metaObject);
        this.setFieldValByName("recUserName", agencyUserModel.getRealName(), metaObject);
        Date currentDate = new Date();
        this.setFieldValByName("recDate", currentDate, metaObject);
        this.setFieldValByName("updateTime", currentDate, metaObject);
    }

    private Boolean isExistField(String field, Object obj) {
        if (obj == null || StringUtils.isEmpty(field)) {
            return null;
        }
        Object o = JSONObject.toJSON(obj);
        JSONObject jsonObj = new JSONObject();
        if (o instanceof JSONObject) {
            jsonObj = (JSONObject) o;
        }
        return jsonObj.containsKey(field);
    }

    private Boolean isStringField(MetaObject metaObject, String fieldName) {
        Class clazz = metaObject.getOriginalObject().getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (fieldName.equals(field.getName()) && ("class java.lang.String").equals(field.getGenericType().toString())) {
                return true;
            }
        }
        return false;
    }


    /**
     * 更新拦截
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        Class clazz = metaObject.getOriginalObject().getClass();
        FillCommonUserField annotation = (FillCommonUserField) clazz.getAnnotation(FillCommonUserField.class);
        if (annotation == null || annotation.isAutoFill()) {
            String userId = RequestContext.getExeUserId();
            ReginParams reginParams =
                    JSONObject.parseObject(null != redisUtils.get(RedisKey.buildReginKey(userId, getToken())) ?
                            redisUtils.get(RedisKey.buildReginKey(userId, getToken())).toString() : null, ReginParams.class);
            if (ObjectUtils.isEmpty(reginParams)) {
                return;
            }
            AgencyUserModel agencyUserModel = reginParams.getUserModel();
            recInfoUpdate(metaObject, agencyUserModel);
        }
    }
}