package io.hmit.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.api.R;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.hmit.annotation.Login;
import io.hmit.common.constant.Constant;
import io.hmit.common.utils.Result;
import io.hmit.common.utils.sm.SMUtil;
import io.hmit.common.validator.ValidatorUtils;
import io.hmit.config.ZhelibanUtils;
import io.hmit.dto.LoginDTO;
import io.hmit.entity.TokenEntity;
import io.hmit.entity.UserEntity;
import io.hmit.modules.zlb.constants.IdTypeEnum;
import io.hmit.modules.zlb.service.AuthService;
import io.hmit.service.TokenService;
import io.hmit.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 登录接口
 *
 * @author zsh 408538940@qq.com
 */
@Slf4j
@RestController
@RequestMapping("/api")
@Api(tags = "登录接口")
public class ApiLoginController {

    @Autowired
    private UserService userService;
    @Autowired
    private TokenService tokenService;

    @Autowired
    private AuthService authService;


    @PostMapping("login")
    @ApiOperation("登录")
    public Result<Map<String, Object>> login(@RequestBody LoginDTO dto) {

        //表单校验
        ValidatorUtils.validateEntity(dto);

        //用户登录
        Map<String, Object> map = userService.login(dto);

        return new Result().ok(map);
    }

    @Login
    @PostMapping("logout")
    @ApiOperation("退出")
    public Result logout(@ApiIgnore @RequestAttribute("userId") Long userId) {

        tokenService.expireToken(userId);
        return new Result();
    }

