package cn.ey.biz.module.system.service.appuser;

import cn.ey.biz.common.pojo.PageResult;
import cn.ey.biz.module.system.controller.admin.appuser.vo.*;
import cn.ey.biz.module.system.convert.appuser.AppUserConvert;
import cn.ey.biz.module.system.convert.auth.OAuth2ClientConvert;
import cn.ey.biz.module.system.dal.dataobject.appuser.AppUserDO;
import cn.ey.biz.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
import cn.ey.biz.module.system.dal.mapper.appuser.AppUserMapper;
import cn.ey.biz.module.system.dal.mapper.oauth2.OAuth2ClientMapper;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;

import static cn.ey.biz.common.exception.util.ServiceExceptionUtil.exception;
import static cn.ey.biz.module.system.enums.ErrorCodeConstants.APP_USER_NOT_EXISTS;
import static cn.ey.biz.module.system.enums.ErrorCodeConstants.OAUTH2_CLIENT_NOT_EXISTS;

@Service
public class AppUserServiceImpl implements AppUserService {

    @Resource
    private AppUserMapper appUserMapper;

    @Resource
    private OAuth2ClientMapper oAuth2ClientMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createAppUser(AppUserReqVO reqVO) {
        String appSecret = IdUtil.fastSimpleUUID();
        String clientId = IdUtil.fastSimpleUUID();
        AppUserDO appUserDO = new AppUserDO();
        appUserDO.setDeleted(false);
        appUserDO.setAppId(reqVO.getAppId());
        appUserDO.setAppSecret(appSecret);
        appUserDO.setClientId(clientId);
        appUserDO.setStatus(reqVO.getStatus());
        appUserDO.setRemark(reqVO.getRemark());
        // appUserDO.setTenantId(TenantContextHolder.getRequiredTenantId());
        appUserMapper.insert(appUserDO);
        OAuth2ClientReqVO auth2ClientReqVO = reqVO.getAuth2ClientReqVO();
        auth2ClientReqVO.setName(reqVO.getAppId());
        auth2ClientReqVO.setClientId(clientId);
        auth2ClientReqVO.setSecret(appSecret);
        auth2ClientReqVO.setStatus(reqVO.getStatus());
        auth2ClientReqVO.setRedirectUris(new ArrayList<>());
        auth2ClientReqVO.setAuthorizedGrantTypes(new ArrayList<>());
        auth2ClientReqVO.setScopes(new ArrayList<>());
        auth2ClientReqVO.setAuthorities(new ArrayList<>());
        auth2ClientReqVO.setResourceIds(new ArrayList<>());
        OAuth2ClientDO oAuth2ClientDO = OAuth2ClientConvert.INSTANCE.voToDo(auth2ClientReqVO);
        oAuth2ClientMapper.insert(oAuth2ClientDO);
        return appUserDO.getId();
    }

    @Override
    public void updateAppUserStatus(AppUserReqVO reqVO) {
        AppUserDO appUserDO = checkAppUserExist(reqVO.getId());
        LambdaUpdateWrapper<AppUserDO> updateWrapper = Wrappers.<AppUserDO>update()
                .lambda()
                .eq(AppUserDO::getId, reqVO.getId());
        appUserDO.setAppId(reqVO.getAppId());
        appUserDO.setStatus(reqVO.getStatus());
        appUserMapper.update(appUserDO, updateWrapper);

        OAuth2ClientDO oAuth2ClientDO = checkOAuth2ClientExist(appUserDO.getClientId());
        oAuth2ClientDO.setStatus(reqVO.getStatus());
        LambdaUpdateWrapper<OAuth2ClientDO> oAuth2ClientDOLambdaUpdateWrapper = Wrappers.<OAuth2ClientDO>update()
                .lambda()
                .eq(OAuth2ClientDO::getId, oAuth2ClientDO.getId());
        oAuth2ClientMapper.update(oAuth2ClientDO, oAuth2ClientDOLambdaUpdateWrapper);
    }

    @Override
    public AppUserRespVO getAppUser(Long id) {
        AppUserDO appUserDO = appUserMapper.selectById(id);
        return AppUserConvert.INSTANCE.doToVo(appUserDO);
    }

    private AppUserDO checkAppUserExist(Long id) {
        AppUserDO appUserDO = appUserMapper.selectById(id);
        if (null == appUserDO) {
            throw exception(APP_USER_NOT_EXISTS);
        }
        return appUserDO;
    }

    private OAuth2ClientDO checkOAuth2ClientExist(String clientId) {
        OAuth2ClientDO oAuth2ClientDO = oAuth2ClientMapper.selectOne(new LambdaQueryWrapper<OAuth2ClientDO>()
                .eq(OAuth2ClientDO::getClientId, clientId).eq(OAuth2ClientDO::getDeleted, 0));
        if (null == oAuth2ClientDO) {
            throw exception(OAUTH2_CLIENT_NOT_EXISTS);
        }
        return oAuth2ClientDO;
    }

    @Override
    public PageResult<AppUserPageRespVO> getAppUserPage(AppUserPageReqVO reqVO) {
        PageResult<AppUserDO> doPageResult = appUserMapper.selectPage(reqVO);
        return AppUserConvert.INSTANCE.convertPage(doPageResult);
    }

}
