
package com.zfire.mall.manager.schedule;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.controller.customerFront.WorkerOrderInfo;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import com.zfire.mall.manager.utils.AESUtils;
import com.zfire.mall.manager.utils.Base64Util;
import com.zfire.mall.manager.utils.HttpUtils;
import com.zfire.mall.manager.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 对接工单系统
 */

@Slf4j
@Service
public class GongdanLogic {

    @Value("${gongdan.token.get.url}")
    private String getTokenUrl;
    @Value("${gongdan.install.create.url}")
    private String createInstallUrl;
    @Value("${gongdan.repair.create.url}")
    private String createRepairUrl;
    @Value("${gongdan.install.detail.url}")
    private String detailInstallUrl;
    @Value("${gongdan.repair.detail.url}")
    private String detailRepairUrl;
    @Value("${gongdan.client_name}")
    private String clientName;
    @Value("${gongdan.password}")
    private String password;
    @Value("${gongdan.key}")
    private String key;


    @Autowired
    RedisUtil redisUtil;

    @Autowired
    CustomerOrderService customerOrderService;

    @Autowired
    CustomerOrderItemService customerOrderItemService;


    @Autowired
    KingDeeCustomerService kingDeeCustomerService;

    @Autowired
    KingDeeMaterialService kingDeeMaterialService;

    @Autowired
    KingDeeCategoryService kingDeeCategoryService;


    /**
     * 获取工单token
     *
     * @return
     * @throws RemoteServiceException
     */

    public String getGongdanToken() throws Exception {
        //redisUtil.del(Constant.RedisPrefix.TOKEN_GONGDAN);
        if (redisUtil.hasKey(Constant.RedisPrefix.TOKEN_GONGDAN)) {
            String token = (String) redisUtil.get(Constant.RedisPrefix.TOKEN_GONGDAN);
            log.info("【获取工单token】：{}", token);
            return (String) redisUtil.get(Constant.RedisPrefix.TOKEN_GONGDAN);
        }
        Map<String, Object> dataContents = new HashMap<>();
        dataContents.put("password", password);
        //请求php服务
        JSONObject jsonObject = this.doPhpSevice(dataContents, null, getTokenUrl);
        JSONObject data = (JSONObject) jsonObject.get("data");
        long time = new Date().getTime() / 1000;
        Integer exp = (Integer) data.get("exp");
        String token = (String) data.get("token");
        String prefix = (String) data.get("prefix");
        redisUtil.set(Constant.RedisPrefix.TOKEN_GONGDAN, prefix + token, exp - time - 100);

        return token;
    }


    /**
     * 创建安装工单
     *
     * @param
     * @param orderId
     * @return
     * @throws Exception
     */


    public String installOrder(String orderId) throws Exception {
        CustomerOrder customerOrder = customerOrderService.getById(orderId);
        List<CustomerOrderItem> customerOrderItems = customerOrderItemService.lambdaQuery().eq(CustomerOrderItem::getOrderId, orderId).list();
        if (customerOrder == null) {
            return null;
        }
        KingDeeCustomer kingDeeCustomer = kingDeeCustomerService.getById(customerOrder.getCustomerId());
        if (kingDeeCustomer.getAfterNumber() == null)
            return null;

        Map<String, Object> map = new HashMap<>();
        map.put("sales_websit_number", kingDeeCustomer.getAfterNumber());
        map.put("websit_worker_mobile", "");
        map.put("user_name", customerOrder.getUserName());
        map.put("user_phone", customerOrder.getPhone());
        map.put("user_phone2", "");
        map.put("sales_order_no", customerOrder.getId());
        map.put("buy_datetime", customerOrder.getCreateTime().getTime() / 1000);
        map.put("province", customerOrder.getProvince());
        map.put("city", customerOrder.getCity());
        map.put("area", customerOrder.getArea());
        map.put("street", customerOrder.getStreet());
        map.put("address", customerOrder.getReceAddress());
        map.put("request_no", IdWorker.getIdStr());
        map.put("remark", customerOrder.getNotes());

        List<Map<String, Object>> productList = new ArrayList<>();
        for (CustomerOrderItem detail : customerOrderItems) {

            KingDeeMaterial kingDeeMaterial = kingDeeMaterialService.getById(detail.getMaterialId());
            KingDeeCategory kingDeeCategory = kingDeeCategoryService.getById(kingDeeMaterial.getCategoryId());

            if (kingDeeCategory.getMainNumber() == null)
                continue;

            Map<String, Object> pMap = new HashMap<>();
            pMap.put("name", detail.getSpecification());
            pMap.put("main_id", kingDeeCategory.getMainNumber());
            pMap.put("small_id", "");
            pMap.put("number", detail.getQty());
            pMap.put("price", "");
            pMap.put("pic_url", "");
            productList.add(pMap);
        }
        if (productList.size() == 0) {
            return null;
        }
        map.put("product_list", productList);
        Map<String, String> header = new HashMap<>();
        header.put("Authorization", this.getGongdanToken());

        JSONObject jsonObject = this.doPhpSevice(map, header, createInstallUrl);

        JSONObject data = (JSONObject) jsonObject.get("data");
        String workerOrderNo = (String) data.get("worker_order_no");

        customerOrder.setGongDanId(workerOrderNo);
        customerOrder.updateById();
        return "";
    }


