package com.iotechn.unimall.admin.api.user;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dangdang.openplatform.openapi.sdk.ApiException;
import com.dangdang.openplatform.openapi.sdk.SdkClient;
import com.dangdang.openplatform.openapi.sdk.internal.util.FileItem;
import com.dangdang.openplatform.openapi.sdk.request.order.OrderDetailsGetRequest;
import com.dangdang.openplatform.openapi.sdk.request.order.OrderGoodsSendRequest;
import com.dangdang.openplatform.openapi.sdk.request.order.OrdersContentDecryptRequest;
import com.dangdang.openplatform.openapi.sdk.requestmodel.order.EncryptDTO;
import com.dangdang.openplatform.openapi.sdk.requestmodel.order.OrderDetailsGet;
import com.dangdang.openplatform.openapi.sdk.response.order.OrderDetailsGetResponse;
import com.dangdang.openplatform.openapi.sdk.response.order.OrderGoodsSendResponse;
import com.dangdang.openplatform.openapi.sdk.response.order.OrdersContentDecryptResponse;
import com.dangdang.openplatform.openapi.sdk.responsemodel.order.CryptUserInfo;
import com.dangdang.openplatform.openapi.sdk.responsemodel.order.OrdersContentDecryptDTO;
import com.google.gson.JsonObject;
import com.iotechn.unimall.core.util.MD5Util;
import com.iotechn.unimall.data.util.XMLUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.iotechn.unimall.core.exception.AdminServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.data.domain.UserDO;
import com.iotechn.unimall.data.mapper.UserMapper;
import com.iotechn.unimall.data.model.Page;
import okhttp3.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: kbq
 * Date: 2019-07-11
 * Time: 下午7:57
 */
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Autowired
    private UserMapper userMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUser(Long adminId, UserDO user) throws ServiceException {
        if (user == null) {
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if (user.getPhone() == null) {
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if (userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone", user.getPhone())) > 0) {
            throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
        }
        Date now = new Date();
        user.setId(null);
        user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0, 7)));
        user.setGmtCreate(now);
        user.setGmtUpdate(now);
        return userMapper.insert(user) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long adminId, Long id, String nickname) throws ServiceException {
        return userMapper.delete(new EntityWrapper<UserDO>()
                .eq("id", id)
                .eq("nickname", nickname)) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(Long adminId, UserDO user) throws ServiceException {
        if (user == null || user.getId() == null) {
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if (user.getPhone() == null) {
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if (userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone", user.getPhone()).notIn("id", user.getId())) > 0) {
            throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
        }
        Date now = new Date();
        user.setGmtUpdate(now);
        UserDO userDO = userMapper.selectById(user.getId());
        if (userDO.getPassword().equals(user.getPassword())) {
            return userMapper.updateById(user) > 0;
        }
        if (user.getPassword() != null) {
            user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0, 7)));
        }
        return userMapper.updateById(user) > 0;
    }

    @Override
    public Boolean updateStatus(Long adminId, Long userId, Integer status) throws ServiceException {
        if (userId == null || status == null || (status != 0 && status != 1)) {
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        UserDO userDO = new UserDO();
        userDO.setId(userId);
        userDO.setStatus(status);
        userDO.setGmtUpdate(new Date());
        if (userMapper.updateById(userDO) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Page<UserDO> getUser(Long adminId, Long id, String nickname, Integer level, Integer gender, Integer status, Integer pageNo, Integer limit) throws ServiceException {
        Integer count = userMapper.countUser(id, nickname, level, gender, status);
        List<UserDO> userDOList = userMapper.getUserList(id, nickname, level, gender, status, limit * (pageNo - 1), limit);
        Page<UserDO> page = new Page<UserDO>(userDOList, pageNo, limit, count);
        return page;
    }

    @Override
    public String test(String param, String param1) throws Exception {
        String url = "https://open-api.ushengyun.com/printer/print";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 模拟登陆，按实际服务器端要求选用 Post 或 Get 请求方式
        HttpPost httpPost = new HttpPost(url);
        SortedMap<Object, Object> params = new TreeMap<Object, Object>();
        Long now = new Date().getTime();
        params.put("appid", "10317");
        params.put("timestamp", now);
        params.put("deviceid", "70006716");
        params.put("devicesecret", "y77iba4i");
        params.put("printdata", "<S2><C>#1 饿了么</C></S2><S1><C>优声科技(成都店)</C></S1><S1><C>--在线支付--</C></S1><S2><C>[预订单]</C></S2>");
        String sign = createSign(params,"eaf56473cc6cba0d5a8e10d3a35ab51b");
        params.put("sign", sign);
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(params));

        httpPost.setEntity(new StringEntity(jsonObject.toString(), StandardCharsets.UTF_8));
        ;
        // 设置header信息
        httpPost.setHeader("Content-type", "application/json");
        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            // 执行请求操作，并拿到结果（同步阻塞）
            String body = EntityUtils.toString(response.getEntity());
            jsonObject = JSONObject.parseObject(body);
            if (jsonObject.getString("status").equals("1001")) {
                String token = jsonObject.getJSONObject("result").getString("token");
                System.out.println("token = " + token);
                return token;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放链接
            response.close();
            httpClient.close();
        }

        return "";

    }
    /**
     * 生成签名
     */
    public static String createSign(SortedMap<Object,Object> parameters,String key){
        StringBuffer sbkey = new StringBuffer();
        //1.将所有参与传参的参数按照accsii排序（升序)
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            //2.空值不传递，不参与签名组串
            if(null != v && !"".equals(v)) {
                sbkey.append(k + v );
            }
        }
        sbkey=sbkey.append(key);
        System.out.println("排序好的顺序为："+sbkey.toString());
        //3.MD5加密,结果转换为大写字符
        String sign = getMD5(sbkey.toString()).toLowerCase();
        return sign;
    }

    /**
     * 对字符串进行MD5加密
     */
    public static String getMD5(String str) {
        MessageDigest digest;

        try {
            digest = MessageDigest.getInstance("MD5");
            digest.update(str.getBytes());
            return new BigInteger(1, digest.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}
