package com.njyunzhi.pet_identity.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.njyunzhi.pet_identity.common.*;
import com.njyunzhi.pet_identity.entity.TaPerson;
import com.njyunzhi.pet_identity.service.ITaPersonService;
import com.njyunzhi.pet_identity.service.ITaPetIdentityService;
import com.njyunzhi.pet_identity.service.ITaPetService;
import com.njyunzhi.pet_identity.vo.MaLogin;
import com.njyunzhi.pet_identity.vo.WxMaAuthParam;
import com.njyunzhi.pet_identity.vo.WxMaPreload;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "小程序登入/登出")
@RestController
@RequestMapping("/wx/{clientId}")
public class WxMaController extends BaseController {

    @Autowired
    ITaPersonService iTaPersonService;

    @Autowired
    ITaPetService iTaPetService;

    @Autowired
    ITaPetIdentityService iTaPetIdentityService;

    @Autowired
    WxUtils wxUtils;


    @GetMapping("/preload")
    @ApiOperation(value="小程序预加载", notes = "小程序预加载", httpMethod = "POST", response = ResponseBean.class)
    public ResponseBean preload(@ApiParam("客户端ID") @PathVariable String clientId,
                                @ApiParam("小程序预加载参数") @RequestParam(required = false) WxMaPreload wxMaPreload) throws Exception {

        return ResponseBean.success(null);
    }

    /**
     * 小程序
     * @param loginParam
     * @return
     * @throws Exception
     */
    @PostMapping("/login")
    @ApiOperation(value="小程序登录", notes = "小程序登录", httpMethod = "POST", response = ResponseBean.class)
    public ResponseBean appLogin(@ApiParam("客户端ID") @PathVariable String clientId,
                                 @ApiParam("登录参数") @RequestBody MaLogin loginParam) throws Exception {

        String code = loginParam.getCode();
        WxMaJscode2SessionResult sessionInfo = wxUtils.getMaService().getUserService().getSessionInfo(code);
        String openid = sessionInfo.getOpenid();
        String sessionKey = sessionInfo.getSessionKey();

        TaPerson taPerson = iTaPersonService.getExistBy("openid", openid, false, true);
        if (null == taPerson) {
            taPerson = new TaPerson();
            taPerson.setOpenid(openid);
            taPerson.setStatus(Constants.STATUS_NORMAL);
            taPerson.setCreateDate(LocalDateTime.now());
            iTaPersonService.save(taPerson);
        }

        StpUtil.login(taPerson.getPersonId(), clientId);
        Map<String, Object> res = new HashMap<>();
        res.put("person", taPerson);
        res.put("pets", iTaPetService.getListBy("person_id", taPerson.getPersonId(), true, true));
        res.put("cards", iTaPetIdentityService.getListBy("person_id", taPerson.getPersonId(), true, true));
        res.put("token", StpUtil.getTokenValue());
        res.put("sessionKey", sessionKey);

        return ResponseBean.success(res);
    }


    @PutMapping("/auth-user")
    @ApiOperation(value="授权头像", notes = "授权头像", httpMethod = "PUT", response = TaPerson.class)
    public ResponseBean updateUserInfo(@ApiParam("客户端ID") @PathVariable String clientId,
                                       @ApiParam("授权头像的参数") @RequestBody WxMaAuthParam params) throws Exception {
        WxMaService service = wxUtils.getMaService();
        checkAuthParams(service, params);

        // 解密用户信息
        WxMaUserInfo userInfo = service.getUserService().getUserInfo(params.getSessionKey(), params.getEncryptedData(), params.getIv());

        TaPerson taPerson = currentPerson();
        if (null == taPerson) {
            throw new Exception("校验当前人员失败, 请重试");
        }

        taPerson.setAvatar(userInfo.getAvatarUrl());
        taPerson.setNickName(userInfo.getNickName());
        taPerson.setSex(Integer.parseInt(userInfo.getGender()));

        iTaPersonService.updateById(taPerson);

        return ResponseBean.success(taPerson);
    }

    @ApiOperation(value="授权手机", notes = "授权手机", httpMethod = "PUT", response = TaPerson.class)
    @PutMapping("/auth-phone")
    public ResponseBean updateUserPhone(@ApiParam("客户端ID") @PathVariable String clientId,
                                        @ApiParam("授权手机的参数") @RequestBody WxMaAuthParam params) throws Exception {

        WxMaService service = wxUtils.getMaService();

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = service.getUserService().getPhoneNoInfo(params.getSessionKey(), params.getEncryptedData(), params.getIv());

        TaPerson taPerson = currentPerson();
        if (null == taPerson) {
            throw new Exception("校验当前人员失败, 请重试");
        }

        taPerson.setPhone(phoneNoInfo.getPhoneNumber());
        iTaPersonService.updateById(taPerson);

        return ResponseBean.success(taPerson);
    }


    private void checkAuthParams(WxMaService service, WxMaAuthParam params) throws Exception {
        String signature = params.getSignature();
        String rawData = params.getRawData();
        String encryptedData = params.getEncryptedData();
        String iv = params.getIv();
        String sessionKey = params.getSessionKey();

        if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(rawData) || StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv) || StringUtils.isEmpty(sessionKey)) {
            throw new Exception("缺失授权参数");
        }

        boolean isValid = service.getUserService().checkUserInfo(sessionKey, rawData, signature);
        if (!isValid) {
            throw new Exception("校验授权参数失败, 请重试");
        }
    }
}
