package com.cftech.waybill.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.addresst.model.Address;
import com.cftech.addresst.service.AddressService;
import com.cftech.base.codingrule.utils.CodingruleUtils;
import com.cftech.core.util.Constants;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.order.model.Order;
import com.cftech.order.service.OrderService;
import com.cftech.orderdetail.model.OrderDetails;
import com.cftech.orderdetail.service.OrderDetailsService;
import com.cftech.sys.model.User;
import com.cftech.sys.security.UserUtils;
import com.cftech.waybill.model.Waybill;
import com.cftech.waybill.dao.WaybillMapper;
import com.cftech.waybill.service.WaybillService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.sql.Conds;
import com.cftech.waybill.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 顺丰物流运单ServiceImpl
 *
 * @author Strive
 * @date: 2020-10-21 15:04
 */
@Slf4j
@Service("waybillService")
public class WaybillServiceImpl extends GenericServiceImpl<Waybill> implements WaybillService {

    @Autowired
    @Qualifier("waybillMapper")
    private WaybillMapper waybillMapper;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderDetailsService orderDetailsService;

    @Autowired
    private AddressService addressService;

    @Autowired
    private CodingruleUtils codingruleUtils;

    @Override
    public GenericDao<Waybill> getGenericMapper() {
        return waybillMapper;
    }


    public Waybill fetchByWayBillId(String id) {
        return waybillMapper.fetchByWayBillId(id);
    }

    @Override
    @Transactional
    public JSONObject orderSendOutForWaybill(HttpServletRequest request, Long orderId, String datas) {
        JSONObject retObj = new JSONObject();
        Long accountsId = UserUtils.getmpaccounts(request);
        User user = UserUtils.getUser();
        try {
            if (orderId == null) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", "Request Params Is Null ! ");
                return retObj;
            }
            //获取订单
            Conds orderConds = new Conds();
            orderConds.equal("o.del_flag", Constants.DEL_FLAG_0);
            orderConds.equal("o.id", orderId);
            List<Order> orders = orderService.fetchSearchByPage(orderConds, null, 0, 0);
            if (orders == null || orders.size() != 1) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 订单不存在 ! ");
                return retObj;
            }
            Order order = orders.get(0);

