package com.crm.login.rely.backend.controller;

import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.PrefixEnum;
import com.crm.rely.backend.core.constant.SourceEnum;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.entity.login.InfoEntity;
import com.crm.rely.backend.exception.ControllerException;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.AESUtil;
import com.crm.rely.backend.util.HttpServletRequestUtil;
import com.crm.rely.backend.util.UUIDUtil;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;

/**
 * @author houn
 */
public class BaseLoginController {

    @Autowired
    protected RedisService redisService;

    protected <T extends InfoEntity> String login(T entity) throws Exception {

        return login(entity, null);
    }

    protected <T extends InfoEntity> String login(T entity, SourceEnum source) throws Exception {

        saveLoginInfo(entity);

        String token = UUIDUtil.getUUID();
        redisService.saveObject(token, entity.getPrefix().getCode() + entity.getId(), Constants.ACCESS_TOKEN_TIME);
        if (source == null) {
            source = SourceEnum.WEB;
        }
        long time = 0;
        if (SourceEnum.WEB.equals(source)) {
            time = Constants.ACCESS_TOKEN_TIME;
        } else {
            time = Constants.ACCESS_PHONE_TOKEN_TIME;
        }
        redisService.saveObject(entity.getPrefix().getCode() + entity.getId() + Constants.LOGIN_LINK + source.getCode(), token, time);

        String accessToken = AESUtil.encrypt(token + Constants.LOGIN_LINK + source.getCode());
        return accessToken;
    }

    protected <T extends InfoEntity> void saveLoginInfo(T entity) throws Exception {

        verification(entity);

        redisService.save(entity.getPrefix().getCode() + entity.getId(), entity);
    }

    protected InfoEntity getLoginInfo(PrefixEnum prefix, Long id) throws Exception {

        InfoEntity info = redisService.getEntity(prefix.getCode() + id, InfoEntity.class);
        return info;
    }

    protected <T extends InfoEntity> T getLoginInfo( PrefixEnum prefix, Long id,Class<T> clazz) throws Exception {

        T info = redisService.getEntity(prefix.getCode() + id, clazz);
        return info;
    }

    protected InfoEntity loginInfo(HttpServletRequest request) throws Exception {

        InfoEntity entity = HttpServletRequestUtil.getLoginInfo(request, redisService);

        return entity;
    }
    /**
     * 退出登录
     *
     * @param prefixEnum
     * @param id
     * @throws Exception
     */
    protected void logout(PrefixEnum prefixEnum, Long id) throws Exception {

        redisService.remove(prefixEnum.getCode() + id);
    }

    protected BaseResultDto logout(HttpServletRequest httpServletRequest) throws Exception {

        String accessToken = httpServletRequest.getHeader(Constants.ACCESS_TOKEN);
        if (!Strings.isNullOrEmpty(accessToken)) {
            redisService.remove(accessToken);
        }

        return BaseResultDto.success(Constants.LOGOUT_SUCCESS);
    }

    private <T extends InfoEntity> void verification(T entity) throws Exception {

        if (entity == null) {
            throw new ControllerException(Constants.SYSTEM_ERROR);
        }
        if (entity.getPrefix() == null && entity.getPrefix().equals("")) {
            throw new ControllerException(Constants.SYSTEM_ERROR);
        }
        if (entity.getId() == null) {
            throw new ControllerException(Constants.SYSTEM_ERROR);
        }
        if (entity.getValid() == null) {
            throw new ControllerException(Constants.SYSTEM_ERROR);
        }
    }
}