package yangtz.cs.liu.dingding.controller;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.MpLoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.MpTokenService;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yangtz.cs.liu.campus.domain.student.SchoolStudent;
import yangtz.cs.liu.campus.domain.student.SchoolStudentEducational;
import yangtz.cs.liu.campus.mapper.student.SchoolStudentMapper;
import yangtz.cs.liu.campus.service.impl.teacher.SchoolTeacherServiceImpl;
import yangtz.cs.liu.campus.service.student.ISchoolStudentEducationalService;
import yangtz.cs.liu.dingding.utils.AccessTokenUtils;
import yangtz.cs.liu.wechat.domain.WxLoginBody;
import yangtz.cs.liu.wechat.service.api.IWxLoginService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static yangtz.cs.liu.wechat.constant.LoginTypeConstant.TEACHER_LOGIN;

/**
 *
 *  企业内部应用免登
 * @author openapi@dingtalk
 * 2020-11-3
 */
@RestController
@RequestMapping("/dd/App/user")
public class DdAppLoginController {

    @Autowired
    private AccessTokenUtils accessTokenUtils;
    @Autowired
    private SysUserServiceImpl sysUserService;

    @Autowired
    private IWxLoginService wxLoginService;

    @Autowired
    private SchoolStudentMapper schoolStudentMapper;
    @Autowired
    private MpTokenService mpTokenService;
    /**
     *
     * @param code
     * @return
     * ServiceResult
     * 2020-11-3
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public AjaxResult login (@RequestParam("code") String code , @RequestParam("roleType") String roleType) throws Exception {
        // 获取access_token，注意正式代码要有异常流处理
        String access_token= accessTokenUtils.getToken();
        // 获取用户信息
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getuserinfo");
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(code);
        request.setHttpMethod("GET");
        OapiUserGetuserinfoResponse response;
        try {
            response = client.execute(request, access_token);
        } catch (ApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        Long errcode = response.getErrcode();

        if (errcode != 0){
            return AjaxResult.error(errcode.intValue(),response.getErrmsg());
        }
        // 查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理（session）,避免后续的业务交互（前端到应用服务端）每次都要重新获取用户身份，提升用户体验
        String userId = response.getUserid();
        // 查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理（session）,避免后续的业务交互（前端到应用服务端）每次都要重新获取用户身份，提升用户体验
        if (StringUtils.isEmpty(userId)){
            throw new ServiceException("免登码已失效，请重新获取");
        }
        //获取用户详细信息
        Map<String, Object> userInfo = getUserInfo(userId, access_token);
        String unionId = (String) userInfo.get("unionId");

        SysUser sysUserVo = new SysUser();
        sysUserVo.setUserLoginType(roleType);
        sysUserVo.setPhonenumber(userInfo.get("phone").toString());
        List<SysUser> sysUsers = sysUserService.selectUserListTypeLogin(sysUserVo);
        if (sysUsers.isEmpty()){
            throw new ServiceException("未查询到该用户信息");
        }
        SysUser sysUser = sysUsers.get(0);

        WxLoginBody wxLoginBody = new WxLoginBody();
        wxLoginBody.setPhonenumber(sysUser.getPhonenumber());
        wxLoginBody.setType(sysUser.getUserLoginType());
        wxLoginBody.setOpenId(unionId);
        wxLoginBody.setParentTelephone(sysUser.getPhonenumber());
        if (null != sysUser.getStudentId()){
            SchoolStudent schoolStudent = schoolStudentMapper.selectById(sysUser.getStudentId().toString());
            wxLoginBody.setStudentIdCard(schoolStudent.getIdCard());
            wxLoginBody.setStudentName(schoolStudent.getStudentName());
        }
        wxLoginBody.setParentName(sysUser.getUserName());
        wxLoginBody.setTeacherName(sysUser.getUserName());

        MpLoginUser user = wxLoginService.ddApplogin(wxLoginBody);
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("login error");
        }
        String userName = TEACHER_LOGIN.equals(user.getType()) ? user.getTeacherName() : user.getParentName();
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        String token = mpTokenService.createToken(user);
        return AjaxResult.success().put(Constants.TOKEN, token);
    }


    /**
     * 获取当前手机号有几个角色
     */

    @GetMapping("/getRole")
    public AjaxResult getRole(@RequestParam("code") String code){
        // 获取access_token，注意正式代码要有异常流处理
        String access_token= accessTokenUtils.getToken();
        // 获取用户信息
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getuserinfo");
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(code);
        request.setHttpMethod("GET");
        OapiUserGetuserinfoResponse response;
        try {
            response = client.execute(request, access_token);
        } catch (ApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        // 查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理（session）,避免后续的业务交互（前端到应用服务端）每次都要重新获取用户身份，提升用户体验
        String userId = response.getUserid();
        Map<String, Object> userInfo = getUserInfo(userId, access_token);
        SysUser sysUser = new SysUser();
        sysUser.setPhonenumber(userInfo.get("phone").toString());
        List<SysUser> sysUsers = sysUserService.selectUserListTypeLogin(sysUser);
        if (sysUsers.isEmpty()){
            return AjaxResult.error("没有相关角色");
        }else if (sysUsers.size() == 1 ){
            List<Map<String,String>> mapList = new ArrayList<>();
            Map<String,String> map = new HashMap<>();
            if (null == sysUsers.get(0).getStudentId()){
                map.put("name",sysUsers.get(0).getUserName());
                map.put("userLoginType",sysUsers.get(0).getUserLoginType());
            }else {
                SchoolStudent schoolStudent = schoolStudentMapper.selectById(sysUsers.get(0).getStudentId());
                map.put("name",sysUsers.get(0).getUserName());
                map.put("userLoginType",sysUsers.get(0).getUserLoginType());
                map.put("studentName",schoolStudent.getStudentName());
            }
            mapList.add(map);
            return  AjaxResult.success(mapList);
        }else if (sysUsers.size()> 1){
            List<Map<String,String>> mapList = new ArrayList<>();
            sysUsers.forEach(date->{
                Map<String,String> map = new HashMap<>();
                if (null == date.getStudentId()){
                    map.put("name",date.getUserName());
                    map.put("userLoginType",date.getUserLoginType());
                }else {
                    SchoolStudent schoolStudent = schoolStudentMapper.selectById(date.getStudentId());
                    map.put("name",date.getUserName());
                    map.put("userLoginType",date.getUserLoginType());
                    map.put("studentName",schoolStudent.getStudentName());
                }
                mapList.add(map);
            });
            return AjaxResult.success(mapList);
        }
        return AjaxResult.error("未找到用户信息");
    }


    /**
     *
     * @param userId
     * @param token
     * @return
     */
    public Map<String,Object> getUserInfo(String userId,String token){
        Map<String,Object> map = new HashMap<>();
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            OapiV2UserGetResponse rsp = client.execute(req, token);
            OapiV2UserGetResponse.UserGetResponse result = rsp.getResult();
            String name = result.getName();
            String phone = result.getMobile();
            String unionId = result.getUnionid();
            map.put("userName",name);
            map.put("phone",phone);
            map.put("unionId",unionId);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return map;
    }
}
