package com.ruoyi.ibs.app.service.impl;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.ibs.app.domain.QYUserDTO;
import com.ruoyi.ibs.app.domain.QYUserDetailDTO;
import com.ruoyi.ibs.app.domain.QywxOrg;
import com.ruoyi.ibs.app.mapper.QYWeiXinMapper;
import com.ruoyi.ibs.app.service.QYWeiXinManagerInfoService;
import com.ruoyi.ibs.app.service.WeiXinService;
import com.ruoyi.ibs.app.util.Constants;
import com.ruoyi.ibs.app.util.JsonResult;
import com.ruoyi.ibs.app.util.RedisUtil;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;


import com.ruoyi.framework.web.service.TokenService;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

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

/**
 * @author 600477
 * @date 2023/11/15
 */
@Slf4j
@Service
public class QYWeiXinManagerInfoServiceImpl  implements QYWeiXinManagerInfoService {

    @Autowired
    private WeiXinService weiXinService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisUtil redisUtil;


    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private SysLoginService sysLoginService;

    @Autowired
    private QYWeiXinMapper qyWeiXinMapper;



    @Override
    public AjaxResult getQYWeiXinUserInfo(String code,String orgId) {
        QywxOrg qywxOrg = qyWeiXinMapper.getQywxOrg(orgId);
        //获取企业微信用户信息
        JsonResult<QYUserDTO> qyUserResult = weiXinService.getQYUser( code,qywxOrg.getAppId(),qywxOrg.getSecret(),orgId );
        if (!Constants.OK.equals( qyUserResult.getCode() )) {
            return AjaxResult.error( Constants.FAILURE, qyUserResult.getMessage() );
        }
        //获取企业微信用户详细信息
        JsonResult<QYUserDetailDTO> qyUserDetailResult = weiXinService.getQYUserDetail( qyUserResult.getData() );
        if (!Constants.OK.equals( qyUserDetailResult.getCode() )) {
            return AjaxResult.error( Constants.FAILURE, qyUserDetailResult.getMessage() );
        }
        QYUserDetailDTO qyUserDetailDTO = qyUserDetailResult.getData();
        log.info(qyUserDetailResult.getData().toString());
        String userName  = sysUserMapper.selectOneByNum( qyUserDetailDTO.getMobile() );
        if (userName == null ) {
            return AjaxResult.error( Constants.FAILURE, "客户经理信息不存在" );
        }
        SysUser sysUser = sysUserMapper.selectUserByUserName( userName );
//        UsernamePasswordAuthenticationToken token = null;
        Authentication token = null;
        if (sysUser == null) {
            return AjaxResult.error("客户经理信息不存在");
        }
        AjaxResult ajax = AjaxResult.success();
        try{
            UserDetails userDetails = new LoginUser(sysUser.getUserId(),sysUser.getDeptId(),sysUser,permissionService.getMenuPermission(sysUser));
            token = new UsernamePasswordAuthenticationToken(userDetails,null, AuthorityUtils.createAuthorityList("ROLE_USER"));
            AuthenticationContextHolder.setContext(token);
            SecurityContextHolder.getContext().setAuthentication(token);
        }
        catch (Exception e){
            if (e instanceof BadCredentialsException){
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"failed", "login.failed"));
                throw new UserPasswordNotMatchException();
            }else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"failed", e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"sucess", "login.sucess"));
        LoginUser loginUser = (LoginUser) token.getPrincipal();
        sysLoginService.recordLoginInfo(sysUser.getUserId());
        String userToken = tokenService.createToken(loginUser);
        ajax.put(Constants.QY_WEI_XIN_ACCESS_TOKEN_KEY,userToken);
        return ajax;
    }

    @Override
    public AjaxResult getLogin(String userName) {
        SysUser sysUser = sysUserMapper.selectUserByUserName( userName );
//        UsernamePasswordAuthenticationToken token = null;
        Authentication token = null;
        if (sysUser == null) {
            return AjaxResult.error("客户经理信息不存在");
        }
        AjaxResult ajax = AjaxResult.success();
        try{
            UserDetails userDetails = new LoginUser(sysUser.getUserId(),sysUser.getDeptId(),sysUser,permissionService.getMenuPermission(sysUser));
            token = new UsernamePasswordAuthenticationToken(userDetails,null, AuthorityUtils.createAuthorityList("ROLE_USER"));
            AuthenticationContextHolder.setContext(token);
            SecurityContextHolder.getContext().setAuthentication(token);
        }
        catch (Exception e){
            if (e instanceof BadCredentialsException){
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"failed", "login.failed"));
                throw new UserPasswordNotMatchException();
            }else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"failed", e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally {
            AuthenticationContextHolder.clearContext();
        }
//        UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
//        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());
//        Authentication authentication = authenticationManager.authenticate(token);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName,"sucess", "login.sucess"));
        LoginUser loginUser = (LoginUser) token.getPrincipal();
        System.out.println("--------------");
        System.out.println(SecurityUtils.getLoginUser());
        System.out.println("--------------");
        sysLoginService.recordLoginInfo(sysUser.getUserId());
        String userToken = tokenService.createToken(loginUser);
//        redisUtil.set(userToken,loginUser,120);
        ajax.put(Constants.QY_WEI_XIN_ACCESS_TOKEN_KEY,userToken);
        return ajax;
    }

    @Override
    public QywxOrg getQyApi(String orgId) {
        return qyWeiXinMapper.getQywxOrg(orgId);
    }

    @Override
    public QywxOrg getQyApi2(String orgId) {
        return qyWeiXinMapper.getQywxOrg2(orgId);
    }
}
