package com.usky.common.mybatis.core;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.bean.UnifiedUser;

import java.util.Date;
import java.util.Optional;

/**
 * 基础 service
 *
 * @param <M>
 * @param <T>
 * @author chenpeng
 * Create at December 2, 2018 at 14:05:49 GMT+8
 */
public abstract class AbstractCrudService<M extends BaseMapper<T>, T>
        extends ServiceImpl<M, T> implements CrudService<T> {

    private static final String DEFAULT_USER_ID = "0";
    private static final String DEFAULT_USER_NAME = "system";
    private static final UnifiedUser DEFAULT_OPERATOR = new UnifiedUser(DEFAULT_USER_ID, DEFAULT_USER_NAME);

    @Override
    public void fillDefaultOperator(T model) {
        Optional.ofNullable(model).ifPresent(m -> {
            if (model instanceof BaseModel) {
                BaseModel baseModel = (BaseModel) model;
                fillCreateOperator(baseModel, null);
                fillUpdateOperator(baseModel, null);
            }
        });
    }

    @Override
    public UnifiedUser getDefaultOperator() {
        return DEFAULT_OPERATOR;
    }

    @Override
    public void fillNecessaryOperatorProperty(T entity, UnifiedUser operator, boolean isUpdate) {
        if (entity == null) {
            return;
        }
        if (entity instanceof BaseModel) {
            BaseModel baseModel = (BaseModel) entity;
            if (isUpdate) {
                fillUpdateAt(baseModel);
                fillUpdateOperator(baseModel, operator);
            } else {
                fillCreateAt(baseModel);
                fillCreateOperator(baseModel, operator);
                fillUpdateAt(baseModel);
                fillUpdateOperator(baseModel, operator);
            }
        }
    }

    @Override
    public <E> CommonPage<E> ToCommonPage(IPage<E> page) {
        CommonPage<E> commonPage = new CommonPage<>();
        commonPage.setTotal(page.getTotal());
        commonPage.setCurrent(page.getCurrent());
        commonPage.setRecords(page.getRecords());
        commonPage.setSize(page.getSize());
        return commonPage;
    }

    private void fillUpdateOperator(BaseModel baseModel, UnifiedUser operator) {
        if (baseModel != null) {
            operator = (operator == null) ? DEFAULT_OPERATOR : operator;
            baseModel.setUpdateUserId(operator.getId().toString());
            baseModel.setUpdateUserName(operator.getName());
        }
    }

    private void fillCreateOperator(BaseModel baseModel, UnifiedUser operator) {
        if (baseModel != null) {
            operator = (operator == null) ? DEFAULT_OPERATOR : operator;
            baseModel.setCreateUserId(operator.getId().toString());
            baseModel.setCreateUserName(operator.getName());
        }
    }

    private void fillUpdateAt(BaseModel baseModel) {
        if (baseModel != null) {
            baseModel.setUpdateTime(new Date());
        }
    }

    private void fillCreateAt(BaseModel baseModel) {
        if (baseModel != null) {
            baseModel.setCreateTime(new Date());
        }
    }
}
