package com.reptileclient.jlifeapp.service;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.reptileclient.jlifeapp.constant.HemaConstant;
import com.reptileclient.jlifeapp.constant.HmPayOrderStatusMapConstants;
import com.reptileclient.jlifeapp.constant.PayOrderStatusMapConstants;
import com.reptileclient.jlifeapp.dao.HmStationShopMapper;
import com.reptileclient.jlifeapp.dao.hm.JxWorkerOrderMapper;
import com.reptileclient.jlifeapp.entity.hm.*;
import com.reptileclient.jlifeapp.util.OkHttpUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
public class HmShopAndStationRelationService {

    static ObjectMapper objectMapper;

    @Autowired
    private JxWorkerOrderMapper jxWorkerOrderMapper;

    static {
        objectMapper = new ObjectMapper();
    }

    @Autowired
    private HmStationShopMapper hmStationShopMapper;

    public void syncHmShopAndStation() {
        hmStationShopMapper.cleanTable();
        List<HmSupplier> suppliers = getSupplier();
        System.out.println("suppliers = " + suppliers);
        List<HmStationShop> dbStationShops = new ArrayList<>();
        for (HmSupplier supplier : suppliers) {
            List<HmStationAndShop> stationAndShops = getStations(supplier.getSupplierCode());
            for (HmStationAndShop stationAndShop : stationAndShops) {
                List<ShopListItem> itemList = stationAndShop.getShopList();
                for (ShopListItem shopListItem : itemList) {
                    HmStationShop dbStationShop = new HmStationShop();
                    dbStationShop.setCity(getCity(shopListItem.getShopName()));
                    dbStationShop.setStationCode(stationAndShop.getStationCode());
                    dbStationShop.setStationName(stationAndShop.getStationName());
                    dbStationShop.setShopCode(shopListItem.getShopCode());
                    dbStationShop.setShopName(shopListItem.getShopName());
                    dbStationShops.add(dbStationShop);
                }
            }
        }
        hmStationShopMapper.batchInsert(dbStationShops);

    }

    private String getCity(String shopName) {
        if (StringUtils.isEmpty(shopName)) {
            return "";
        }
        if (shopName.contains("北京")) {
            return "北京";
        }
        if (shopName.contains("上海")) {
            return "上海";
        }
        if (shopName.contains("深圳")) {
            return "深圳";
        }
        if (shopName.contains("杭州")) {
            return "杭州";
        }
        if (shopName.contains("苏州")) {
            return "苏州";
        }
        if (shopName.contains("南京")) {
            return "南京";
        }
        if (shopName.contains("重庆")) {
            return "重庆";
        }
        if (shopName.contains("青岛")) {
            return "青岛";
        }
        if (shopName.contains("成都")) {
            return "成都";
        }
        return "";
    }

    private List<HmStationAndShop> getStations(String supplierCode) {
        Map<String, Object> hash = new HashMap<>();
        hash.put("pageNum", 1);
        hash.put("pageSize", 50);
//        hash.put("status", 1);// 仅查询正常的服务站信息
        hash.put("supplierCode", supplierCode);
//        hash.put("type", 0);
        String body;
        try {
            body = objectMapper.writeValueAsString(hash);
            String post = OkHttpUtil.post(HemaConstant.hmShopUrl, body);
            Map map = objectMapper.readValue(post, Map.class);
            Boolean success = (Boolean) map.get("success");
            if (success) {
                Map data = (Map) map.get("data");
//                log.info("解析成功，获取到服务站信息，结果为：" + data);
//                List<HmStationAndShop> list = (List<HmStationAndShop>) data.get("list");
                List<HmStationAndShop> list = objectMapper.readValue(objectMapper.writeValueAsString(data.get("list")),
                        new TypeReference<List<HmStationAndShop>>() {
                        });

//                log.info("服务站数据如下：" + JSONObject.toJSONString(list));
                if (null == list) {
                    return new ArrayList<>();
                }
                return list;
            } else {

                throw new RuntimeException("获取服务站信息失败，请检查网络");
            }
        } catch (JsonProcessingException e) {
            log.error("json转换异常", e);
            throw new RuntimeException(e);
        } catch (IOException e) {
            log.error("请求异常", e);
            throw new RuntimeException(e);
        }

    }


