package com.tax.user.service.impl;

import com.tax.user.constants.UserContants;
import com.tax.user.mapper.SysApplyUserTaxnoMapper;
import com.tax.user.model.SysApplyUserTaxno;
import com.tax.user.model.SysApplyUserTaxnoExample;
import com.tax.user.service.api.SysApplyUserTaxnoService;
import com.tax.user.service.api.SysClientUserService;
import com.tax.user.service.api.SysUserTaxnoService;
import com.tax.user.utils.RuleUtils;
import com.yxcheng.token.common.enumutil.ResultEnum;
import com.yxcheng.token.common.model.JsonResult;
import com.yxcheng.token.common.model.RuleModel;
import com.yxcheng.token.common.model.UserReq;
import com.yxcheng.token.common.template.ApiTemplate;
import com.yxcheng.token.utils.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.function.Predicate;

@Transactional(rollbackFor = Exception.class)
@Component
public class SysApplyUserTaxnoServiceImpl implements SysApplyUserTaxnoService {
    @Autowired
    private SysApplyUserTaxnoMapper sysApplyUserTaxnoMapper;
    @Autowired
    private SysClientUserService sysClientUserService;
    @Autowired
    private SysUserTaxnoService sysUserTaxnoService;


    @Override
    public JsonResult<String> register(UserReq userReq, HttpServletRequest request) {
        return new ApiTemplate<JsonResult<String>>("register") {
            @Override
            protected JsonResult<String> process() throws Exception {
                //验证用户权限
                RuleModel ruleModel = new RuleModel(userReq.getTaxno(), userReq.getUserName(), userReq.getIp(), userReq.getApplyFunction());
                JsonResult<String> result = checkUserAuthority(ruleModel);
                //申请表注册
                saveRegisterUser(userReq);
                //税号表注册
                sysUserTaxnoService.saveRegisterUser(userReq);
                return result.successResponse();
            }
        }.execute();
    }

    @Override
    public JsonResult<Object> isAvailable(RuleModel ruleModel) {
        return checkUserAuthority(ruleModel);
    }

    /**
     * check role of user is available for function and rule
     */
    private JsonResult checkUserAuthority(RuleModel ruleModel){
        JsonResult result = new JsonResult();
        if(!sysClientUserService.checkUserFunction(ruleModel)){
            return result.errorResponse(ResultEnum.user_not_permission);
        }
        if(!RuleUtils.checkIps(ruleModel)){
            return result.errorResponse(ResultEnum.ip_notin_whitelist);
        }
        return result;
    }



    private void saveRegisterUser(UserReq userReq) {
        if(!this.isExist(userReq,ObjectUtil::dataBaseListIsExist)){
            SysApplyUserTaxno entity = new SysApplyUserTaxno();
            entity.setTaxno(userReq.getTaxno());
            entity.setUserName(userReq.getUserName());
            entity.setTaxName(userReq.getTaxName());
            entity.setApplyFunction(userReq.getApplyFunction());
            entity.setCreateDate(new Date());
            entity.setUpdateDate(new Date());
            entity.setApplyStatus(UserContants.APPLY_STATUS_ON);
            entity.setCreateBy(userReq.getAccessKeyID());
            sysApplyUserTaxnoMapper.insert(entity);
        }
    }

    private boolean isExist(UserReq userReq, Predicate<List>predicate) {
        SysApplyUserTaxnoExample query = new SysApplyUserTaxnoExample();
        query.createCriteria().andTaxnoEqualTo(userReq.getTaxno()).andUserNameEqualTo(userReq.getUserName()).andApplyFunctionEqualTo(userReq.getApplyFunction());
        List<SysApplyUserTaxno> sysApplyUserTaxnos = sysApplyUserTaxnoMapper.selectByExample(query);
        return predicate.test(sysApplyUserTaxnos);
    }
}