    private JSONObject doPhpSevice(Map<String, Object> dataContents, Map<String, String> header, String url) throws Exception {
        return this.doPhpSevice(dataContents, header, url, "POST");
    }


    /**
     * 通用请求
     *
     * @param dataContents
     * @param header
     * @param url
     * @return
     * @throws Exception
     */

    private JSONObject doPhpSevice(Map<String, Object> dataContents, Map<String, String> header, String url, String method) throws Exception {
        String ivValue = get16Random();
        String iv = Base64Util.encode(ivValue.getBytes());

        //dataContents.put("password",password);
        String dataJson = JSONObject.toJSONString(dataContents);
        log.info("【请求工单服务】request...：dataContents:{},iv:{},client_name:{}", dataJson, ivValue, clientName);
        byte[] bytes = AESUtils.encryptAES(dataJson, ivValue, key).getBytes();
        String encode = Base64Util.encode(bytes);

        Map<String, String> map = new HashMap<>();
        map.put("client_name", clientName);
        map.put("data_contents", encode);
        map.put("iv", iv);

        log.info("【请求工单服务，加密】request...：{}", JSONObject.toJSONString(map));
        String s = "";
        if (StringUtils.equals(method, "POST")) {
            s = HttpUtils.requestPostForm(url, map, header);
        } else {
            s = HttpUtils.requestGet(url, map, header);
        }
        log.info("【请求工单服务】response...：{}", s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if (jsonObject == null || !jsonObject.get("code").toString().equals("1")) {
            throw new RemoteServiceException("对接工单系统失败,请联系相关开发人员");
        }
        return jsonObject;
    }


    public static String get16Random() {
        //随机生成一位整数
        int random = (int) (Math.random() * 9 + 1);
        String valueOf = String.valueOf(random);
        //生成uuid的hashCode值
        int hashCode = UUID.randomUUID().toString().hashCode();
        //可能为负数
        if (hashCode < 0) {
            hashCode = -hashCode;
        }
        String value = valueOf + String.format("%015d", hashCode);
        return value;
    }


    public String checkSign(String data, String iv, String lKey) {
        String s = "";
        log.info("【工单进度通知】content:{},iv:{},lKey:{}", data, iv, lKey);
        try {
            String rIv = new String(Base64Util.decode(iv));
            //String data = new String(Base64Util.decode(content));
            if (StringUtils.isEmpty(lKey)) {
                lKey = key;
            }
            s = AESUtils.decryptAES(data, rIv, lKey);
        } catch (Exception e) {
            throw new RemoteServiceException("解密失败");
        }
        if (StringUtils.isEmpty(s)) {
            throw new RemoteServiceException("解密失败");
        }
        return s;
    }

//    @Test
//    public void test() throws Exception {
//        String key = "6aw4gwGqwQRR4-12";
//        String clientName = "gs-java";
//        //加密
//        Map<String,Object> map = new HashMap<>();
//        map.put("userId","1554378014451503106");
//        map.put("orderStatus","已派单");
//        map.put("workerOrderNo","6620221019101256930521");
//        map.put("orderId","5060");
//        map.put("prepareTime","2022-10-19 上午");
//        map.put("workerName","张珊珊");
//        map.put("remark","预约维修");
//        String dataJson = JSONObject.toJSONString(map);
//        String inValue =  get16Random();
//        String iv = Base64Util.encode(inValue.getBytes());
//        String content = AESUtils.encryptAES(dataJson, inValue, key);
//
//        Map<String,String> param = new HashMap<>();
//        param.put("client_name",clientName);
//        param.put("data_contents",content);
//        param.put("iv",iv);
//
//        //解密
//        String s = this.checkSign(content,iv,key);
//
//        System.out.print("结果:"+s);
//
//    }

    @Test
    public void test() {
        String content = "wFzuMYdrh6T0fGDqxlum0+h717qodaKI93+7cF1JeuuWkklWQNx1wZiqMrUJw+bv";
        String iv = "aWRvV051bUZQSGhnbG5jdw==";
        String s = this.checkSign(content, iv, "6aw4gwGqwQRR4-22");
        System.out.print(s);
    }


    /**
     * 安装工单列表
     */
    public List<WorkerOrderInfo> getInstallOrderList(String orderId) throws Exception {

        List<WorkerOrderInfo> workerOrderInfos = new ArrayList<>();
        try{
            Map<String,Object> map = new HashMap<>();
            map.put("request_order_no",orderId);
            Map<String,String> header = new HashMap<>();
            header.put("Authorization",this.getGongdanToken());
            JSONObject jsonObject  = this.doPhpSevice(map, header, detailInstallUrl);
            JSONArray datas = (JSONArray)jsonObject.get("data");
            for(Object o : datas) {
                JSONObject data = (JSONObject)o;
                WorkerOrderInfo workerOrderInfo = new WorkerOrderInfo();
                workerOrderInfo.setWorkerOrder(data.getString("worker_order_no"));
                workerOrderInfo.setPgid(data.getString("pgid"));
                workerOrderInfo.setWorkerName(data.getString("worker_name"));
                workerOrderInfo.setWorkerPhone(data.getString("worker_phone"));
                workerOrderInfo.setInstallNumber(data.getString("install_number"));
                workerOrderInfo.setInstallName(data.getString("install_name"));
                workerOrderInfo.setOrderState(data.getString("order_state_text"));
                workerOrderInfo.setOrderStateInt(data.getInteger("order_state"));
                workerOrderInfo.setOrderReceTime(data.getString("receive_time_text"));
                workerOrderInfo.setFinishTime(data.getString("finish_time_text"));
                workerOrderInfo.setReserveTime(data.getString("reserve_datetime_text"));
                workerOrderInfo.setServerContent("安装服务");
                workerOrderInfo.setBracket(data.getString("bracket"));
                workerOrderInfo.setPipe(data.getString("pipe"));
                workerOrderInfo.setSwitchFlag(data.getString("switch_flag"));
                workerOrderInfo.setHighAltitude(data.getString("high_altitude"));
                workerOrderInfo.setHole(data.getString("hole"));
                workerOrderInfo.setRemark(data.getString("remark"));
                //辅助人员
                List<Map<String, String>> assist = (List<Map<String, String>>) data.get("assist_data_list");
                if(CollectionUtils.isNotEmpty(assist)){
                    workerOrderInfo.setAssistName(assist.get(0).get("name"));
                }
                //操作类型
                List<WorkerOrderInfo.Fkxx> fkxxs = new ArrayList<>();
                List<Map<String, String>> operators = (List<Map<String, String>>) data.get("order_install_operating_log");
                if (CollectionUtils.isNotEmpty(operators)) {
                    for (Map<String, String> operator : operators) {
                        WorkerOrderInfo.Fkxx fkxx = new WorkerOrderInfo.Fkxx();
                        fkxx.setOperatorType(operator.get("type"));
                        fkxx.setOperatorContent(operator.get("content"));
                        fkxx.setLastOperatorTime(operator.get("updatetime"));
                        fkxx.setOperatorName(operator.get("operator"));
                        fkxx.setOperatorWebsit(operator.get("operate_websit"));
                        fkxx.setResult(operator.get("feedback"));
                        fkxxs.add(fkxx);
                    }
                    workerOrderInfo.setFkxxs(fkxxs);
                }
                List<Map<String, Object>> stocks = (List<Map<String, Object>>) data.get("stock_order");
                if (CollectionUtils.isNotEmpty(stocks)) {
                    //辅材信息
                    List<WorkerOrderInfo.Fcxx> fcxxs = new ArrayList<>();
                    for (Map<String, Object> stock : stocks) {
                        WorkerOrderInfo.Fcxx fcxx = new WorkerOrderInfo.Fcxx();
                        fcxx.setId((int) stock.get("id"));
                        fcxx.setOrderNo((String) stock.get("docnum"));
                        fcxx.setOperatorWebsit((String) stock.get("websit_name"));
                        fcxx.setOperatorName((String) stock.get("worker_name"));
                        fcxx.setPayStatus((String) stock.get("pay_status_text"));
                        fcxx.setPayTime((String) stock.get("paytime_text"));
                        fcxx.setAmount((String) stock.get("total_amount"));
                        fcxx.setRemark((String) stock.get("remark"));

                        List<Map<String, Object>> details = (List<Map<String, Object>>) stock.get("stock_order_goods");
                        fcxx.setDetails(details);
                        fcxxs.add(fcxx);
                    }
                    workerOrderInfo.setFcxxs(fcxxs);
                }

                workerOrderInfos.add(workerOrderInfo);
            }
        }catch(Exception e){
            log.error("获取安装工单列表失败"+e.getMessage());
        }
        return workerOrderInfos;

    }

}