    //个人登录 - 单点登陆
    @RequestMapping(value="/check_user")
    @ApiOperation("单点登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "票据", paramType = "query", required = true, dataType="String") ,
    })

    public Result checkUser(@ApiIgnore @RequestParam Map<String,Object> map , HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        // 获取到票据信息ticket
        System.out.println("开始进入这个checkuser了————————————————————");
        System.out.println(map);
        Long userId;
        Map<String, Object> userMap = new HashMap<>();

        if(map.get("ticket") != null){
            System.out.println("Ticket 是"+map.get("ticket")+"——————————————————————");
            Map<String,Object> user_map = ZhelibanUtils.getUserInfo(map);
            System.out.println("UserMap是——————————————————————————————");
            System.out.println(user_map);
            if ("6001".equals(user_map.get("result"))){
                return new Result().error("ticket失效");
            }
            if (user_map.get("idnum") !=null){
                //判断是否已经存在了这条信息
                UserEntity oldUser=userService.queryByIdnum(URLEncoder.encode(user_map.get("idnum").toString(), "UTF8"));

                userMap.put("userId", user_map.get("userid"));
                userMap.put("userNick", "");

                if(oldUser==null){
                    //将获得的信息保存到个人登陆表
                    UserEntity user=new UserEntity();
                    user.setUsername(user_map.get("username").toString());
                    user.setMobile(URLEncoder.encode(user_map.get("mobile").toString(), "UTF8"));
                    user.setPassword(URLEncoder.encode(DigestUtils.sha256Hex(user_map.get("idnum").toString()), "UTF8"));
                    user.setIdCardNo(URLEncoder.encode(user_map.get("idnum").toString(), "UTF8"));
                    userService.insert(user);

                    userId = user.getId();
                    userMap.put("username", user.getUsername());
                    userMap.put("mobile", user.getMobile());
                    userMap.put("idnum",user.getIdCardNo());
                }else{
                    userId = oldUser.getId();
                    userMap.put("username", oldUser.getUsername());
                    userMap.put("mobile", oldUser.getMobile());
                    userMap.put("idnum",oldUser.getIdCardNo());

                }
                TokenEntity tokenEntity = tokenService.createToken(userId);
                userMap.put("token", tokenEntity.getToken());
                userMap.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());
            }
            return new Result().ok(userMap);
        }else{
            return new Result().error("票据信息为空");
        }
    }

    //个人登录 - 单点登陆
    @RequestMapping(value="/check_user_ticket_id")
    @ApiOperation("单点登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticketId", value = "票据", paramType = "query", required = true, dataType="String") ,
    })
    public Result checkUserTicketId(@ApiIgnore @RequestParam Map<String,Object> map , HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        // 获取到票据信息ticket
        log.info("开始进入这个check_user_ticket_id了————————————————————");
        System.out.println(map);
        Long userId;
        Map<String, Object> userMap = new HashMap<>();

        if(map.get("ticketId") != null){

            String accessToken = authService.getTokenByTicketId((String) map.get("ticketId"));
            JSONObject userInfoByToken = authService.getUserInfoByToken(accessToken);
            Map<String,Object> user_map = (Map<String, Object>) userInfoByToken.get("personInfo");
            if (user_map.get("idNo") !=null){
                //判断是否已经存在了这条信息
                UserEntity oldUser=userService.queryByIdnum(SMUtil.SM4Encrypt(URLEncoder.encode(user_map.get("idNo").toString(), "UTF8")));

                try {
                    userMap.put("userId", user_map.get("userId"));
                    userMap.put("userNick", ((Map<String, Object>) user_map.get("attributes")).get("nickname"));
                }catch (Exception ignore) {}

                if(oldUser==null){
                    //将获得的信息保存到个人登陆表
                    String idNo = user_map.get("idNo").toString();
                    UserEntity user=new UserEntity();
                    user.setUsername(user_map.get("userName").toString());
                    user.setMobile(SMUtil.SM4Encrypt(URLEncoder.encode(user_map.get("phone").toString(), "UTF8")));
                    user.setPassword(URLEncoder.encode(DigestUtils.sha256Hex(idNo), "UTF8"));
                    user.setIdCardNo(SMUtil.SM4Encrypt(URLEncoder.encode(idNo, "UTF8")));
                    userService.insert(user);

                    userId = user.getId();
                    userMap.put("username", user.getUsername());
                    userMap.put("mobile", SMUtil.SM4Decrypt(user.getMobile()));
                    userMap.put("idnum", SMUtil.SM4Decrypt(user.getIdCardNo()));
                }else{
                    userId = oldUser.getId();
                    userMap.put("username", oldUser.getUsername());
                    userMap.put("mobile", SMUtil.SM4Decrypt(oldUser.getMobile()));
                    userMap.put("idnum", SMUtil.SM4Decrypt(oldUser.getIdCardNo()));

                }
                TokenEntity tokenEntity = tokenService.createToken(userId);
                userMap.put("token", tokenEntity.getToken());
                userMap.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());
            }
            return new Result().ok(userMap);
        }else{
            return new Result().error("票据信息为空");
        }
    }

    @GetMapping("encryptOneTime")
    public Result<Object> encryptOneTime() {
        return userService.encryptOneTime();
    }

    //个人登录 - 单点登陆
    @GetMapping(value="/check_zlb_ticket_id")
    @ApiOperation("单点登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticketId", value = "票据", paramType = "query", required = true, dataType="String") ,
    })
    public Result checkZlbTicketId(@ApiIgnore @RequestParam Map<String,Object> map , HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        // 获取到票据信息ticket
        log.info("开始进入这个check_zlb_ticket_id了，Map = {}", map);
        Long userId;
        Map<String, Object> userMap = new HashMap<>();

        if(map.get("ticketId") != null){

            String accessToken = authService.getTokenByTicketId((String) map.get("ticketId"));
            JSONObject userInfoByToken = authService.getUserInfoByToken(accessToken);
            Map<String,Object> user_map = (Map<String, Object>) userInfoByToken.get("personInfo");
            Map<String,Object> user_attributes = (Map<String, Object>) userInfoByToken.get("attributes");

            JSONObject requestBody = new JSONObject();

            if("LEGAL_PERSON".equals(userInfoByToken.get("userType"))){
                Map<String,Object> user_legal_map = (Map<String, Object>) userInfoByToken.get("legalPersonInfo");
                userMap.put("username", user_legal_map.get("name"));
                //构造requestId请求参数
                requestBody.put("certNo",user_legal_map.get("idNo"));
                requestBody.put("certName",user_legal_map.get("userName"));
                requestBody.put("certType", IdTypeEnum.getByType(user_legal_map.get("idType").toString()).getCode());
                requestBody.put("nation",user_legal_map.get("nation"));
                requestBody.put("mobile",user_legal_map.get("phone"));
                requestBody.put("fkSceneCode","SC-OT01-HT01-c24531c0-b0da-4e38-885f-58f642e30e6a");
                requestBody.put("curLoginMetadata",user_attributes.get("curLoginMetadata"));
            }else{
                userMap.put("username", user_map.get("userName"));
                requestBody.put("certNo",user_map.get("idNo"));
                requestBody.put("certName",user_map.get("userName"));
                requestBody.put("certType", IdTypeEnum.getByType(user_map.get("idType").toString()).getCode());
                requestBody.put("nation",user_map.get("nation"));
                requestBody.put("mobile",user_map.get("phone"));
                requestBody.put("fkSceneCode","SC-OT01-HT01-c24531c0-b0da-4e38-885f-58f642e30e6a");
                requestBody.put("curLoginMetadata",user_attributes.get("curLoginMetadata"));
            }
            JSONObject zlbRequestId = authService.getZlbRequestId(requestBody);
            userMap.put("requestId",zlbRequestId.get("requestId"));
            userMap.put("verifyFree",zlbRequestId.get("verifyFree"));
            userMap.put("userId", user_map.get("userId"));
            userMap.put("mobile", user_map.get("phone"));


            if (user_map.get("idNo") !=null){
                //判断是否已经存在了这条信息
                UserEntity oldUser=userService.queryByIdnum(SMUtil.SM4Encrypt(URLEncoder.encode(user_map.get("idNo").toString(), "UTF8")));

                try {
                    userMap.put("userId", user_map.get("userId"));
                    userMap.put("userNick", ((Map<String, Object>) user_map.get("attributes")).get("nickname"));
                }catch (Exception ignore) {}

                if(oldUser==null){
                    //将获得的信息保存到个人登陆表
                    String idNo = user_map.get("idNo").toString();
                    UserEntity user=new UserEntity();
                    //信息加密存储
                    user.setUsername(SMUtil.SM4Encrypt(user_map.get("userName").toString()));
                    user.setMobile(SMUtil.SM4Encrypt(URLEncoder.encode(user_map.get("phone").toString(), "UTF8")));

                    userService.insert(user);

                    userId = user.getId();
                    userMap.put("username", user.getUsername());
                    userMap.put("mobile", SMUtil.SM4Decrypt(user.getMobile()));
                    userMap.put("idnum", SMUtil.SM4Decrypt(user.getIdCardNo()));
                }else{
                    userId = oldUser.getId();
                    userMap.put("username", oldUser.getUsername());
                    userMap.put("mobile", SMUtil.SM4Decrypt(oldUser.getMobile()));
                    userMap.put("idnum", SMUtil.SM4Decrypt(oldUser.getIdCardNo()));

                }
                TokenEntity tokenEntity = tokenService.createToken(userId);
                userMap.put("token", tokenEntity.getToken());
                userMap.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());
            }
            return new Result().ok(userMap);
        }else{
            return new Result().error("票据信息为空");
        }
    }

    @GetMapping(value="/checkResultByRequestId")
    @ApiOperation("人脸核验结果")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "requestId", value = "票据", paramType = "query", required = true, dataType="String") ,
    })
    public Result checkResultByRequestId(@ApiIgnore @RequestParam Map<String,Object> map , HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        // 获取到票据信息ticket
        log.info("开始进入这个checkResultByRequestId了，Map = {}", map);

        Map<String, Object> userMap = new HashMap<>();

        if(map.get("requestId") != null){

            JSONObject result = authService.checkResultByRequestId((String) map.get("requestId"));

            userMap.put("pass",String.valueOf(result.get("pass")));

            return new Result().ok(userMap);
        }else{
            return new Result().error("requestId为空");
        }
    }


}
