package com.yami.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.app.param.QnhPushParam;
import com.yami.shop.bean.enums.AuditStatus;
import com.yami.shop.bean.model.*;

import java.util.Date;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yami.shop.bean.param.ItemQueryDto;
import com.yami.shop.bean.param.OrderDto;
import com.yami.shop.bean.param.StoreDto;
import com.yami.shop.bean.vo.GoodsItemPageVo;
import com.yami.shop.bean.vo.GoodsItemVo;
import com.yami.shop.bean.vo.StoreDetailVo;
import com.yami.shop.bean.vo.StoreListVo;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.dao.ShopDetailMapper;
import com.yami.shop.dao.ShopSkuMapper;
import com.yami.shop.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author wy
 */
@Service
@Slf4j
public class QnhServiceImpl implements IQnhService {
    //测试
//    private static final String APP_ID = "101151";

//    private static final String SECRET = "19ba6d8bc121b0857c77a5d91c26797f";

    //正式
    private static final String APP_ID = "100265";

    private static final String SECRET = "cbd4f52c6e3ca4537686af42189af328";

    private static final String GET_STORES = "https://lingshouopen.waimai.meituan.com/api/v1/qnh-api-boot/store/getStores";

    private static final String ITEM_QUERY = "https://lingshouopen.waimai.meituan.com/api/v1/freego/warehouse/getItemList";

    private static final String QUERY_STORE = "https://lingshouopen.waimai.meituan.com/api/v1/qnh-api-boot/store/queryStore";

    private static final String ADD_ORDER = "https://lingshouopen.waimai.meituan.com/api/v1/order-v2/addorder";

    private static final String GET_SKU_STOCK = "https://lingshouopen.waimai.meituan.com/api/v1/freego/warehouse/getSkuStock";

    @Resource
    private IRequestLogService requestLogService;

    @Resource
    private ShopDetailService shopDetailService;

    @Resource
    private ProductService productService;

    @Resource
    private SkuService skuService;

    @Resource
    private CategoryService categoryService;

    @Resource
    private ShopWalletService shopWalletService;

    @Resource
    private ShopAuditingService shopAuditingService;
    @Resource
    private ShopDetailMapper shopDetailMapper;

    @Resource
    private ShopSkuMapper shopSkuMapper;

    @Override
    public List<StoreListVo> getStores(StoreDto dto) {
        Map<String, Object> body = bulidMap();
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isNotEmpty(dto.getOrgCode())) {
            jsonObject.put("org_code", dto.getOrgCode());
        }
        if (StringUtils.isNotEmpty(dto.getOrgName())) {
            jsonObject.put("org_name", dto.getOrgName());
        }
        body.put("data", jsonObject);
        body.put("sign", generateSignature(body));
        Map<String, List<String>> header = new HashMap<>();
        header.put("appid", Collections.singletonList(APP_ID));
        HttpResponse execute = HttpRequest.post(GET_STORES).header(header).body(JSON.toJSONString(body)).execute();
        JSONObject result = JSONObject.parseObject(execute.body());
        requestLogService.addLog(RequestLog.builder()
                .resource("qnh")
                .requestMethod("getStores")
                .requestParam(JSON.toJSONString(body))
                .result(result.toJSONString())
                .createTime(LocalDateTime.now()).build());
        if (result.getBoolean("result")) {
            JSONArray resultList = result.getJSONArray("resultList");
            List<StoreListVo> storeListVos = JSONObject.parseArray(JSONArray.toJSONString(resultList), StoreListVo.class);
            return storeListVos;
        } else {
            throw new GlobalException(result.getString("msg"));
        }
    }

    @Override
    public StoreDetailVo queryStore(String regionCode, Integer pageNo, Integer pageSize) {
        Map<String, Object> body = bulidMap();
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isNotEmpty(regionCode)) {
            jsonObject.put("region_code", regionCode);
        }
        if (Objects.nonNull(pageNo)) {
            jsonObject.put("page_no", pageNo);
        }
        if (Objects.nonNull(pageSize)) {
            jsonObject.put("page_size", pageSize);
        }
        HttpResponse execute = getExecute(body, jsonObject, QUERY_STORE);
        JSONObject result = JSONObject.parseObject(execute.body());
        requestLogService.addLog(RequestLog.builder()
                .resource("qnh")
                .requestMethod("queryStore")
                .requestParam(JSON.toJSONString(body))
                .result(result.toJSONString())
                .createTime(LocalDateTime.now()).build());
        if (result.getBoolean("result")) {
            JSONArray resultList = result.getJSONArray("resultList");
            List<StoreDetailVo> storeDetailVos = JSONObject.parseArray(JSONArray.toJSONString(resultList), StoreDetailVo.class);
            StoreDetailVo storeDetailVo = storeDetailVos.get(0);
            return storeDetailVo;
        } else {
            throw new GlobalException(result.getString("msg"));
        }
    }

