package com.css.txw.sso.service.oauth2;

import cn.hutool.core.util.IdUtil;
import com.css.txw.sso.constants.ErrorCodeConstants;
import com.css.txw.sso.mapper.oauth2.OAuth2CodeMapper;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2CodeDO;
import com.css.ggzc.framework.common.exception.util.ServiceExceptionUtil;
import com.css.ggzc.framework.common.util.date.DateUtils;
import com.css.ggzc.framework.session.SessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static com.css.ggzc.framework.common.exception.util.ServiceExceptionUtil.exception;


/**
 * OAuth2.0 授权码 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class OAuth2CodeServiceImpl implements OAuth2CodeService {

    /**
     * 授权码的过期时间，默认 5 分钟
     */
    private static final Integer TIMEOUT = 5 * 60;

    @Resource
    private OAuth2CodeMapper oauth2CodeMapper;

    @Override
    public OAuth2CodeDO createAuthorizationCode(String userId, Integer userType, String clientId,
                                                List<String> scopes, String redirectUri, String state) {
        OAuth2CodeDO codeDO = new OAuth2CodeDO().setSqm(generateCode())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(SessionUtils.getYhUuid())
                .setClientid(clientId)
                .setGqsj(LocalDateTime.now().plusSeconds(TIMEOUT))
                .setCdxdz(redirectUri)
                .setRzzt(state);
        codeDO.setYwqdDm("ZNSB.SSO");
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String now = sdf.format(new Date());
        codeDO.setLrrq(now);
        codeDO.setXgrq(now);
        codeDO.setSjcsdq("00000000000");
        codeDO.setSjgsdq("00000000000");
        codeDO.setLrrsfid(SessionUtils.getYhUuid());
        codeDO.setXgrsfid(SessionUtils.getYhUuid());
        codeDO.setSjtbSj(now);
        oauth2CodeMapper.insert(codeDO);
        return codeDO;
    }

    @Override
    public OAuth2CodeDO createAuthorizationCode(String clientId, String redirectUri, String state,String currentToken) {
        OAuth2CodeDO codeDO = new OAuth2CodeDO().setSqm(generateCode())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(SessionUtils.getYhUuid())
                .setClientid(clientId)
                .setGqsj(LocalDateTime.now().plusSeconds(TIMEOUT))
                .setCdxdz(redirectUri)
                .setRzzt(state).setAccessToken(currentToken);
        codeDO.setYwqdDm("ZNSB.SSO");
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String now = sdf.format(new Date());
        codeDO.setLrrq(now);
        codeDO.setXgrq(now);
        codeDO.setSjcsdq("00000000000");
        codeDO.setSjgsdq("00000000000");
        codeDO.setLrrsfid(SessionUtils.getYhUuid());
        codeDO.setXgrsfid(SessionUtils.getYhUuid());
        codeDO.setSjtbSj(now);
        oauth2CodeMapper.insert(codeDO);
        return codeDO;
    }

    @Override
    public OAuth2CodeDO consumeAuthorizationCode(String code) {
        OAuth2CodeDO codeDO = oauth2CodeMapper.selectByCode(code);
        if (codeDO == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.OAUTH2_CODE_NOT_EXISTS);
        }
        if (DateUtils.isExpired(codeDO.getGqsj())) {
            throw exception(ErrorCodeConstants.OAUTH2_CODE_EXPIRE);
        }
        oauth2CodeMapper.deleteById(codeDO.getUuid());
        return codeDO;
    }

    private static String generateCode() {
        return IdUtil.fastSimpleUUID();
    }

}
