package com.boco.nbd.wios.wx.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.boco.nbd.wios.manage.entity.bo.LoginInfo;
import com.boco.nbd.wios.manage.entity.bo.RoleBo;
import com.boco.nbd.wios.manage.service.impl.AccountService;
import com.boco.nbd.wios.manage.service.impl.RoleService;
import com.boco.nbd.wios.wx.utils.WeChatSessionKeyUtils;
import com.boco.nbd.wios.wx.vo.MinaLoginInfo;
import com.ihidea.component.api.v2.BaseResponse;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.util.BeanUtilsEx;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

/**
 * @author kevin
 * @create 2020/10/28 20:59
 */
@Api(tags = "微信小程序用户相关接口")
@RestController
@RequestMapping("/mina")
@ApiIgnore
public class MinaUserController {

    private static final String MINA_MENU="mina";

    @Autowired
    private AccountService accountService;

    @Autowired
    private RoleService roleService;


    @PostMapping(value = "/getOpenIdByCode")
    @ApiOperation(value = "根据code获取openId")
    @ApiImplicitParams({@ApiImplicitParam(name = "code", value = "微信code", dataType = "String", paramType = "query", required = true)})
  	public BaseResponse<String> getOpenIdByCode(String code) {
        String openId = null;
        if(StringUtils.isNotBlank(code)){
            openId = WeChatSessionKeyUtils.getOpenIdForWxInstant(code);
            if (StringUtils.isBlank(openId)) {
                throw new ServiceException("使用微信登陆失败,请刷新页面或重新进入");
            }
        }
        return new BaseResponse<>(openId);
  	}

    /**
     * 账号密码登录
     *
     * 登录的用户可能是区域工程经理、安装服务商员工(角色不固定),角色不同会导致订单查看范围不同
     * 0. 判断账号和密码是否匹配, 检查是否有小程序权限
     *
     * 后续查询订单
     * 1. 判断是否是区域工程经理角色(ROLE_ID:5)
     * 2. 如果是区域工程经理,根据负责的区域编号查询订单
     * 3. 如果是安装服务商员工,根据数据权限是个人还是全部来查询订单
     * 4. 查询订单数据范围(区域regionId,安装服务商supplierId, 员工staffId)
     *
     * 也就是登录成功后,需要返回当前用户角色和小程序按钮权限
     *
     * @param account
     * @param password
     * @return
     */
    @PostMapping(value = "/staff/login")
    @ApiOperation(value = "员工账号+密码登录")
    @ApiImplicitParams({@ApiImplicitParam(name = "account", value = "账号(手机号码)", dataType = "String", paramType = "query", required = true), 
    	@ApiImplicitParam(name = "password", value = "密码(手机端md5加密)", dataType = "String", paramType = "query", required = true)})
    public BaseResponse<MinaLoginInfo> login(String account, String password) throws Exception {

        LoginInfo loginInfo = accountService.loginMina(account, password);
        return new BaseResponse<>(convertLoginInfo(loginInfo));
    }

    /**
     * 一般登录信息转换为小程序登录信息
     * @param loginInfo
     * @return
     * @throws Exception
     */
    private MinaLoginInfo convertLoginInfo(LoginInfo loginInfo) throws Exception{
        MinaLoginInfo minaLoginInfo=BeanUtilsEx.copyPropertiesUnConvert(loginInfo, MinaLoginInfo.class);
        minaLoginInfo=getPermission(minaLoginInfo);
        Assert.notNull(minaLoginInfo.getCurrRoleId(), "无权限,请联系管理员开通权限");
        return minaLoginInfo;
    }

    private MinaLoginInfo getPermission(MinaLoginInfo minaLoginInfo){
        // 判断当前用户是否具有小程序权限
        List<RoleBo> roles=roleService.findMinaRoleMenu(minaLoginInfo.getAccountId());
        if(CollUtil.isNotEmpty(roles)){
            roles.forEach((role)->{
                if(StringUtils.contains(role.getMenuIds(), MINA_MENU)){
                    minaLoginInfo.setCurrRoleId(role.getId());
                    minaLoginInfo.setCurrRoleName(role.getName());
                    minaLoginInfo.setMenus(role.getMenuIds());
                    return;
                }
            });
        }
        return minaLoginInfo;
    }

    @GetMapping(value = "/staff/permission")
    @ApiOperation(value = "获取权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountId", value = "账号编号", dataType = "int", paramType = "query", required = true),
    })
    public BaseResponse<MinaLoginInfo> getPermissionByAccountId(Integer accountId) throws Exception{
        MinaLoginInfo minaLoginInfo=new MinaLoginInfo();
        minaLoginInfo.setAccountId(accountId);

        return new BaseResponse<>(getPermission(minaLoginInfo));
    }

    @PostMapping(value = "/staff/loginByWx")
    @ApiOperation(value = "微信授权手机号码登录")
    @ApiImplicitParams({@ApiImplicitParam(name = "openId", value = "微信openId", dataType = "String", paramType = "query", required = true), 
    	@ApiImplicitParam(name = "encryptedData", value = "包括敏感数据在内的完整用户信息的加密数据", dataType = "String", paramType = "query", required = true),
    	@ApiImplicitParam(name = "iv", value = "加密算法的初始向量", dataType = "String", paramType = "query", required = true)})
    public BaseResponse<MinaLoginInfo> loginByWx(String openId, String encryptedData, String iv) throws Exception{
        return new BaseResponse<>(convertLoginInfo(accountService.loginMinaByWx(openId, encryptedData, iv)));
    }
}