//    @Override
//    public boolean getSkuStock(String skuCode, Long prodId) {
//        Sku one1 = skuService.getOne(Wrappers.<Sku>lambdaQuery().eq(Sku::getSkuCode, skuCode).eq(Sku::getProdId, prodId));
//        Map<String, Object> body = bulidMap();
//        if (null == one1) throw new GlobalException("请重新选择规格，该规格不存在！");
//        Product byId = productService.getById(prodId, 1);
//        ShopDetail shopDetail = shopDetailMapper.selectById(byId.getShopId());
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("page_no", 1);
//        if (ObjectUtils.isNotEmpty(shopDetail)) {
//            jsonObject.put("poi_code", shopDetail.getThirdPartyCode());
//        }
//        jsonObject.put("sku_code", skuCode);
//        jsonObject.put("page_size", 50);
//        HttpResponse execute = getExecute(body, jsonObject, GET_SKU_STOCK);
//        JSONObject result = JSONObject.parseObject(execute.body());
//        requestLogService.addLog(RequestLog.builder()
//                .resource("qnh")
//                .requestMethod("getSkuStock")
//                .requestParam(JSON.toJSONString(body))
//                .result(result.toJSONString())
//                .createTime(LocalDateTime.now()).build());
//        if (result.get("data") != null) {
//            JSONArray resultList = result.getJSONArray("data");
//            resultList.forEach(rowData -> {
//                JSONObject jsonObject1 = JSONObject.parseObject(rowData.toString());
//                one1.setStocks(jsonObject1.getBigDecimal("available_stock").intValue());
//                one1.setActualStocks(jsonObject1.getBigDecimal("available_stock").intValue());
//                skuService.updateById(one1);
//            });
//            return true;
//        } else {
//            throw new GlobalException(result.getString("msg"));
//        }
//    }

