package com.xxfc.platform.im.biz;

import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.vo.ImiVo;
import com.github.wxiaoqi.security.common.constant.UserConstant;
import com.github.wxiaoqi.security.common.msg.BaseResponse;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.mongodb.client.result.UpdateResult;
import com.xxfc.platform.im.model.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@Slf4j
public class UserBiz {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    UserFeign userFeign;

    @Value("${im.url}")
    String imUrl;

    /**
     * 注册
     * @param map
     * @return
     */
    public BaseResponse register(Map<String, Object> map){
        BaseResponse baseResponse = new BaseResponse();
        String str = "";
        if(map.get("telephone") != null && !("").equals(map.get("telephone"))){
            str += "telephone="+map.get("telephone").toString()+"&";
        }
        if(map.get("password") != null && !("").equals(map.get("password"))){
            str += "password="+map.get("password").toString()+"&";
        }
        if(map.get("nickname") != null && !("").equals(map.get("nickname"))){
            str += "nickname="+map.get("nickname").toString();
        }
        String result = this.doPost(imUrl + "/user/register",str) ;
        JSONObject json = JSONObject.parseObject(result);
        //如果已经注册过，查询出手机号对应用户信息执行登录返回
        if(0 == json.getInteger("resultCode")){
            String phone = map.get("telephone").toString();
            Query query = new Query(Criteria.where("phone").is(phone));
            User mgt = mongoTemplate.findOne(query, User.class);
            if(mgt == null){
                result = "系统错误";
            }else{
                json.put("password",mgt.getPassword());
                Map<String,Object> params = new HashMap<String,Object>();
                params.put("userId",mgt.getId());
                json.put("data",params);
                result = json.toJSONString();
                /*Map<String,Object>params = new HashMap<String,Object>();
                params.put("userId",mgt.getUserId());
                params.put("telephone",mgt.getPhone());
                params.put("password",mgt.getPassword());
               result = this.login(params);*/
            }
        }else{
            json.put("password",map.get("password").toString());
            result = json.toJSONString();
        }

        baseResponse.setStatus(200);
        baseResponse.setMessage(result);
        log.info("用户注册：result = {}, telephone = {}, password = {}, nickname = {}", result, map.get("telephone"), map.get("password"), map.get("nickname"));
        return  baseResponse;
    }


    /**
     * 登录
     * @param map
     * @return
     */
    public String login(Map<String, Object> map) {
        String str = "";
        if(map.get("userId") != null && !("").equals(map.get("userId"))){
            str += "userId="+map.get("userId").toString()+"&";
        }
        if(map.get("telephone") != null && !("").equals(map.get("telephone"))){
            str += "telephone="+DigestUtils.md5Hex(map.get("telephone").toString())+"&";
        }
        if(map.get("password") != null && !("").equals(map.get("password"))){
            str += "password="+map.get("password").toString();
        }
        str += "&areaCode=86";
        String result = this.doPost(imUrl + "/user/login",str) ;
        JSONObject json = JSONObject.parseObject(result);
        log.info("用户登录：result = {}, telephone = {}, password = {}, userId = {}", result, map.get("telephone"), map.get("password"), map.get("userId"));
        json.put("password",map.get("password").toString());
        return  json.toJSONString();
    }

    public ObjectRestResponse updateUserInfo(String nickname) {
        AppUserDTO appUserDTO = getUserInfo();
        if(appUserDTO == null) {
            return ObjectRestResponse.createFailedResult(500, "token失效");
        }
        if(StringUtils.isBlank(nickname)) {
            return ObjectRestResponse.paramIsEmpty();
        }
        String phone = appUserDTO.getUsername();
        Query query = new Query(Criteria.where("phone").is(phone));

        Update update = Update.update("nickname",nickname);
       UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Map.class,"user");
       return ObjectRestResponse.succ(updateResult);
    }

    /**
     * 远程请求
     * @param path
     * @param params
     * @return
     */
    private String doPost(String path,String params){
        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        String result = null;
        try {
            URL url = new URL(path);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间：60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoOutput(true);
            // 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
            connection.setDoInput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 通过连接对象获取一个输出流
            os = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            os.write(params.getBytes());
            // 通过连接对象获取一个输入流，向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            connection.disconnect();
        }
         return result;
    }

    public AppUserDTO getUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if(request.getHeader("Authorization") !=null) {
            return userFeign.userDetailByToken(request.getHeader("Authorization")).getData();
        } else if(request.getHeader("access_token") != null) {
            return userFeign.userDetailByToken(request.getHeader("access_token")).getData();
        }
       return null;
    }

    public ImiVo getUserInfo(Integer imId) {
        ImiVo imiVo = userFeign.findUserInfoByImiId(imId);
        return imiVo;
    }

    /**
     *根据 id 批量查询
     * @param imUserIds
     * @return
     */
    public Map<Integer,User> findAllByImUserIds(List<Integer> imUserIds) {
         Map<Integer,User> imUserMap = new HashMap<>(imUserIds.size());
        List<User> users = mongoTemplate.find(Query.query(Criteria.where("id").in(imUserIds)), User.class);
        if (CollectionUtils.isEmpty(users)){
           return imUserMap;
        }
        imUserMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        return imUserMap;
    }

    /**
     * 更新Im 密码
     * @param telphone
     * @param password
     */
    public void updatePasswordByPhone(String telphone,String password){
        Query query = Query.query(Criteria.where("phone").is(telphone));
        Update update = Update.update("password", password);
        mongoTemplate.updateFirst(query,update,Map.class,"user");
    }

    /**
     * 删除 im
     * @param imUserId
     */
    public void deleteById(Integer imUserId) {
        mongoTemplate.remove(Query.query(Criteria.where("id").is(imUserId)),User.class);
    }
}