    private List<HmSupplier> getSupplier() {
        Request request = new Request.Builder().url(HemaConstant.hmSupplierUrl).get().build();
        String s = OkHttpUtil.get(request);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.readValue(s, new TypeReference<List<HmSupplier>>() {
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void synctagPayOrderInfo() {
        //根据 鲸选钟点工关键字查询所有作业单
        List<HmBookTradeOrder> tradeOrders = getWorkOrder();

        List<JxWorkerOrder> jxWorkerOrders = new ArrayList<>();
        //生成本次鲸选订单号
        List<String> jxOrderNo = generateJxOrderNo(tradeOrders.size());
        for (HmBookTradeOrder tradeOrder : tradeOrders) {
            HmPaymentOrder paymentOrder = getPayOrderByPayNo(tradeOrder.getPaymentNo());
            if (StringUtils.isBlank(paymentOrder.getPaymentNo())) {
                continue;
            }
            if (paymentOrder.getStatus() < 3 || paymentOrder.getStatus() == 7) {
                //舍弃未支付和支付前关闭的订单
                continue;
            }
            JxWorkerOrder jxWorkerOrder = new JxWorkerOrder();
            jxWorkerOrder.setJxOrderNo(jxOrderNo.remove(0));
            jxWorkerOrder.setHmPayOrderno(paymentOrder.getPaymentNo());
            jxWorkerOrder.setServiceModel(1); //默认保姆
            jxWorkerOrder.setItemName(paymentOrder.getItemName());
            jxWorkerOrder.setHmShopCode(paymentOrder.getShopCode());
            jxWorkerOrder.setHmShopName(paymentOrder.getShopName());
            jxWorkerOrder.setCustomerName(tradeOrder.getUserName()); //这个名字比较正规
            jxWorkerOrder.setCustomerPhone(tradeOrder.getUserPhone());
            //手机号中间4位掩码
            jxWorkerOrder.setCustomerMaskPhone(tradeOrder.getUserPhone().substring(0, 3) + "****" + tradeOrder.getUserPhone().substring(7, 11));
            jxWorkerOrder.setCustomerAddr(tradeOrder.getAddrName() + tradeOrder.getAddrDetail()); //详细地址
            jxWorkerOrder.setHmStatus(paymentOrder.getStatus());
            jxWorkerOrder.setStatus(getStatus(paymentOrder.getStatus()));
            jxWorkerOrder.setCustomerSource(1);
            jxWorkerOrder.setPayTime(paymentOrder.getPayTime());
            jxWorkerOrder.setWriteTime(new Date());
            jxWorkerOrders.add(jxWorkerOrder);
        }
        //合并数据库数据和接口数据
        //根据盒马服务单号合并，数据库有数据则判断盒马状态是否有变化，有则记录更新，没有则不记录，数据库没有数据则记录新增
        List<JxWorkerOrder> jxWorkerOrders1 = jxWorkerOrderMapper.list();
        Map<String, JxWorkerOrder> jxWorkerOrderMap = jxWorkerOrders1.stream()
                .collect(Collectors.toMap(JxWorkerOrder::getHmPayOrderno, jxWorkerOrder -> jxWorkerOrder));
        List<JxWorkerOrder> insert = new ArrayList<>();
        List<JxWorkerOrder> update = new ArrayList<>();
        for (JxWorkerOrder jxWorkerOrder : jxWorkerOrders) {
            if (jxWorkerOrderMap.containsKey(jxWorkerOrder.getHmPayOrderno())) {
                JxWorkerOrder jxWorkerOrder1 = jxWorkerOrderMap.get(jxWorkerOrder.getHmPayOrderno());
                if (!Objects.equals(jxWorkerOrder1.getHmStatus(), jxWorkerOrder.getHmStatus())) {
                    jxWorkerOrder.setId(jxWorkerOrder1.getId());
                    jxWorkerOrder.setJxOrderNo(jxWorkerOrder1.getJxOrderNo());
                    if (jxWorkerOrder1.getStatus() == PayOrderStatusMapConstants.WAIT_MATCH.getCode()
                            && jxWorkerOrder.getHmStatus() == HmPayOrderStatusMapConstants.PAID.getCode()) {
                        //匹配环节是我们自己进行的
                        jxWorkerOrder.setStatus(PayOrderStatusMapConstants.WAIT_MATCH.getCode());
                    }
                    update.add(jxWorkerOrder);
                }
            } else {
                insert.add(jxWorkerOrder);
            }
        }
        if (insert.size() > 0) {
            jxWorkerOrderMapper.batchInsert(insert);
        }
        if (update.size() > 0) {
            jxWorkerOrderMapper.updateBatch(update);
        }
    }

    private Integer getStatus(Integer status) {
        if (status == null) {
            return null;
        }
        //mapping
        // 盒马 已服务 ===》 服务已完成
        // 已支付 ===》已支付
        // 已取消 ===》 已退款
        //  已派单===》服务中 （自有状态）
        //  已服务===》服务已完成 （自有状态）

        if (status == HmPayOrderStatusMapConstants.PAID.getCode()) {
            return PayOrderStatusMapConstants.PAID.getCode();
        } else if (status == HmPayOrderStatusMapConstants.ASSIGNED.getCode()) {
            return PayOrderStatusMapConstants.SERVICING.getCode();
        } else if (status == HmPayOrderStatusMapConstants.COMPLETED.getCode()) {
            return PayOrderStatusMapConstants.SERVICED_COMPLETE.getCode();
        } else if (status == HmPayOrderStatusMapConstants.CANCELED.getCode()) {
            return PayOrderStatusMapConstants.REFUND.getCode();
        } else if (status == HmPayOrderStatusMapConstants.SERVICED.getCode()) {
            return PayOrderStatusMapConstants.SERVICING.getCode();
        } else {
            return 0;
        }
    }

    private List<String> generateJxOrderNo(int size) {
        String maxJxOrderNo = jxWorkerOrderMapper.getMaxJxOrderNo();
        int i = 0;
        if (!StringUtils.isBlank(maxJxOrderNo)) {
            i = Integer.parseInt(maxJxOrderNo.substring(2));
        }
        List<String> orderNos = new LinkedList<>();
        for (int i1 = 0; i1 < size; i1++) {
            orderNos.add("DD" + String.format("%07d", i + i1));
        }
        return orderNos;
    }


    private HmPaymentOrder getPayOrderByPayNo(String paymentNo) {
        Map<String, Object> hash = new HashMap<>();
        hash.put("pageIndex", 1);
        hash.put("pageSize", 200);
        hash.put("paymentNo", paymentNo);
        try {
            String s = OkHttpUtil.post(HemaConstant.hmPayUrl, objectMapper.writeValueAsString(hash));
            if (StringUtils.isBlank(s)) {
                return new HmPaymentOrder();
            } else {
                Map map = objectMapper.readValue(s, Map.class);
                Boolean success = (Boolean) map.get("success");
                if (success) {
                    Map<String, Object> data = (Map<String, Object>) map.get("data");
                    return JSONObject.parseArray(objectMapper.writeValueAsString(data.get("list")), HmPaymentOrder.class).get(0);
                } else {
                    throw new RuntimeException("解析盒马付款单数据失败");
                }

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    private List<HmBookTradeOrder> getWorkOrder(int pageNum, List<HmBookTradeOrder> result) {
        Map<String, Object> hash = new HashMap<>();
        hash.put("pageIndex", pageNum);
        hash.put("pageSize", 200);
        hash.put("itemName", "鲸选钟点工");
        try {
            String post = OkHttpUtil.post(HemaConstant.serverInfoGetUrl, objectMapper.writeValueAsString(hash));
            Map map = objectMapper.readValue(post, Map.class);
            Boolean success = (Boolean) map.get("success");
            if (success) {
                Map data = (Map) map.get("data");
                Integer nextPage = (Integer) data.get("nextPage");
                Boolean isLastPage = (Boolean) data.get("isLastPage");
                if (!isLastPage && nextPage != 0) {
                    getWorkOrder(nextPage, result);
                }
                List<HmBookTradeOrder> list = JSONObject.parseArray(objectMapper.writeValueAsString(data.get("list")), HmBookTradeOrder.class);
                if (null == list) {
                    return result;
                }
                result.addAll(list);
                return result;
            } else {
                throw new RuntimeException("获取作业单失败，请检查网络");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private List<HmBookTradeOrder> getWorkOrder() {
        List<HmBookTradeOrder> result = new ArrayList<>();
        List<HmBookTradeOrder> order = getWorkOrder(1, result);
        return order.stream().filter(a -> StringUtils.isNotBlank(a.getPaymentNo())).collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(HmBookTradeOrder::getPaymentNo))), ArrayList::new));
    }

    public Object syncOnePersonOrderStatus(String orderNo) {
        JxWorkerOrder order = jxWorkerOrderMapper.getOne(orderNo);
        JSONObject jsonObject = new JSONObject();
        if (null == order) {
            jsonObject.put("success", -1);
            jsonObject.put("message", "订单不存在");
        } else {
            HmPaymentOrder payOrderByPayNo = getPayOrderByPayNo(order.getHmPayOrderno());
            if (null == payOrderByPayNo) {
                jsonObject.put("success", -1);
                jsonObject.put("message", "订单不存在");
                return jsonObject;
            }
            Integer status = getStatus(payOrderByPayNo.getStatus());
            if (null == status) {
                jsonObject.put("success", -1);
                jsonObject.put("message", "订单状态不正确");
                return jsonObject;
            }
            order.setStatus(status);
            order.setHmStatus(payOrderByPayNo.getStatus());
            jxWorkerOrderMapper.updateByPrimaryKey(order);
            jsonObject.put("errno", 0);
            jsonObject.put("message", "订单状态同步成功");
        }
        return jsonObject;
    }
}
