package com.seer.teach.user.app.auth.service.strategy;

import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.enums.RoleEnum;
import com.seer.teach.common.exception.CommonException;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.CommonUtils;
import com.seer.teach.mp.api.WechatOfficialAccountApi;
import com.seer.teach.mp.api.resp.WxOAuth2AccessTokenDTO;
import com.seer.teach.user.app.auth.LoginType;
import com.seer.teach.user.app.auth.request.LoginParam;
import com.seer.teach.user.app.auth.service.LoginStrategy;
import com.seer.teach.user.app.auth.service.LoginUser;
import com.seer.teach.user.entity.RoleEntity;
import com.seer.teach.user.entity.UserAuthEntity;
import com.seer.teach.user.entity.UserEntity;
import com.seer.teach.user.entity.UserRoleEntity;
import com.seer.teach.user.service.IRoleService;
import com.seer.teach.user.service.IUserAuthService;
import com.seer.teach.user.service.IUserRoleService;
import com.seer.teach.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 仓库账户登录策略
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class WarehouseAccountLoginStrategy extends AbstractLoginStrategy implements LoginStrategy {

    private final IUserService userService;

    private final WechatOfficialAccountApi wechatOfficialAccountApi;

    private final IUserAuthService userAuthService;

    private final IUserRoleService userRoleService;

    private final IRoleService roleService;

    @Override
    public LoginType getType() {
        return LoginType.WAREHOUSE_ACCOUNT;
    }

    @Override
    public LoginUser authenticate(LoginParam request) {
        AssertUtils.notNull(request.getPassword(), ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
        UserEntity accountUser = userService.getOneByUserName(request.getUserName());
        AssertUtils.notNull(accountUser, ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
        String password = CommonUtils.encryptPassword(request.getPassword());
        if (!password.equals(accountUser.getPassword())) {
            throw new CommonException(ResultCodeEnum.USERNAME_OR_PASSWORD_IS_ERROR);
        }
        List<UserRoleEntity> userRoles = userRoleService.getListByUserId(accountUser.getId());
        AssertUtils.notEmpty(userRoles, ResultCodeEnum.USER_NOT_HAVE_WAREHOUSE_ROLE);

        Collection<RoleEntity> roles = roleService.getRoleListByRoleIds(userRoles.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toSet()));
        roles.stream().filter(role -> RoleEnum.WAREHOUSE_MANAGER.getCode().equals(role.getRoleCode()))
                .findAny()
                .orElseThrow(() -> new CommonException(ResultCodeEnum.USER_NOT_HAVE_WAREHOUSE_ROLE));

        WxOAuth2AccessTokenDTO wxOAuth2AccessToken = wechatOfficialAccountApi.getUserWxOAuth2AccessToken(request.getAppId(),request.getJsCode());
        AssertUtils.notNull(wxOAuth2AccessToken, ResultCodeEnum.WX_OAUTH_USED_ERROR);
        UserAuthEntity userAuthEntity = userAuthService.getOneByOpenId(wxOAuth2AccessToken.getOpenId());
        if (Objects.isNull(userAuthEntity)) {
            log.info("用户未绑定微信");
            boolean userAuthSaved = saveUserAuth(getType().getCode(), accountUser.getId(), wxOAuth2AccessToken,request.getAppId());
            log.info("保存用户授权信息：{}", userAuthSaved);
        }else {
            updateUserAuth(userAuthEntity);
        }
        return new LoginUser(accountUser.getId());
    }
}