package com.winsea.svc.common.config;

import com.alipay.sofa.rpc.context.RpcInvokeContext;
import com.baomidou.mybatisplus.mapper.ISqlInjector;
import com.baomidou.mybatisplus.mapper.MetaObjectHandler;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.winsea.svc.common.international.InternationalResourceProviderAdapter;
import com.yh.saas.common.support.mpext.CustomSqlInjector;
import com.yh.saas.common.support.mpext.LogicDeleteFilledAspect;
import com.yh.saas.common.support.util.ContextWrapper;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.shiro.SecurityUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Date;

/**
 * Mybatis plus配置
 *
 * @author SunTianjun
 */
@Configuration
public class MybatisPlusConfig {


    /**
     * 分页插件
     */
    @ConditionalOnMissingBean(PaginationInterceptor.class)
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /**
     * 自定义SQL注入器<br/>
     * 支持逻辑删除与共通字段递增
     */
    @ConditionalOnMissingBean(ISqlInjector.class)
    @Bean
    public ISqlInjector sqlInjector() {
        return new CustomSqlInjector();
    }

    /**
     * 修改逻辑删除不能填充问题
     */
    @ConditionalOnMissingBean(LogicDeleteFilledAspect.class)
    @Bean
    public LogicDeleteFilledAspect logicDeleteFilledAspect() {
        return new LogicDeleteFilledAspect();
    }

    /**
     * 字段自动填充
     */
    @ConditionalOnMissingBean(MetaObjectHandler.class)
    @Bean
    public MetaObjectHandler metaObjectHandler() {

        final String SOFA_USER_ID_VAR_NAME = "userId";

        final String SOFA_USER_INFO_VAR_NAME = "userInfo";

        final String DEFAULT_USER = "sysadmin";

        final String CREATE_USER_ID_FIELD = "createUserId";

        final String UPDATE_USER_ID_FIELD = "updateUserId";

        final String CREATE_DATE_FIELD = "createDate";

        final String UPDATE_DATE_FIELD = "updateDate";

        final String UPDATE_FLAG_FIELD = "updateFlag";

        final String DELETE_FLAG_FIELD = "deleteFlag";

        return new MetaObjectHandler() {

            @Override
            public void insertFill(MetaObject metaObject) {
                Date currentDate = new Date();
                String currentUserId = null;
                try{
                    currentUserId = (String) SecurityUtils.getSubject().getPrincipal();
                } catch (Exception e){
                    currentUserId = RpcInvokeContext.getContext().getRequestBaggage("userId");
                }
                this.setFieldValByName(CREATE_DATE_FIELD, currentDate, metaObject);
                this.setFieldValByName(UPDATE_DATE_FIELD, currentDate, metaObject);
                this.setFieldValByName(UPDATE_FLAG_FIELD, "0", metaObject);
                this.setFieldValByName(DELETE_FLAG_FIELD, "0", metaObject);

                if (null != currentUserId) {
                    this.setFieldValByName(CREATE_USER_ID_FIELD, currentUserId, metaObject);
                    this.setFieldValByName(UPDATE_USER_ID_FIELD, currentUserId, metaObject);
                } else {
                    if (null == this.getFieldValByName(CREATE_USER_ID_FIELD, metaObject)) {
                        this.setFieldValByName(CREATE_USER_ID_FIELD, DEFAULT_USER, metaObject);
                    }

                    if (null == this.getFieldValByName(UPDATE_USER_ID_FIELD, metaObject)) {
                        this.setFieldValByName(UPDATE_USER_ID_FIELD, DEFAULT_USER, metaObject);
                    }
                }

                this.setInternationResourceId(metaObject, false);
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                String currentUserId = null;
                try{
                    currentUserId = (String) SecurityUtils.getSubject().getPrincipal();
                } catch (Exception e){
                    currentUserId = RpcInvokeContext.getContext().getRequestBaggage("userId");
                }
                if (null != currentUserId) {
                    this.setFieldValByName(UPDATE_USER_ID_FIELD, currentUserId, metaObject);
                } else if (null == this.getFieldValByName(UPDATE_USER_ID_FIELD, metaObject)) {
                    this.setFieldValByName(UPDATE_USER_ID_FIELD, DEFAULT_USER, metaObject);
                }
                this.setFieldValByName(UPDATE_DATE_FIELD, new Date(), metaObject);
                this.setFieldValByName(UPDATE_FLAG_FIELD, "1", metaObject);

                this.setInternationResourceId(metaObject, true);
            }

            /**
             * 设置国际化资源ID
             */
            private void setInternationResourceId(MetaObject metaObject, boolean updated) {
                InternationalResourceProviderAdapter iResourceProvider = null;
                try {
                    iResourceProvider = ContextWrapper.getApplicationContext()
                            .getBean(InternationalResourceProviderAdapter.class);
                } catch (Exception ex) {
                    // ignore
                }

                if (null != iResourceProvider) {
                    iResourceProvider.setInternationalText(metaObject, updated);
                }
            }

//            /**
//             * 获取当前用户ID
//             */
//            private String getCurrentUserId() {
//                try {
//                    if (null != RpcInvokeContext.getContext().getRequestBaggage(SOFA_USER_ID_VAR_NAME)) {
//                        return RpcInvokeContext.getContext().getRequestBaggage(SOFA_USER_ID_VAR_NAME);
//                    }
//                } catch (Exception ex) {
//                    // ignore
//                }
//
//                try {
//                    return (String) SecurityUtils.getSubject().getPrincipal();
//                } catch (Exception e) {
//                    return null;
//                }
//            }
        };
    }



}
