package com.testor.module.iam.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.testor.biz.auth.AuthEnumCode;
import com.testor.biz.auth.model.TokenResponse;
import com.testor.biz.auth.model.UserInfoResponse;
import com.testor.biz.auth.service.AuthService;
import com.testor.biz.sys.user.UserHelper;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.common.constant.IamBindStatusEnum;
import com.testor.module.iam.dao.IamUserMappingDao;
import com.testor.module.iam.model.domain.IamUserMapping;
import com.testor.module.iam.model.dto.BindIamUserDto;
import com.testor.module.iam.service.IamSysUserService;
import com.testor.module.iam.service.IamUserMappingService;
import com.testor.module.iam.util.RequestIamUtil;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.jwt.JwtHelper;
import com.tongtech.tfw.backend.common.models.exceptions.ApiException;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @ClassName: IamUserMappingServiceImpl
 * @Description: TODO
 * @Author: lm
 * @CreateTime: 2023/12/29 10:21
 * @Version: 1.0
 */
@Service("IamUserMappingServiceImpl")
public class IamUserMappingServiceImpl extends SuperServiceImpl<IamUserMappingDao, IamUserMapping>  implements IamUserMappingService {

    @Autowired
    private AuthService authService;

    @Autowired
    private RequestIamUtil requestIamUtil;

    @Autowired
    private IamSysUserService iamSysUserService;

    @Override
    public BaseResponse<TokenResponse> bindIamUserAndLogin(BindIamUserDto bindUserDto) {
        /**
         * 首先进行登录操作，成功后检查iam账户是否被其它用户绑定，没有就绑定到当前账户，返回token
         * 登录失败或已被其它账户绑定，则进行提示
         */
        BaseResponse<TokenResponse> baseResponse = new BaseResponse();
        String password = UserHelper.userPassword(bindUserDto.getPassword());
        SysUser sysUser = authService.login(bindUserDto.getLoginName());
        if (ObjectHelper.isNotEmpty(sysUser)) {
            if (password.equals(sysUser.getLoginPwd())){
                // 用户可以登录，检查是否绑定IAM，检查IAM是否被绑定
                IamUserMapping userIdMapping = getByUserId(sysUser.getUserId());
                //List<IamUserMapping> iamUserIdMapping = getByIamUserId(bindUserDto.getIamUserId());
                if (ObjectHelper.isEmpty(userIdMapping)){
                    // 系统用户未绑定
                    //  if (ObjectHelper.isNotEmpty(iamUserIdMapping)){
                    //      // iam已被绑定，让用户重新单点登录
                    //      throw new ApiException(IamBindStatusEnum.BOUND.transform());
                    //  }else {
                        // 绑定，然后执行生成token
                        IamUserMapping iamUserMapping = new IamUserMapping();
                        iamUserMapping.setUserId(sysUser.getUserId());
                        iamUserMapping.setIamUserId(bindUserDto.getIamUserId());
                        iamUserMapping.setBindTime(new Date());
                        save(iamUserMapping);
                    //}
                }else {
                    // 系统用户被其它iamUserId绑定
                    if(!userIdMapping.getIamUserId().equals(bindUserDto.getIamUserId())){
                        throw new ApiException(IamBindStatusEnum.BIND_BY_OTHER_IAM_USER.transform());
                    }
                }
                UserInfoResponse userInfoResponse = authService.getUserInfo(sysUser.getUserId());
                String jwt = JwtHelper.issueJwtAuth0(IdHelper.getId32bit(), sysUser.getUserId(), JSON.toJSONString(userInfoResponse.getUserInfo()), "Token Issuer", "", 36000L);
                TokenResponse build = TokenResponse.builder().token(jwt).expired(300L).build();
                baseResponse.setData(build);
            }else {
                // 密码错误
                throw new ApiException(AuthEnumCode.PASSWORD.transform());
            }
        }else {
            // 用户不存在
            throw new ApiException(AuthEnumCode.USERNAME.transform());
        }
        return baseResponse;
    }

    @Override
    public boolean bindIamUser(String userId, String iamUserId) {
        boolean flag = false;
        // iamUserId是否绑定，若不被当前用户绑定，则不可绑定
        IamUserMapping userIdMapping = getByUserId(userId);
        //List<IamUserMapping> iamUserIdMapping = getByIamUserId(iamUserId);
        if (ObjectHelper.isEmpty(userIdMapping)){
            // 系统用户未绑定
            //if (ObjectHelper.isNotEmpty(iamUserIdMapping)){
                // iam已被绑定其它账户绑定
                //throw new ApiException(IamBindStatusEnum.BIND_BY_OTHER_USER.transform());
            //}else {
                // 绑定，然后执行生成token
                IamUserMapping iamUserMapping = new IamUserMapping();
                iamUserMapping.setUserId(userId);
                iamUserMapping.setIamUserId(iamUserId);
                iamUserMapping.setBindTime(new Date());
                save(iamUserMapping);
                flag = true;
            //}
        }else {
            // 用户绑定的iam与当前不是一个，执行替换操作
            if (userIdMapping.getIamUserId().equals(iamUserId)){
                flag = true;
            }else {
                /*if (!ObjectHelper.isEmpty(iamUserIdMapping)){
                    throw new ApiException(IamBindStatusEnum.BIND_BY_OTHER_USER.transform());
                }*/
                // 删除映射关系
                deleteByUserId(userId);
                IamUserMapping iamUserMapping = new IamUserMapping();
                iamUserMapping.setUserId(userId);
                iamUserMapping.setIamUserId(iamUserId);
                iamUserMapping.setBindTime(new Date());
                save(iamUserMapping);
                flag = true;
            }
        }
        return flag;
    }

    @Override
    public IamUserMapping getByUserId(String userId) {
        return getBaseMapper().selectOne(new QueryWrapper<IamUserMapping>().eq("user_id",userId));
    }

    public List<IamUserMapping> getByIamUserId(String iamUserId) {
        return getBaseMapper().selectList(new QueryWrapper<IamUserMapping>().eq("iam_user_id",iamUserId));
    }

    @Override
    public boolean deleteByUserId(String userId) {
        return remove((Wrapper)(new QueryWrapper()).eq("user_id", userId));
    }

    @Override
    public boolean deleteByIamUserId(String iamUserId) {
        return remove((Wrapper)(new QueryWrapper()).eq("iam_user_id", iamUserId));

    }
}