            Conds detailConds = new Conds();
            detailConds.equal("d.del_flag", Constants.DEL_FLAG_0);
            detailConds.equal("o.id", orderId);
            List<OrderDetails> odets = orderDetailsService.fetchSearchByPage(detailConds, null, 0, 0);
            if (odets == null || odets.size() == 0) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 订单明细不存在 ! ");
                return retObj;
            }

            Address address = addressService.fetchById(order.getAddressId());
            if (address == null) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 收货地址不存在! ");
                return retObj;
            }


            //生成物流数据
            Waybill waybill = new Waybill();
            waybill.setAccountsId(accountsId);
            waybill.setNumber(codingruleUtils.getNumber(accountsId, Waybill.class.getName()));
            waybill.setConsultId(order.getConsultId());
            waybill.setOpenId(order.getOpenid());
            waybill.setStorageManage(String.valueOf(user.getId()));
            waybill.setOrderId(order.getId());
            waybill.setOrderCode(order.getNumber());
            waybill.setContact(address.getAddressName());
            waybill.setMobile(address.getPhone());
            waybill.setProvince(address.getProvinceName());
            waybill.setCity(address.getCityName());
            waybill.setCounty(address.getCountyName());
            waybill.setAddress(address.getAddress());
            waybill.setAddressId(String.valueOf(order.getAddressId()));

            //接口调用数据
            JSONObject msgDataObj = ExpressOrderInfoUtils.generateWaybillOrder(order, odets, waybill);
            Long timestamp = System.currentTimeMillis();//时间戳
            String checkWord = SystemConfig.p.getProperty("sf.checkWord");
            String msgDigest = ExpressOrderInfoUtils.generateSfDigest(msgDataObj.toString(), timestamp, checkWord);
            System.out.println(msgDataObj.toString());
            List<BasicNameValuePair> content = new ArrayList<>();
            content.add(new BasicNameValuePair("partnerID", SystemConfig.p.getProperty("sf.partnerID")));//合作伙伴编码、顾客编码
            content.add(new BasicNameValuePair("requestID", FqHttpUtils.generateUUID()));
            content.add(new BasicNameValuePair("serviceCode", FqConstants.SF_ORDER_SEND_CODE));//接口服务代码
            content.add(new BasicNameValuePair("timestamp", String.valueOf(timestamp)));
            content.add(new BasicNameValuePair("msgDigest", msgDigest));
            content.add(new BasicNameValuePair("msgData", msgDataObj.toString()));

            CloseableHttpEntity closeableHttpEntity = FqHttpUtils.sendHttpPost(FqConstants.SF_ORDER_SEND_URL, content);
            if (closeableHttpEntity != null && closeableHttpEntity.getCode() == 200) {
                waybill.setDescription(msgDataObj.toString());

                if (closeableHttpEntity.getRetObj().containsKey("apiResultCode") &&
                        StringUtils.equals(closeableHttpEntity.getRetObj().getString("apiResultCode"), "A1000")) {
                    JSONObject apiResultData = closeableHttpEntity.getRetObj().getJSONObject("apiResultData");
                    if (apiResultData.getBoolean("success")) {
                        JSONObject msgData = apiResultData.getJSONObject("msgData");
                        String originCode = msgData.getString("originCode");//原寄地区域代码，可用于顺丰电子运单标签打印
                        String destCode = msgData.getString("destCode");//目的地区域代码，可用于顺丰电子运单标签打
                        String filterResult = msgData.getString("filterResult");//筛单结果
                        waybill.setOriginCode(originCode);
                        waybill.setDestCode(destCode);
                        waybill.setFilterResult(filterResult);

                        JSONArray waybillNoInfoList = msgData.getJSONArray("waybillNoInfoList");//顺丰运单号
                        for (int i=0; i<waybillNoInfoList.size(); i++) {
                            JSONObject obj = waybillNoInfoList.getJSONObject(i);
                            if (obj.getInteger("waybillType") == 1) {
                                waybill.setWaybillNo(obj.getString("waybillNo"));//顺丰运单号
                                order.setCourierNumber(obj.getString("waybillNo"));
                                order.setStatus("3");
                            }
                        }

                        JSONArray routeLabelInfo = msgData.getJSONArray("routeLabelInfo");//路由标签数据详细数据
                        for (int i=0; i<routeLabelInfo.size(); i++) {
                            JSONObject obj = routeLabelInfo.getJSONObject(i);
                            if (StringUtils.equals(obj.getString("code"),"1000")) {
                                waybill.setRouteDes(obj.getString("routeLabelData"));
                            }
                        }

                        waybill.setWaybillRemark(msgData.getString("remark"));//不可派发原因

                        //更新出库批次号
                        if (StringUtils.isNoneBlank(datas) && JSONObject.parseArray(datas).size() > 0) {
                            JSONArray arr = JSONObject.parseArray(datas);

                            Conds orderDesConds = new Conds();
                            orderDesConds.equal("d.del_flag", Constants.DEL_FLAG_0);
                            orderDesConds.equal("d.order_id", orderId);
                            List<OrderDetails> orderDetailsList = orderDetailsService.fetchSearchByPage(orderDesConds, null, 0, 0);
                            for (OrderDetails orderDetails : orderDetailsList) {
                                for (int i=0; i< arr.size(); i++) {
                                    JSONObject obj = arr.getJSONObject(i);
                                    if (StringUtils.equals(orderDetails.getDrugsCode(), obj.getString("productCode"))) {
                                        orderDetails.setDrugsName(obj.getString("productName"));
                                        orderDetails.setDrugsMateriel(obj.getString("batchNo"));
                                        orderDetailsService.update(orderDetails);
                                        continue;
                                    }
                                }
                            }
                        }

                        waybillMapper.save(waybill);
                        orderService.update(order);

                        retObj.put("errorNo", 0);
                        retObj.put("errorMsg", "下单接口调用成功");
                        return retObj;
                    }
                }
            } else {
                log.info("调用丰桥接口：订单编码 {} 错误！" + orderId);
                retObj.put("errorNo", 1);
            }
        } catch (Exception e) {
            retObj.put("errorNo", 1);
            e.printStackTrace();
        } finally {
            log.info("调用丰桥接口：订单编码 {}" + orderId );
        }

        return retObj;
    }

    @Override
    @Transactional
    public JSONObject orderPrinterBill(HttpServletRequest request, Long orderId) {
        JSONObject retObj = new JSONObject();
        Long accountsId = UserUtils.getmpaccounts(request);
        try {
            if (orderId == null) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", "Request Params Is Null ! ");
                return retObj;
            }
            //获取订单
            Conds orderConds = new Conds();
            orderConds.equal("o.del_flag", Constants.DEL_FLAG_0);
            orderConds.equal("o.id", orderId);
            List<Order> orders = orderService.fetchSearchByPage(orderConds, null, 0, 0);
            if (orders == null || orders.size() != 1) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 订单不存在 ! ");
                return retObj;
            }
            Order order = orders.get(0);

            Conds detailConds = new Conds();
            detailConds.equal("d.del_flag", Constants.DEL_FLAG_0);
            detailConds.equal("o.id", orderId);
            List<OrderDetails> odets = orderDetailsService.fetchSearchByPage(detailConds, null, 0, 0);
            if (odets == null || odets.size() == 0) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 订单明细不存在 ! ");
                return retObj;
            }

            //生成物流数据
            Conds billConds = new Conds();
            billConds.equal("t.del_flag", Constants.DEL_FLAG_0);
            billConds.equal("t.order_id", order.getId());
            Map<String, Object> params = new HashMap<>();
            params.put("conds", billConds);
            List<Waybill> waybillList = waybillMapper.fetchSearchByPage(params);
            if (waybillList == null || waybillList.size() <=0) {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", " 物流数据不存在 ! ");
                return retObj;
            }
            Waybill waybill = waybillList.get(0);

            //调用接口
            JSONObject result = ExpressOrderInfoUtils.generateBillPrinterObj(order, odets, waybill);
            JSONArray arr = new JSONArray();
            arr.add(result);
            boolean bool = BillPrinterUtils.executePrinter(arr.toString());
            if (bool) {
                waybill.setStatus("1");
                waybillMapper.update(waybill);
                retObj.put("errorNo", 0);
                retObj.put("errorMsg", "调用打印服务成功!");
            } else {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", "调用打印服务失败!");
            }
        } catch (Exception e) {
            e.getMessage();
            log.error("调用顺丰打印sdk服务失败 errorMsg = " + e.getMessage());
            retObj.put("errorNo", 1);
            retObj.put("errorMsg", "调用打印服务失败!" + e.getMessage());
        }
        return retObj;
    }


}