//    @Override
//    public boolean getSkuStock(String skuCode, Long prodId, Integer platform) {
//        Sku one1 = skuService.getOne(Wrappers.<Sku>lambdaQuery()
//                .eq(Sku::getSkuCode, skuCode)
//                .eq(Sku::getProdId, prodId));
//        if (null == one1) throw new GlobalException("请重新选择规格，该规格不存在！");
//        Product byId = productService.getById(prodId, platform);
//        ShopDetail shopDetail = shopDetailMapper.selectById(byId.getShopId());
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("page_no", 1);
//        if (ObjectUtils.isNotEmpty(shopDetail)) {
//            jsonObject.put("poi_code", shopDetail.getThirdPartyCode());
//        }
//        ShopSku shopSku = shopSkuMapper.selectByShopAndSku(one1.getSkuId(), byId.getShopId());
//        jsonObject.put("sku_code", skuCode);
//        jsonObject.put("page_size", 50);
//        one1.setStocks(shopSku.getShopSkuStocks());
//        one1.setActualStocks(shopSku.getShopSkuStocks());
//        return Boolean.TRUE;
//        HttpResponse execute = getExecute(body, jsonObject, GET_SKU_STOCK);
//        JSONObject result = JSONObject.parseObject(execute.body());
//        requestLogService.addLog(RequestLog.builder()
//                .resource("qnh")
//                .requestMethod("getSkuStock")
//                .requestParam(JSON.toJSONString(body))
//                .result(result.toJSONString())
//                .createTime(LocalDateTime.now()).build());
//        if (result.get("data") != null) {
//            JSONArray resultList = result.getJSONArray("data");
//            resultList.forEach(rowData -> {
//                JSONObject jsonObject1 = JSONObject.parseObject(rowData.toString());
//                one1.setStocks(jsonObject1.getBigDecimal("available_stock").intValue());
//                one1.setActualStocks(jsonObject1.getBigDecimal("available_stock").intValue());
//                skuService.updateById(one1);
//            });
//            return true;
//        } else {
//            throw new GlobalException(result.getString("msg"));
//        }
//    }

    private HttpResponse getExecute(Map<String, Object> body, JSONObject jsonObject, String url) {
        body.put("data", jsonObject);
        body.put("sign", generateSignature(body));
        Map<String, List<String>> header = new HashMap<>();
        header.put("appid", Collections.singletonList(APP_ID));
        return HttpRequest.post(url).header(header).body(JSON.toJSONString(body)).execute();
    }

    @Override
    public GoodsItemPageVo itemQuery(ItemQueryDto dto) {
        Map<String, Object> body = bulidMap();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("page_no", dto.getPageNo());
        jsonObject.put("page_size", dto.getPageSize());
        jsonObject.put("poi_ids", dto.getOrgCode());
        if (StringUtils.isNotEmpty(dto.getName())) {
            jsonObject.put("name", dto.getName());
        }
        if (StringUtils.isNotEmpty(dto.getSkuCode())) {
            jsonObject.put("sku_code", dto.getSkuCode());
        }
        if (StringUtils.isNotEmpty(dto.getSpuIds())) {
            jsonObject.put("spu_code", dto.getSpuIds());
        }
        if (Objects.nonNull(dto.getQueryStatus()) && StringUtils.isNotEmpty(dto.getChannelIds())) {
            jsonObject.put("query_status", dto.getQueryStatus());
            jsonObject.put("channel_ids", dto.getChannelIds());
        }
        HttpResponse execute = getExecute(body, jsonObject, ITEM_QUERY);
//        HttpResponse execute = getExecute(body, jsonObject, PROD_QUERY);
        JSONObject result = JSONObject.parseObject(execute.body());
//        requestLogService.addLog(RequestLog.builder()
//                .resource("qnh")
//                .requestMethod("itemQuery")
//                .requestParam(JSON.toJSONString(body))
//                .result(result.toJSONString())
//                .createTime(LocalDateTime.now()).build());
        if ("0".equals(result.getString("code"))) {
            JSONArray resultList = result.getJSONArray("data");
            Integer totalCount = result.getInteger("total_count");
            Integer totalPage = result.getInteger("total_page");
            GoodsItemPageVo goodsItemPageVo = new GoodsItemPageVo();
            goodsItemPageVo.setTotalCount(totalCount);
            goodsItemPageVo.setTotalPage(totalPage);
            List<GoodsItemVo> goodsItemVos = JSONObject.parseArray(JSONArray.toJSONString(resultList), GoodsItemVo.class);
            goodsItemPageVo.setData(goodsItemVos);
            return goodsItemPageVo;
        } else {
            throw new GlobalException(result.getString("msg"));
        }
    }

    @Override
    public String addOrder(OrderDto dto) {
        Map<String, Object> body = bulidMap();
        JSONObject jsonObject = bulidOrderParam(dto);
        HttpResponse execute = getExecute(body, jsonObject, ADD_ORDER);
        JSONObject result = JSONObject.parseObject(execute.body());
        requestLogService.addLog(RequestLog.builder()
                .resource("qnh")
                .requestMethod("addOrder")
                .requestParam(JSON.toJSONString(body))
                .result(result.toJSONString())
                .createTime(LocalDateTime.now()).build());
        if ("0".equals(result.getString("code"))) {
            String orderId = result.getJSONObject("data").getString("qnh_order_id");
            return orderId;
        } else {
            throw new GlobalException(result.getString("msg"));
        }
    }

    @Override
    public void syncShop(List<StoreListVo> storeListVos) {
        List<StoreListVo> storeListVoList = null;
        if (CollectionUtil.isNotEmpty(storeListVos)) {
            storeListVoList = storeListVos;
        } else {
            storeListVoList = getStores(new StoreDto());
        }
        Date date = new Date();
        List<ShopDetail> shopDetails = new ArrayList<>();
        List<ShopWallet> shopWallets = new ArrayList<>();
        List<ShopAuditing> shopAuditings = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(storeListVoList)) {
            for (StoreListVo item : storeListVoList) {
                StoreDetailVo storeDetailVo = queryStore(item.getCode(), 1, 20);
                if (Objects.nonNull(storeDetailVo)) {
                    ShopDetail shopDetail = new ShopDetail();
                    shopDetail.setThirdPartyCode(storeDetailVo.getRegionCode());
                    shopDetail.setShopName(storeDetailVo.getRegionName());
                    shopDetail.setShopLat(storeDetailVo.getLatitude());
                    shopDetail.setShopLng(storeDetailVo.getLongitude());
                    shopDetail.setShopAddress(storeDetailVo.getAddress());
                    shopDetail.setProvince(storeDetailVo.getDistrict().getProvinceName());
                    shopDetail.setCity(storeDetailVo.getCity());
                    shopDetail.setArea(storeDetailVo.getDistrict().getAreaName());
                    shopDetail.setShopStatus(-1);
                    shopDetail.setCreateTime(date);
                    shopDetail.setUpdateTime(date);
                    shopDetails.add(shopDetail);
                }
            }
            shopDetailService.saveBatch(shopDetails);
            for (ShopDetail shopDetail : shopDetails) {
                ShopWallet shopWallet = new ShopWallet();
                shopWallet.setShopId(shopDetail.getShopId());
                shopWallet.setUnsettledAmount(0.0);
                shopWallet.setSettledAmount(0.0);
                shopWallet.setFreezeAmount(0.0);
                shopWallet.setTotalSettledAmount(0.0);
                shopWallet.setVersion(0L);
                shopWallet.setUpdateTime(new Date());
                shopWallets.add(shopWallet);

                ShopAuditing auditing = new ShopAuditing();
                auditing.setShopId(shopDetail.getShopId());
                auditing.setCreateTime(new Date());
                auditing.setStatus(AuditStatus.WAITAUDIT.value());
                auditing.setUpdateTime(new Date());
                shopAuditings.add(auditing);
            }
            shopWalletService.saveBatch(shopWallets);
            shopAuditingService.saveBatch(shopAuditings);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncGoods(List<GoodsItemVo> goodsItemVos) {
        int currentPage = 1;
        List<StoreListVo> storeListVoList = getStores(new StoreDto());
        if (CollectionUtil.isNotEmpty(storeListVoList)) {
            List<Long> poiIds = storeListVoList.stream().map(StoreListVo::getPoiId).collect(Collectors.toList());
            ItemQueryDto itemQueryDto = new ItemQueryDto();
            itemQueryDto.setOrgCode("1066181");
            itemQueryDto.setPageSize(100);
            List<GoodsItemVo> all = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(goodsItemVos)) {
                all = goodsItemVos;
            } else {
                while (true) {
                    itemQueryDto.setPageNo(currentPage);
                    GoodsItemPageVo page = itemQuery(itemQueryDto);
                    if (CollectionUtil.isNotEmpty(page.getData())) {
                        itemQueryDto.setPageNo(currentPage++);
                        List<GoodsItemVo> data = page.getData();
                        List<Sku> skuList = new ArrayList<>();
//            ArrayList<Category> categoryInfos = new ArrayList<>();
                        for (GoodsItemVo item : data) {
                            Product product = new Product();
                            ShopDetail shopDetail = shopDetailService.getOne(new LambdaQueryWrapper<ShopDetail>()
                                    .eq(ShopDetail::getThirdPartyCode, item.getPoiCode()));
                            product.setShopId(shopDetail.getShopId());
                            product.setProdName(item.getName());
                            List<GoodsItemVo.ChannelItemInfoList> channelItemInfoLists = item.getSkuList().get(0).getChannelItemInfoList();
                            GoodsItemVo.ChannelItemInfoList channelItemInfoList = new GoodsItemVo.ChannelItemInfoList();
                            if (channelItemInfoLists.size() == 1) {
                                channelItemInfoList = channelItemInfoLists.get(0);
                            } else {
                                for (GoodsItemVo.ChannelItemInfoList var : channelItemInfoLists) {
                                    if (100 == var.getChannelId()) {
                                        channelItemInfoList = var;
                                    } else {
                                        channelItemInfoList = channelItemInfoLists.get(0);
                                    }
                                }
                            }
                            double price = 0.01;
                            Integer quantity = 0;
                            if (Objects.nonNull(channelItemInfoList.getChannelPrice())) {
                                price = Double.parseDouble(channelItemInfoList.getChannelPrice()) / 100;
                                product.setOriPrice(price);
                                product.setPrice(price);
                                quantity = channelItemInfoList.getChannelQuantity().intValue();
                                product.setTotalStocks(quantity);
                                product.setStatus(1);
                            } else {
                                product.setOriPrice(0.1);
                                product.setPrice(0.01);
                                product.setStatus(0);
                            }
                            product.setBrief(item.getDescription());
                            product.setVideo(item.getVideoInfo());
                            product.setPic(item.getImages());
                            product.setImgs(item.getImages());
                            product.setCreateTime(new Date());
                            product.setUpdateTime(new Date());
                            product.setContent("");
                            product.setShopName(item.getPoiName());

//                            String exist = item.getCategory();
//                            if (StringUtils.isNotEmpty(exist)) {
//                                List<Category> list = categoryService.list(new LambdaQueryWrapper<Category>()
//                                        .eq(Category::getShopId, shopDetail.getShopId())
//                                        .eq(Category::getResource, exist));
//                                if (CollectionUtil.isEmpty(list)) {
//                                    List<Category> categories = new ArrayList<>();
//                                    String[] split = exist.split(">");
//                                    Date date = new Date();
//                                    for (String value : split) {
//                                        Category one = categoryService.getOne(new LambdaQueryWrapper<Category>()
//                                                .eq(Category::getShopId, shopDetail.getShopId())
//                                                .eq(Category::getCategoryName, value));
//                                        if (Objects.nonNull(one)) {
//                                            break;
//                                        }
//                                        Category category = new Category();
//                                        category.setShopId(shopDetail.getShopId());
//                                        category.setCategoryName(value);
//                                        category.setRecTime(date);
//                                        category.setUpdateTime(date);
//                                        category.setSeq(1);
//                                        category.setGrade(0);
//                                        categories.add(category);
//                                    }
//                                    if (CollectionUtil.isNotEmpty(categories)) {
//                                        categoryService.saveBatch(categories);
//                                        Long parentId = 0L;
//                                        for (Category category : categories) {
//                                            Long categoryId = category.getCategoryId();
//                                            category.setParentId(parentId);
//                                            parentId = categoryId;
//                                        }
//                                        categoryService.updateBatchById(categories);
//                                        product.setShopCategoryId(categories.get(categories.size() - 1).getCategoryId());
//                                    }
//                                } else {
//                                    product.setShopCategoryId(list.get(list.size() - 1).getCategoryId());
//                                }
//                            }
                            List<GoodsItemVo.CategoryInfo> categoryInfos = item.getCategoryInfo();
                            if (CollectionUtil.isNotEmpty(categoryInfos)) {
                                List<Category> categories = new ArrayList<>();
                                Date date = new Date();
                                for (GoodsItemVo.CategoryInfo obj : categoryInfos) {
                                    Category one = categoryService.getOne(new LambdaQueryWrapper<Category>()
                                            .eq(Category::getShopId, shopDetail.getShopId())
                                            .eq(Category::getCategoryName, obj.getName()));
                                    if (Objects.nonNull(one)) {
                                        product.setShopCategoryId(one.getCategoryId());
                                        break;
                                    }
                                    Category category = new Category();
                                    category.setShopId(shopDetail.getShopId());
                                    category.setCategoryName(obj.getName());
                                    category.setRecTime(date);
                                    category.setUpdateTime(date);
                                    category.setSeq(1);
                                    category.setGrade(0);
                                    categories.add(category);
                                }
                                if (CollectionUtil.isNotEmpty(categories)) {
                                    categoryService.saveBatch(categories);
                                    Long parentId = 0L;
                                    for (Category category : categories) {
                                        Long categoryId = category.getCategoryId();
                                        category.setParentId(parentId);
                                        parentId = categoryId;
                                    }
                                    categoryService.updateBatchById(categories);
                                    product.setShopCategoryId(categories.get(categories.size() - 1).getCategoryId());
                                }
                            }

//                products.add(product);
                            productService.save(product);
                            List<GoodsItemVo.SukList> skus = item.getSkuList();
                            for (GoodsItemVo.SukList skuItem : skus) {
                                Sku sku = new Sku();
                                sku.setProdId(product.getProdId());
                                sku.setSkuName(skuItem.getSpec());
                                sku.setOriPrice(price);
                                sku.setPrice(price);
                                sku.setStocks(quantity);
                                sku.setUpdateTime(new Date());
                                sku.setRecTime(new Date());
                                sku.setProdName(product.getProdName());
                                sku.setWeight(Double.parseDouble(skuItem.getWeightForUnit()));
                                sku.setVolume(0.0D);
                                sku.setStatus(1);
                                sku.setPartyCode(skuItem.getSkuId());
                                sku.setModelId(item.getSpuCode());
                                sku.setIsDelete(0);
                                sku.setWeightUnit(skuItem.getWeightUnit());
                                sku.setActualStocks(quantity);
                                skuList.add(sku);
                            }
//                List<GoodsItemVo.CategoryInfo> categoryInfo = item.getCategoryInfo();
//                if (CollectionUtil.isNotEmpty(categoryInfo)) {
//                    for (GoodsItemVo.CategoryInfo categoryItem : categoryInfo) {
//                        Category category = new Category();
//                        category.setShopId(shopDetail.getShopId());
//                        category.setCategoryName(categoryItem.getName());
//                        category.setRecTime(new Date());
//                        category.setUpdateTime(new Date());
//                        category.setSeq(1);
//                        category.setGrade(0);
//                        categoryInfos.add(category);
//                    }
//                }
                        }
                        skuService.saveBatch(skuList);
//            categoryService.saveBatch(categoryInfos);

                    } else {
                        break;
                    }
                }
            }
//            List<Product> products = new ArrayList<>(all.size());
        }
    }

    @Override
    public Map<String, String> getDetailShop(String name) {
        List<ShopDetail> list = shopDetailService.list(new LambdaQueryWrapper<ShopDetail>()
                .like(StringUtils.isNotEmpty(name), ShopDetail::getShopName, name)
                .isNotNull(ShopDetail::getThirdPartyCode));
        return list.stream().collect(Collectors.toMap(ShopDetail::getThirdPartyCode, ShopDetail::getShopName));
    }

    private JSONObject bulidOrderParam(OrderDto orderDto) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("channel_sheetno", orderDto.getChannelSheetno());
        jsonObject.put("channel_keyword", orderDto.getChannelKeyword());
        jsonObject.put("pay_over", orderDto.getPayOver());
        jsonObject.put("billtype", orderDto.getBilltype());
        if (StringUtils.isNotEmpty(orderDto.getReturnOrderSn())) {
            jsonObject.put("return_order_sn", orderDto.getReturnOrderSn());
        }
        jsonObject.put("total_sale_value", orderDto.getTotalSaleValue());
        jsonObject.put("total_disc_value", orderDto.getTotalDiscValue());
        jsonObject.put("total_sj_disc", orderDto.getTotalSjDisc());
        jsonObject.put("total_pt_disc", orderDto.getTotalPtDisc());
        jsonObject.put("total_sj_dp", orderDto.getTotalSjDp());
        jsonObject.put("total_pt_dp", orderDto.getTotalPtDp());
        jsonObject.put("commission_value", orderDto.getCommissionValue());
        jsonObject.put("payable_value", orderDto.getPayableValue());
        jsonObject.put("total_item_value", orderDto.getTotalItemValue());
        jsonObject.put("payable_logistics_value", orderDto.getPayableLogisticsValue());
        jsonObject.put("logistics_mode_keyword", orderDto.getLogisticsModeKeyword());
        jsonObject.put("weight", orderDto.getWeight());
        jsonObject.put("lunchbox_fee", orderDto.getLunchboxFee());
        jsonObject.put("org_code", orderDto.getOrgCode());
        jsonObject.put("org_name", orderDto.getOrgName());
        jsonObject.put("order_time", orderDto.getOrderTime());
        jsonObject.put("group_id", orderDto.getGroupId());

        JSONObject receiverJson = new JSONObject();
        receiverJson.put("name", orderDto.getReceiver().getName());
        receiverJson.put("mobile", orderDto.getReceiver().getMobile());
        receiverJson.put("address", orderDto.getReceiver().getAddress());
        receiverJson.put("longitude", orderDto.getReceiver().getLongitude());
        receiverJson.put("latitude", orderDto.getReceiver().getLatitude());
        jsonObject.put("receiver", receiverJson);

        JSONArray orderDetailJsons = new JSONArray();
        List<OrderDto.OrderDetails> orderDetails = orderDto.getOrderDetails();
        for (OrderDto.OrderDetails item : orderDetails) {
            JSONObject orderDetail = new JSONObject();
            orderDetail.put("sku_id", item.getSkuId());
            orderDetail.put("order_item_id", item.getOrderItemId());
            orderDetail.put("name", item.getName());
            orderDetail.put("original_price", item.getOriginalPrice());
            orderDetail.put("weight", item.getWeight());
            orderDetail.put("sale_price", item.getSalePrice());
            orderDetail.put("qty", item.getQty());
            orderDetail.put("money", item.getMoney());
            orderDetailJsons.add(orderDetail);
        }
        jsonObject.put("order_details", orderDetailJsons);

        JSONObject pay = new JSONObject();
        pay.put("keyword", orderDto.getOrderPayments().getKeyword());
        pay.put("name", orderDto.getOrderPayments().getName());
        pay.put("payment", orderDto.getOrderPayments().getPayment());
        jsonObject.put("order_payments", pay);

        return jsonObject;
    }

    public Map<String, Object> bulidMap() {
        Map<String, Object> body = new HashMap<>();
        body.put("appid", APP_ID);
        body.put("timestamp", (System.currentTimeMillis() / 1000));
        body.put("qid", UUID.randomUUID().toString());
        body.put("version", "2.3");
        return body;
    }

    public static String generateSignature(Map<String, Object> data) {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String item : keyArray) {
            if (Objects.isNull(data.get(item))) {
                continue;
            }
            if (!data.get(item).toString().trim().isEmpty()) {
                sb.append(item).append("=").append(data.get(item).toString().trim()).append("&");
            }
        }
        sb.append(SECRET);
        return DigestUtils.md5Hex(sb.toString()).toUpperCase();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String dataUpdate(QnhPushParam qnhPushParam) {
//        String key = "qnh:dataUpdate:" + qnhPushParam.getSign();
//        if (!RedisUtil.hasKey(key)) {
//            RedisUtil.set(key, qnhPushParam.getSign(), 120);
//            RequestLog one = requestLogService.getOne(new LambdaQueryWrapper<RequestLog>()
//                    .eq(RequestLog::getSign, qnhPushParam.getSign()));
//            if (Objects.nonNull(one)) {
//                return ResponseEntity.ok().build();
//            }
//            List<QnhPushParam.Data> data = qnhPushParam.getData();
//            for (QnhPushParam.Data item : data) {
//                String opType = item.getOp_type();
//                ItemQueryDto query = new ItemQueryDto();
//                query.setOrgCode(item.getOrg_code());
//                query.setSpuIds(item.getSpu_id());
//                query.setPageSize(1);
//                query.setPageNo(1);
//                if ("1".equals(opType)) {
//                    StoreListVo storeListVo = new StoreListVo();
//                    storeListVo.setCode(item.getOrg_code());
//                    syncShop(Collections.singletonList(storeListVo));
//
//                    ResponseEntity<GoodsItemPageVo> resData = itemQuery(query);
//                    syncGoods(resData.getBody().getData());
//                }
//                if ("2".equals(opType)) {
//                    ShopDetail shopDetail = shopDetailService.getOne(new LambdaQueryWrapper<ShopDetail>()
//                            .eq(ShopDetail::getThirdPartyCode, item.getOrg_code()));
//                    if (Objects.isNull(shopDetail)) {
//                        StoreListVo storeListVo = new StoreListVo();
//                        storeListVo.setCode(item.getOrg_code());
//                        syncShop(Collections.singletonList(storeListVo));
//                    }
//
//                    ResponseEntity<GoodsItemPageVo> resData = itemQuery(query);
//                    List<Sku> exists = skuService.list(new LambdaQueryWrapper<Sku>()
//                            .eq(Sku::getModelId, item.getSpu_id()));
//                    if (CollectionUtil.isNotEmpty(exists)) {
//                        productService.removeProductByProdId(exists.get(0).getProdId());
//                    }
//                    syncGoods(resData.getBody().getData());
//                }
//                if ("3".equals(opType)) {
//                    Sku exist = skuService.getOne(new LambdaQueryWrapper<Sku>()
//                            .eq(Sku::getModelId, item.getSpu_id()));
//                    if (Objects.nonNull(exist)) {
//                        productService.removeProductByProdId(exist.getProdId());
//                    }
//                }
//            }
//            requestLogService.addLog(RequestLog.builder()
//                    .resource("qnh")
//                    .requestMethod("dataUpdate")
//                    .result(JSON.toJSONString(qnhPushParam))
//                    .sign(qnhPushParam.getSign())
//                    .createTime(LocalDateTime.now()).build());
//            return ResponseEntity.ok().build();
//        }
        return null;
    }


    public static void main(String[] args) {
        QnhServiceImpl qnhService = new QnhServiceImpl();
    }

    /**
     * 从牵牛花同步商家信息-》商品信息-》sku信息
     */
    public void synchronizedInfo() {
        StoreDto dto = new StoreDto();
        Map<String, Object> body = bulidMap();
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isNotEmpty(dto.getOrgCode())) {
            jsonObject.put("org_code", dto.getOrgCode());
        }
        if (StringUtils.isNotEmpty(dto.getOrgName())) {
            jsonObject.put("org_name", dto.getOrgName());
        }
        body.put("data", jsonObject);
        body.put("sign", generateSignature(body));
        Map<String, List<String>> header = new HashMap<>();
        header.put("appid", Collections.singletonList(APP_ID));
        HttpResponse execute = HttpRequest.post(GET_STORES).header(header).body(JSON.toJSONString(body)).execute();
        JSONObject result = JSONObject.parseObject(execute.body());
        System.out.println("获取到商户的信息：" + result);
        if (result.getBoolean("result")) {
            JSONArray resultList = result.getJSONArray("resultList");
            List<StoreListVo> storeListVos = JSONObject.parseArray(JSONArray.toJSONString(resultList), StoreListVo.class);
            storeListVos.forEach(storeListVo -> {
                ShopDetail shopDetail = shopDetailMapper.selectOne(Wrappers.<ShopDetail>lambdaQuery().eq(ShopDetail::getThirdPartyCode, storeListVo.getCode()));
                if (shopDetail == null) {
                    ShopDetail detail = new ShopDetail();
                    detail.setShopName(storeListVo.getName());
                    detail.setThirdPartyCode(storeListVo.getCode());
                    detail.setSync(true);
                    detail.setShopAddress(storeListVo.getAddress());
                    detail.setCreateTime(new Date());
                    detail.setUpdateTime(new Date());
                    detail.setShopStatus(1);
                    detail.setCity(storeListVo.getCity());
                    detail.setShopAddress(storeListVo.getAddress())
                            .setCity(storeListVo.getCity())
                            .setShopName(storeListVo.getName());
                    shopDetailMapper.insert(detail);
                } else {
                    shopDetail.setShopAddress(storeListVo.getAddress())
                            .setCity(storeListVo.getCity())
                            .setShopName(storeListVo.getName());
                    shopDetailMapper.updateById(shopDetail);
                }
                synchronizedInfo1(storeListVo.getCode());
            });
        } else {
            throw new GlobalException(result.getString("msg"));
        }
    }

    @Override
    public void noticeProductInfo(Object object) {
        requestLogService.addLog(RequestLog.builder()
                .resource("qnh")
                .requestMethod("noticeProductInfo")
                .result(JSON.toJSONString(object))
                .createTime(LocalDateTime.now()).build());
    }

    public void synchronizedInfo1(String code) {
        List<StoreListVo> storeListVoList = getStores(new StoreDto());
        if (CollectionUtil.isNotEmpty(storeListVoList)) {
            ItemQueryDto itemQueryDto = new ItemQueryDto();
            itemQueryDto.setOrgCode(code);
            itemQueryDto.setPageSize(100);
            GoodsItemPageVo GoodsItemPageVo = itemQuery(itemQueryDto);
            int totalPages = GoodsItemPageVo.getTotalPage();
            CountDownLatch latch = new CountDownLatch(totalPages);
            // 使用并行流替代线程池提交
            IntStream.rangeClosed(1, totalPages)
                    .parallel()
                    .forEach(pageNum -> {
                        try {
                            log.info("开始处理第 {} 页数据", pageNum);
                            processPage(code, pageNum, itemQueryDto.getPageSize());
                        } catch (Exception e) {
                            log.error("处理分页数据时发生错误，页码: {}", pageNum, e);
                        } finally {
                            latch.countDown();
                        }
                    });

            try {
                latch.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("等待线程完成时被中断", e);
            }

            System.out.println(code + " 执行完成!");
        }
    }

    private void processPage(String code, int pageNum, int pageSize) {
        ItemQueryDto itemQueryDto = new ItemQueryDto();
        itemQueryDto.setOrgCode(code);
        itemQueryDto.setPageSize(pageSize);
        itemQueryDto.setPageNo(pageNum);

        ShopDetail shopDetail = shopDetailService.getOne(
                new LambdaQueryWrapper<ShopDetail>()
                        .eq(ShopDetail::getThirdPartyCode, code)
        );

        GoodsItemPageVo page = itemQuery(itemQueryDto);
        if (CollectionUtil.isEmpty(page.getData())) {
            return;
        }

        List<GoodsItemVo> items = page.getData();
        List<String> spuCodes = items.stream()
                .map(GoodsItemVo::getSpuCode)
                .distinct()
                .collect(Collectors.toList());

        // 批量查询产品（减少循环内多次查询）
        Map<String, Product> existingProducts = productService.list(
                        Wrappers.<Product>lambdaQuery()
                                .in(Product::getSupId, spuCodes)
                                .eq(Product::getShopId, shopDetail.getShopId())
                ).stream()
                .collect(Collectors.toMap(Product::getSupId, product -> product));

        // 批量查询分类（减少循环内查询）
        List<String> categoryNames = items.stream()
                .flatMap(item -> item.getCategoryInfo().stream())
                .map(GoodsItemVo.CategoryInfo::getName)
                .distinct()
                .collect(Collectors.toList());

        Map<String, Category> categoryMap = categoryService.list(
                        Wrappers.<Category>lambdaQuery()
                                .in(Category::getCategoryName, categoryNames)
                                .eq(Category::getShopId, shopDetail.getShopId())
                                .ne(Category::getGrade, 0)
                ).stream()
                .collect(Collectors.toMap(
                        Category::getCategoryName,
                        c -> c,
                        (existing, replacement) -> {
                            // 选择 grade 更高的分类（例如：优先取子分类）
                            return existing.getGrade() >= replacement.getGrade() ? existing : replacement;
                        }
                ));

        // 批量处理商品
        for (GoodsItemVo item : items) {
            String spuCode = item.getSpuCode();
            Product product = existingProducts.getOrDefault(spuCode, new Product());

            boolean isNew = (product.getProdId() == null);

            // 设置基本属性
            product.setShopId(shopDetail.getShopId());
            product.setSupId(spuCode);
            product.setProdName(item.getName());

            // 获取分类ID
            long categoryId = 0L;
            if (CollectionUtil.isNotEmpty(item.getCategoryInfo())) {
                String categoryName = item.getCategoryInfo().get(0).getName();
                Category category = categoryMap.get(categoryName);
                if (category != null && category.getGrade() != 0) {
                    categoryId = category.getCategoryId();
                }
            }
            product.setCategoryId(categoryId);
            product.setShopCategoryId(categoryId);

            // 处理价格和库存
            GoodsItemVo.ChannelItemInfoList channelItem = getChannelItem(item);
            if (channelItem != null && channelItem.getChannelPrice() != null) {
                double price = Double.parseDouble(channelItem.getChannelPrice()) / 100;
                Integer quantity = channelItem.getChannelQuantity().intValue();
                product.setOriPrice(price);
                product.setPrice(price);
                product.setTotalStocks(quantity);
                product.setStatus(1);
            } else {
                product.setOriPrice(0.1);
                product.setPrice(0.01);
                product.setStatus(0);
                product.setTotalStocks(0);
            }

            product.setBrief(item.getDescription());
            product.setVideo(item.getVideoInfo());
            product.setPic(item.getImages());
            product.setImgs(item.getImages());
            product.setCreateTime(new Date());
            product.setUpdateTime(new Date());
            product.setContent("");
            product.setShopName(item.getPoiName());

            if (isNew) {
                productService.save(product);
            } else {
                productService.updateById(product);
            }

            // 处理 SKU
            List<GoodsItemVo.SukList> skus = item.getSkuList();
            if (CollectionUtil.isNotEmpty(skus)) {
                List<String> skuIds = skus.stream()
                        .map(GoodsItemVo.SukList::getSkuId)
                        .collect(Collectors.toList());

                // 批量查询已有 SKU
                Map<String, Sku> existingSkus = skuService.list(
                                Wrappers.<Sku>lambdaQuery()
                                        .in(Sku::getSkuCode, skuIds)
                                        .eq(Sku::getProdId, product.getProdId())
                        ).stream()
                        .collect(Collectors.toMap(Sku::getSkuCode, s -> s));

                skus.forEach(skuItem -> {
                    String skuCode = skuItem.getSkuId();
                    Sku sku = existingSkus.getOrDefault(skuCode, new Sku());

                    boolean isSkuNew = (sku.getSkuId() == null);

                    sku.setSkuCode(skuCode);
                    sku.setProdId(product.getProdId());
                    sku.setSkuName(skuItem.getSpec());
                    sku.setOriPrice(product.getOriPrice());
                    sku.setPrice(product.getPrice());
                    sku.setStocks(product.getTotalStocks());
                    sku.setUpdateTime(new Date());
                    sku.setRecTime(new Date());
                    sku.setProdName(product.getProdName());
                    sku.setWeight(Double.parseDouble(skuItem.getWeightForUnit()));
                    sku.setVolume(0.0D);
                    sku.setStatus(skuItem.getPurchaseStatus());
                    sku.setPartyCode(skuItem.getSkuId());
                    sku.setModelId(item.getSpuCode());
                    sku.setIsDelete(0);
                    sku.setWeightUnit(skuItem.getWeightUnit());
                    sku.setActualStocks(product.getTotalStocks());

                    if (isSkuNew) {
                        skuService.save(sku);
                    } else {
                        skuService.updateById(sku);
                    }

                    System.out.println("新增 SKUID：" + sku.getSkuId());
                });
            }
        }
    }

    private GoodsItemVo.ChannelItemInfoList getChannelItem(GoodsItemVo item) {
        List<GoodsItemVo.ChannelItemInfoList> channelItems = item.getSkuList().get(0).getChannelItemInfoList();
        for (GoodsItemVo.ChannelItemInfoList info : channelItems) {
            if (info.getChannelId() == 100) {
                return info;
            }
        }
        if (channelItems.isEmpty()) {
            return null;
        }
        return channelItems.get(0);
    }
}
