package com.sptg.gateway.controller.implement;

import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.SysLogConstant;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.common.core.util.WebUtils;
import com.sptg.common.security.service.SecurityServiceInterface;
import com.sptg.permissions.api.dto.AccountDto;
import com.sptg.permissions.api.dto.LoginDto;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.feigns.AccountAuthenticationFeign;
import com.sptg.permissions.api.feigns.AccountFeign;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.statistics.api.entity.SysOperationLog;
import com.sptg.statistics.api.feigns.SysOperationLogFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * title: AccountController
 * package: com.sptg.estate.biz.security
 * description: 实施小程序-账号控制器
 *
 *               
 *                      
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/app/account")
public class AccountController {

    private final AccountAuthenticationFeign accountAuthenticationFeign;
    private final AccountFeign accountFeign;
    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final RestTemplate restTemplate;
    private final SysOperationLogFeign sysOperationLogFeign;
    private final ConfFeign confFeign;

    /**
     * 功能描述: 登录接口
     * @param map {
     *             loginName     :    登录名,
     *             loginPwd      :    登录密码
     *            }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                      
     */
    @PostMapping(value = "/login")
    public Map<String,Object> login(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(4);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "登录失败");
        try {
            String loginName = map.get("loginName");
            String loginPwd = map.get("loginPwd");
            if(StringUtils.isBlank(loginName)){
                hashMap.put("result_msg", "登陆名不能为空")
                ;
                return hashMap;
            }
            if(StringUtils.isBlank(loginPwd)){
                hashMap.put("result_msg", "登陆密码不能为空");
                return hashMap;
            }
            LoginDto dto = new LoginDto();
            dto.setLoginName(loginName);
            dto.setLoginPwd(loginPwd);
            ResultBean<Account> resultBean = this.accountAuthenticationFeign.login(dto);
            //账号密码正确
            if (resultBean.getCode().equals(ResultEnum.SUCCESS.getCode())){
                //  用户信息
                Account account = resultBean.getData();
               // 是否开启微信小程序登录 1：已启动，2：未启用
                if(account.getIsWeChatLogin()!=null && account.getIsWeChatLogin()==1){
                    hashMap.put("result_code", 1);
                    hashMap.put("result_msg", "登录成功");
                    //  创建用户令牌
                    String token = this.securityServiceInterface.createUserToken(account);
                    if(StringUtils.isNotBlank(account.getUserPortraitUri())){
                        account.setUserPortraitUri(this.confFeign.getFileServerHost()+account.getUserPortraitUri());
                    }
                    hashMap.put("token", token);
                    hashMap.put("account", account);
                    //  登录日志
                    SysOperationLog sysOperationLog = new SysOperationLog(SysLogConstant.LOGIN_EVENT,WebUtils.getIp(),account);
                    sysOperationLogFeign.info(sysOperationLog);
                }else{
                    hashMap.put("result_msg", "登录账号未开启登录权限，请联系管理员");
                }
            }else {
                hashMap.put("result_msg", resultBean.getMsg());
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 获取微信小程序openid
     * @param map {
     *            js_code : 微信小程序端获取的js_code，时效5分钟,
     *            }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/getOpenid")
    public Map<String,Object> getOpenid(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(3);
        //result_code:0-失败  1-成功
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "openid获取失败");
        try{
            String js_code = map.get("js_code");
            if(StringUtils.isBlank(js_code)){
                hashMap.put("result_msg", "js_code不能为空");
                return hashMap;
            }

            //获取openid的微信接口
            String wxURI = "https://api.weixin.qq.com/sns/jscode2session?appid=wx753ede716c429419&secret=1b99332a2a497aee96565a1825fafb22&grant_type=authorization_code";
            wxURI = wxURI+"&js_code="+js_code;
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(wxURI, String.class);
            //返回正常
            if(responseEntity.getStatusCodeValue()==200){
                String body = responseEntity.getBody();
                Map<String,String> result = JsonUtils.jsonToPojo(body, Map.class);
                String openid = result.get("openid");
                if(StringUtils.isNotBlank(openid)){
                    hashMap.put("result_code", 1);
                    hashMap.put("openid", result.get("openid"));
                    hashMap.put("result_msg", "openid获取成功");
                }else{
                    log.warn("从微信接口获取openid失败:"+body);
                }
            }else{
                hashMap.put("result_msg", "从微信接口获取openid失败");
                log.warn("从微信接口获取openid失败:"+responseEntity.getStatusCodeValue()+":"+responseEntity.getStatusCode());
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }
    /**
     * 功能描述: 根据openid获取账号信息--没有做redis缓冲后期再加
     * @param map {
     *            openid : 微信公众号为用户唯一标识,
     *            }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                      
     */
    @PostMapping(value = "/getByOpenid")
    public Map<String,Object> getByOpenid(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(4);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "openid获取失败");
        String openid  = map.get("openid");
        try {
            if(StringUtils.isBlank(openid)){
                hashMap.put("result_msg", "openid不能为空");
                return hashMap;
            }
            ResultBean<Account> resultBean = this.accountAuthenticationFeign.getByOpenid(openid);
            if (resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()!=null){
                Account account = resultBean.getData();
                //{ 1：已启动，2：未启用 }
                if(account.getIsWeChatLogin()==1){
                    hashMap.put("result_msg", "登录成功");
                    hashMap.put("result_code", 1);
                    //  创建用户令牌
                    String token = this.securityServiceInterface.createUserToken(account);
                    if(StringUtils.isNotBlank(account.getUserPortraitUri())){
                        account.setUserPortraitUri(this.confFeign.getFileServerHost()+account.getUserPortraitUri());
                    }
                    hashMap.put("token", token);
                    hashMap.put("account", account);
                    //  登录日志
                    SysOperationLog sysOperationLog = new SysOperationLog(SysLogConstant.LOGIN_EVENT,WebUtils.getIp(),account);
                    sysOperationLogFeign.info(sysOperationLog);
                }else{
                    hashMap.put("result_msg", "登录账号未开启登录权限，请联系管理员");
                }
            }else{
                hashMap.put("result_msg", "未获取到账号信息，请先绑定账号");
                return hashMap;
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }
    /**
     * 功能描述: 根据openid获取账号信息
     * @param map {
     *            openid      : 微信公众号为用户唯一标识,
     *            accountId   : 绑定的账号id
     *            }
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/bindOpenid")
    public Map<String,Object> bindOpenid(@RequestBody Map<String,String> map){
        Map<String,Object> hashMap = new HashMap<>(2);
        hashMap.put("result_code", 0);
        hashMap.put("result_msg", "绑定失败");
        String openid  = map.get("openid");
        String accountId  = map.get("accountId");
        try {
            if(StringUtils.isBlank(openid)){
                hashMap.put("result_msg", "openid不能为空");
                return hashMap;
            }
            if(StringUtils.isBlank(accountId)){
                hashMap.put("result_msg", "accountId不能为空");
                return hashMap;
            }
            ResultBean<Account> resultBean = this.accountAuthenticationFeign.getByOpenid(openid);
            // openid 已经绑定账号
            if(resultBean.getCode().equals(ResultEnum.SUCCESS.getCode()) && resultBean.getData()!=null){
                hashMap.put("result_msg", "该微信号已绑定了账号："+resultBean.getData().getLoginName()+",请先解绑，再绑定");
                return hashMap;
            }else{
                Account a = this.accountFeign.getById(Long.valueOf(accountId));
                if(a!=null){
                    if(StringUtils.isBlank(a.getOpenid())){
                        AccountDto dto = new AccountDto();
                        dto.setOpenid(openid);
                        dto.setId(Long.valueOf(accountId));
                        dto.setLoginName(a.getLoginName());
                        ResultBean<Boolean> result = this.accountAuthenticationFeign.bindOpenid(dto);
                        if (result.getCode().equals(ResultEnum.SUCCESS.getCode())){
                            hashMap.put("result_msg", "绑定成功");
                            hashMap.put("result_code", 1);
                        }
                    }else{
                        hashMap.put("result_msg", "要绑定的账号已绑定微信，请先解绑后再绑定");
                    }
                }else{
                    hashMap.put("result_msg", "要绑定的微信账号不存在");
                }
            }
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }

    /**
     * 功能描述: 退出登录
     * @return ResultBean<hashMap> 返回结果
     *               
     *                     
     */
    @PostMapping(value = "/logout")
    public Map<String,Object> logout(){
        Map<String,Object> hashMap = new HashMap<>(2);
        hashMap.put("result_code", 1);
        hashMap.put("result_msg", "退出成功");
        try {
            Account account = this.securityServiceInterface.getOnLineUser();
            this.securityServiceInterface.removeUserToken();
            //登出日志
            SysOperationLog sysOperationLog = new SysOperationLog(SysLogConstant.OUT_LOGIN_EVENT, WebUtils.getIp(),account);
            sysOperationLogFeign.info(sysOperationLog);
        }catch (Exception e){
            log.error("异常", e);
            hashMap.put("result_msg", "后台程序异常");
        }
        return hashMap;
    }
}
