package org.dromara.zhishu.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.pdd.pop.sdk.common.util.JsonUtil;
import com.pdd.pop.sdk.http.PopClient;
import com.pdd.pop.sdk.http.PopHttpClient;
import com.pdd.pop.sdk.http.api.pop.request.PddGoodsSkuPriceUpdateRequest;
import com.pdd.pop.sdk.http.api.pop.response.PddGoodsSkuPriceUpdateResponse;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.pqc.math.linearalgebra.BigEndianConversions;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysOss;
import org.dromara.system.service.ISysConfigService;
import org.dromara.zhishu.domain.*;
import org.dromara.zhishu.domain.bo.*;
import org.dromara.zhishu.domain.dto.BookPriceInfoDto;
import org.dromara.zhishu.domain.dto.SuccessDataItemDto;
import org.dromara.zhishu.domain.dto.request.GoodsSaleStatusSetRequest;
import org.dromara.zhishu.domain.dto.request.SoldOutRequest;
import org.dromara.zhishu.domain.vo.*;
import org.dromara.zhishu.enums.TaskStatusTypeEnum;
import org.dromara.zhishu.enums.TaskTypeEnum;
import org.dromara.zhishu.service.*;
import org.dromara.zhishu.service.client.KfzClient;
import org.dromara.zhishu.service.client.PddClient;
import org.dromara.zhishu.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.dromara.zhishu.mapper.TaskMapper;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.transfer.s3.model.Upload;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务列表Service业务层处理
 *
 * @author yxy
 * @date 2025-03-21
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class TaskServiceImpl implements ITaskService {

    private final TaskMapper baseMapper;
    private final IRunningTaskService runningTaskService;
    private final IRunningTaskByShopService runningTaskByShopService;
    private final IShopService shopService;
    private final IShopDetailService shopDetailService;
    private final PddClient pddClient;
    private final IPriceTemplateService priceTemplateService;
    private final ITaskPauseService taskPauseService;

    @Lazy
    @Autowired
    private PddServiceImpl pddService;




    /**
     * 锁对象
     */
    private final Map<String, Object> lockMap = new HashMap<>();
    private final Map<String, Boolean> runMap = new HashMap<>();
    @Autowired
    private TaskMapper taskMapper;

    /**
     * 查询任务列表
     *
     * @param id 主键
     * @return 任务列表
     */
    @Override
    public TaskVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public TaskVo selectByFileName(String fileName) {
        return baseMapper.selectByFileName(fileName);
    }

    @Override
    public List<TaskVo> selectRunningTask(Integer pageSize,Integer pageNum){
        return baseMapper.selectRunningTask( pageSize, pageNum);
    }

    @Override
    public int selectRunningTaskCount(){
        return baseMapper.selectRunningTaskCount();
    }

    /**
     * 分页查询任务列表列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 任务列表分页列表
     */
    @Override
    public TableDataInfo<TaskVo> queryPageList(TaskBo bo, PageQuery pageQuery) {
        // 当前用户id
        Long userId = LoginHelper.getUserId();
        if(userId != 1){
            bo.setCreateBy(userId);
        }
        // 通过用户id找到店铺id
        LambdaQueryWrapper<Task> lqw = buildQueryWrapper(bo);
        Page<TaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        for (TaskVo record : result.getRecords()) {
            if (TaskTypeEnum.SYNC_GOODS_KFZ.getCode().equals(record.getTaskType())||TaskTypeEnum.SYNC_GOODS_WLN.getCode().equals(record.getTaskType())) {
                if (TaskStatusTypeEnum.EXECUTED.getCode().equals(record.getTaskStatus())) {
                    record.setHasSyncFile(false);
                } else {
                    // 判断redis中是否存在未完成的任务
                    String lockKey = "ReadExcelKey_" + record.getShopIds();
                    String writeExcelLock = RedisUtils.getCacheObject(lockKey);
                    if (ObjectUtil.isNotEmpty(writeExcelLock)) {
                        log.info("============正在读取文件：{}=============", writeExcelLock);
                        record.setHasSyncFile(false);
                    } else {
                        // 指定读取需要新增的商品Excel文件路径
                        String newGoodsExcelPath = Paths.get(UrlUtil.getUrl(), "New_" + record.getShopIds() + "_0.xlsx").toString();
                        log.info("============新增文件：{}=============", newGoodsExcelPath);
                        // 指定读取需要修改的商品Excel文件路径
                        String updateGoodsExcelPath = Paths.get(UrlUtil.getUrl(), "Changed_" + record.getShopIds() + "_0.xlsx").toString();
                        log.info("============变更文件：{}=============", updateGoodsExcelPath);
                        // 若获取存在说明存在读取该文件的线程，则直接返回，不进行后续操作
                        record.setHasSyncFile(FileUtil.isFileExists(newGoodsExcelPath) || FileUtil.isFileExists(updateGoodsExcelPath));
                    }
                }
            }

        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的任务列表列表
     *
     * @param bo 查询条件
     * @return 任务列表列表
     */
    @Override
    public List<TaskVo> queryList(TaskBo bo) {
        LambdaQueryWrapper<Task> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Task> buildQueryWrapper(TaskBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Task> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(Task::getCreateTime);
        lqw.eq(StringUtils.isNotBlank(bo.getTaskType()), Task::getTaskType, bo.getTaskType());
        lqw.eq(StringUtils.isNotBlank(bo.getShopIds()), Task::getShopIds, bo.getShopIds());

        lqw.like(StringUtils.isNotBlank(bo.getShopNames()), Task::getShopNames, bo.getShopNames());
        lqw.like(StringUtils.isNotBlank(bo.getFileName()), Task::getFileName, bo.getFileName());
        lqw.eq(bo.getDataNum() != null, Task::getDataNum, bo.getDataNum());
        lqw.eq(bo.getId() != null, Task::getId, bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskStatus()), Task::getTaskStatus, bo.getTaskStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Task::getStatus, bo.getStatus());
        lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), Task::getCreateBy, bo.getCreateBy());
        return lqw;
    }

    /**
     * 新增任务列表
     *
     * @param bo 任务列表
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TaskBo bo) {
        Task add = MapstructUtils.convert(bo, Task.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

//    @Override
//    public void addGoods(Map map, TaskBo taskBo, Long userId) {
//        // 图书列表
//        Map data = (Map) map.get("data");
//        Map addMap = new HashMap();
//        addMap.put("shopIds",map.get("shopIds").toString());
//        addMap.put("taskId",taskBo.getId().toString());
//        addMap.put("taskName",taskBo.getFileName());
//        addMap.put("url", data.get("url").toString());
//        addMap.put("imageSelect",map.get("imageSelect").toString());
//        addMap.put("way",map.get("way").toString());
//        //调用接口
//        InterfaceUtils.postForm("http://localhost:16001","/huidiao/pdd/addGoods", addMap);
//    }


    @Override
    public void addGoods(Map map, TaskBo taskBo, Long userId) {
        String way = taskBo.getWay();
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        Map data = (Map) map.get("data");
        List<SuccessDataItemDto> rawList = null;
        try {
            rawList = EasyExcelUtil.readExcelFromUrl(data.get("url").toString(),SuccessDataItemDto.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 获取原始数据并过滤掉所有字段都为空的无效行
        List<SuccessDataItemDto> list = rawList.stream()
                .filter(dto -> dto.isValidData())
                .collect(Collectors.toList());

        try {
            DecryptUtils.decryptDtoList(list);
            System.out.println("数据解密成功");
        } catch (Exception e) {
            System.err.println("数据解密失败: " + e.getMessage());
            throw new RuntimeException("解密失败", e);
        }

        for(String shopId : shopIdsArr){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            // 剩余额度
            Long usageCount = shopService.checkUsageCount(shopVo);
            ShopDetailVo shopDetails =shopDetailService.queryByShopId(Long.parseLong(shopId));
            String createResStr = map.get("createResStr").toString();
            Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
            String taskId = createResMap.get("data").toString();
            Map setTaskBodyMap = new HashMap();
            setTaskBodyMap.put("task_id",taskId);
            List<Map<String,Object>> bodyList = new ArrayList<>();
            int runNum = 0;
            for (SuccessDataItemDto bookVo : list) {
                runNum++;
                if (shopDetails.getOpenRepeat().equals("1")){
                    // 多店过滤
                    List<ShopVo> ShopVoList = shopService.selectMallIdsById(Long.parseLong(shopId));
                    String ids = ShopVoList.stream()
                            .map(ShopVo::getId)          // 提取 id，假设返回类型为 Long 或 String
                            .map(String::valueOf)        // 转换为字符串
                            .collect(Collectors.joining(","));
                    // 构建请求参数
                    Map formData = new HashMap();
                    // 注意：接口需要的格式是数组字符串 "[id1,id2,id3]"
                    String shopIdsArray = "[" + ids + "]";
                    formData.put("shopIds", shopIdsArray);
                    formData.put("isbn", bookVo.getIsbn());
                    String res = InterfaceUtils.postForm("http://36.212.20.113:8182","/api/goods/goofish/multipleStores",formData);
                    Map resMap = JsonUtil.transferToObj(res,Map.class);
                    Boolean bool = (Boolean) resMap.get("success");
                    if (!bool){
                        continue;
                    }
                }else if (way.equals("0")){
                    Map formData = new HashMap();
                    formData.put("shopid",shopId);
                    formData.put("isbn",bookVo.getIsbn());
                    String res = InterfaceUtils.postForm("http://36.212.20.113:8182","/api/goods/simple",formData);
                    Map resMap = JsonUtil.transferToObj(res,Map.class);
                    Boolean bool = (Boolean) resMap.get("success");
                    if (!bool){
                        continue;
                    }
                }
                Map body = new HashMap();
                Map bookInfo = new HashMap();
                bookInfo.put("isbn",bookVo.getIsbn());
                bookInfo.put("book_name",bookVo.getTitle());
                if(StringUtils.isNotEmpty(bookVo.getImageBigUrl())){
                    JSONObject imageObject = new JSONObject();
                    List<String> carouselUrlArray = new ArrayList<>();
                    String[] images = bookVo.getImageBigUrl().split(",");
                    for (String image : images){
                        carouselUrlArray.add(image);
                    }
                    imageObject.put("carousel_url_array",carouselUrlArray);
                    bookInfo.put("image_object",imageObject);
                }
                body.put("book_info",bookInfo);
                Map detail = new HashMap();
                BigDecimal totalPrice = new BigDecimal(bookVo.getTotalPrice());
                detail.put("price",totalPrice.longValue());
                detail.put("stock",bookVo.getStock() == null || StringUtils.isEmpty(bookVo.getStock()) ? shopDetails.getStockDeff() : Long.parseLong(bookVo.getStock()));
                // 商品编码
                detail.put("out_goods_id",bookVo.getGoodsCode() == null ? "" : bookVo.getGoodsCode());
                // 规格编码
                detail.put("sku_code",bookVo.getSkuCode() == null ? "" : bookVo.getSkuCode());
                // 上下架状态
                String isOnSale = bookVo.getIsOnSale() == null ? "0" : bookVo.getIsOnSale().equals("0") ? "1" : "0";
                detail.put("is_onsale",Long.parseLong(isOnSale));
                body.put("detail",detail);
                bodyList.add(body);
                if (bodyList.size() % 1000 == 0 || runNum == list.size()){
                    String response = InterfaceUtils.postTaskBodyWithSign(UrlUtil.getNewTaskUrl(), "/task/setTaskBody", taskId, bodyList);
                    System.out.println("新发布任务发布"+bodyList.size()+"条");
                    // 清空列表，准备下一批
                    bodyList.clear();
                }

                usageCount--;
                if (usageCount == 0){
                    break;
                }
            }
            // 处理剩余数据
            if (!bodyList.isEmpty()) {
                String response = InterfaceUtils.postTaskBodyWithSign(UrlUtil.getNewTaskUrl(), "/task/setTaskBody", taskId, bodyList);
                System.out.println("新发布任务发布结束："+bodyList.size()+"条");
            }
            // 更新使用次数
            shopService.updateUsageCount(shopVo,usageCount);
        }
    }


    @Override
    public void addGoodsCenter(Map map, TaskBo taskBo, Long userId) {
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        List<Map> list = (List<Map>) map.get("data");
        for(String shopId : shopIdsArr){
            ShopDetailVo shopDetails =shopDetailService.queryByShopId(Long.parseLong(shopId));
            //获取价格模板
            PriceTemplateVo priceTemplateVo = priceTemplateService.queryById(shopDetails.getSaleTemplateId());
            BigDecimal lowPrice = new BigDecimal(priceTemplateVo.getLowPrice()).divide(new BigDecimal(100));
            BigDecimal highPrice = new BigDecimal(priceTemplateVo.getHighPrice()).divide(new BigDecimal(100));
            for (Map bookVo : list) {
                BigDecimal totalPrice = new BigDecimal(bookVo.get("price").toString());
                Map goMap = new HashMap();
                goMap.put("priority","4");
                goMap.put("retry_count","3");
                goMap.put("isbn", bookVo.get("bookNum") == null ? "" : bookVo.get("bookNum").toString());
                goMap.put("totalPrice",  bookVo.get("price") == null ? "" : bookVo.get("price").toString());
                goMap.put("stock", bookVo.get("stock") == null ? "" : bookVo.get("stock").toString());
                goMap.put("bookName", bookVo.get("bookName") == null ? "" : bookVo.get("bookName").toString());
                goMap.put("code", bookVo.get("code") == null ? "" : bookVo.get("code").toString());
                goMap.put("imgBigUrl", bookVo.get("bookImgUrl") == null ? "" : bookVo.get("bookImgUrl").toString());
                goMap.put("artNo", bookVo.get("artNo") == null ? "" : bookVo.get("artNo").toString());
                goMap.put("taskId", taskBo.getId().toString());
                goMap.put("shopId",shopId);
                goMap.put("imageSelect", map.get("imageSelect"));  //1是官图 2是实拍图
                goMap.put("way",map.get("way"));
                /**
                 * 创建运行任务对象
                 */
                RunningTask runningTask = new RunningTask();
                runningTask.setTaskId(taskBo.getId());
                runningTask.setShopId(Long.valueOf(shopId));
                runningTask.setGoodsId(0L);
                runningTask.setRandomNum(System.currentTimeMillis());
                runningTask.setTaskName(taskBo.getFileName());
                runningTask.setPriority(255L);
                runningTask.setData(JsonUtil.transferToJson(goMap));

                if(totalPrice.compareTo(highPrice) > 0 || totalPrice.compareTo(lowPrice) < 0){
                    runningTask.setStatus("3");
                    runningTask.setCallBackData("商品价格不在设置的价格区间");
                }else{
                    runningTask.setStatus("0");
                }
                runningTask.setTaskType("1");
                runningTaskService.insert(runningTask);
            }
        }
    }

    /**
     * 表格更新任务
     */
    @Override
    public void editGoodsPrice(Map map, TaskBo taskBo, Long userId) {
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        Map data = (Map) map.get("data");
        List<SuccessDataItemDto> rawList = null;
        try {
            rawList = EasyExcelUtil.readExcelFromUrl(data.get("url").toString(),SuccessDataItemDto.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 获取原始数据并过滤掉所有字段都为空的无效行
        List<SuccessDataItemDto> list = rawList.stream()
                .filter(dto -> dto.isValidData())
                .collect(Collectors.toList());

        //根据isbn查询商品信息
        for(String shopId : shopIdsArr){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            Long usageCount = shopService.checkUsageCount(shopVo);
            ShopDetailVo shopDetailVo = shopDetailService.queryByShopId(Long.parseLong(shopId));
            PriceTemplateVo priceTemplateVo = priceTemplateService.queryById(shopDetailVo.getSaleTemplateId());

            String createResStr = map.get("createResStr").toString();
            Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
            String taskId = createResMap.get("data").toString();
            Map setTaskBodyMap = new HashMap();
            setTaskBodyMap.put("task_id",taskId);
            List<Map<String,Object>> bodyList = new ArrayList<>();
            int runNum = 0;
            for (SuccessDataItemDto bookVo : list) {

                //调用任务池方法，如果正常则继续，如果不正常则休息5秒
                BigDecimal priceL = null;
                BigDecimal priceOld = new BigDecimal(bookVo.getTotalPrice()).divide(new BigDecimal(100));
                BigDecimal highPrice = new BigDecimal(priceTemplateVo.getHighPrice()).divide(new BigDecimal(100));;
                BigDecimal lowPrice = new BigDecimal(priceTemplateVo.getLowPrice()).divide(new BigDecimal(100));

                if(priceOld.compareTo(highPrice) > 0 || priceOld.compareTo(lowPrice) < 0){
                    //商品价格不在店铺设置的价格区间
                    continue;
                }else{
                    priceL = priceOld;
                }
                //加价百分比
                BigDecimal proportion = new BigDecimal(0);
                //加价价格
                BigDecimal addAmount = new BigDecimal(0);
                //获取价格区间
                List<Map> priceListMap = JsonUtil.transferToObj(priceTemplateVo.getRangePrice(),List.class);
                for (int i=0;i<priceListMap.size();i++){
                    Map priceMap = priceListMap.get(i);
                    //范围低价
                    BigDecimal minPrice = new BigDecimal(priceMap.get("minPrice").toString()).divide(new BigDecimal(100));
                    //范围高价
                    BigDecimal maxPrice = new BigDecimal(priceMap.get("maxPrice").toString()).divide(new BigDecimal(100));

                    if(priceOld.compareTo(minPrice) >= 0 && priceOld.compareTo(maxPrice) <= 0){
                        /**
                         * 当商品在这个价格区间内时，获取加价百分比喝加价价格
                         */
                        proportion = new BigDecimal(priceMap.get("adjustPercent").toString()).divide(new BigDecimal(100));
                        addAmount = new BigDecimal(priceMap.get("adjustAmount").toString()).divide(new BigDecimal(100));
                        break;
                    }
                    /**
                     * 如果执行到这里，则代表没有匹配的价格模板，则使用第一条
                     */
                    if(i == priceListMap.size() - 1){
                        //如果最后一条执行完毕还是没有匹配到，则使用第一条
                        priceMap = priceListMap.get(0);
                        proportion = new BigDecimal(priceMap.get("adjustPercent").toString()).divide(new BigDecimal(100));
                        addAmount = new BigDecimal(priceMap.get("adjustAmount").toString()).divide(new BigDecimal(100));
                    }
                }
                //拼单价格
                BigDecimal pricePd = proportion
                        .multiply(priceL)
                        .add(priceL)
                        .add(addAmount)
                        .multiply(new BigDecimal(100))
                        .setScale(0, RoundingMode.DOWN);

                runNum++;
                Map body = new HashMap();
                Map bookInfo = new HashMap();
                bookInfo.put("isbn",bookVo.getIsbn());
                bookInfo.put("trilateralId",bookVo.getTrilateralId());
                bookInfo.put("goodsCode",bookVo.getGoodsCode());
                body.put("book_info",bookInfo);
                Map detail = new HashMap();
                // 1 上架  2 下架  3 删除  4 修改库存  5 修改价格
                detail.put("status",5);
                detail.put("price",pricePd.longValue());
                body.put("detail",detail);
                bodyList.add(body);

                if (bodyList.size() % 500 == 0 || runNum == list.size()){
                    NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
                    // 清空列表，准备下一批
                    bodyList.clear();
                }

                usageCount--;
                if (usageCount == 0){
                    break;
                }
            }
            // 处理剩余数据
            if (!bodyList.isEmpty()) {
                NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
            }


            // 更新使用次数
            shopService.updateUsageCount(shopVo,usageCount);
        }
    }

    @Override
    public void editGoodsStock(Map map, TaskBo taskBo, Long userId) {
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        Map data = (Map) map.get("data");
        List<SuccessDataItemDto> rawList = null;
        try {
            rawList = EasyExcelUtil.readExcelFromUrl(data.get("url").toString(), SuccessDataItemDto.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 获取原始数据并过滤掉所有字段都为空的无效行
        List<SuccessDataItemDto> list = rawList.stream()
                .filter(dto -> dto.isValidData())
                .collect(Collectors.toList());

        for(String shopId : shopIdsArr) {
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            Long usageCount = shopService.checkUsageCount(shopVo);
            String createResStr = map.get("createResStr").toString();
            Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
            String taskId = createResMap.get("data").toString();
            Map setTaskBodyMap = new HashMap();
            setTaskBodyMap.put("task_id",taskId);
            List<Map<String,Object>> bodyList = new ArrayList<>();
            int runNum = 0;
            for (SuccessDataItemDto bookVo : list) {
                runNum++;
                Map body = new HashMap();
                Map bookInfo = new HashMap();
                bookInfo.put("isbn",bookVo.getIsbn());
                bookInfo.put("trilateralId",bookVo.getTrilateralId());
                bookInfo.put("goodsCode",bookVo.getGoodsCode());
                body.put("book_info",bookInfo);
                Map detail = new HashMap();
                // 1 上架  2 下架  3 删除  4 修改库存  5 修改价格
                detail.put("status",4);
                detail.put("stock",Long.parseLong(bookVo.getStock()));
                body.put("detail",detail);
                bodyList.add(body);

                if (bodyList.size() % 500 == 0 || runNum == list.size()){
                    NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
                    // 清空列表，准备下一批
                    bodyList.clear();
                }

                usageCount--;
                if (usageCount == 0){
                    break;
                }
            }
            // 处理剩余数据
            if (!bodyList.isEmpty()) {
                NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
            }
            // 更新使用次数
            shopService.updateUsageCount(shopVo,usageCount);
        }
    }


//    @Override
//    public void editTwoPiecesDiscount(Long shopId){
//        ShopVo shopVo = shopService.queryById(shopId);
//        List<Map> runningTaskList = runningTaskByShopService.selectGetShopGoodsList("t_running_task_"+shopId,"",null,null,null,null,null,0L,100000L);
//        for(Map map : runningTaskList){
//            //解析数据
//            Map successData = JsonUtil.transferToObj(map.get("success_data").toString(), Map.class);
//            String goodsId = successData.get("trilateralId").toString();
//            String skuId = successData.get("skuId").toString();
//            Map<String,String> mapData = new HashMap();
//            mapData.put("goodsId",goodsId);
//            mapData.put("skuId",skuId);
//            mapData.put("token",shopVo.getToken());
//            String clientId = "203c5a7ba8bd4b8488d5e26f93052642";
//            String clientSecret = "892ffaa86e12b7a3d8d2942b669d9aa520ad8179";
//            PopClient client = new PopHttpClient(clientId, clientSecret);
//            PddGoodsSkuPriceUpdateRequest request = new PddGoodsSkuPriceUpdateRequest();
//            request.setGoodsId(Long.parseLong(goodsId));
//            List<PddGoodsSkuPriceUpdateRequest.SkuPriceListItem> skuPriceList = new ArrayList<PddGoodsSkuPriceUpdateRequest.SkuPriceListItem>();
//            PddGoodsSkuPriceUpdateRequest.SkuPriceListItem item = new PddGoodsSkuPriceUpdateRequest.SkuPriceListItem();
//            item.setSkuId(Long.parseLong(skuId));
//            skuPriceList.add(item);
//            request.setSkuPriceList(skuPriceList);
//            request.setTwoPiecesDiscount(95);
//            PddGoodsSkuPriceUpdateResponse response = null;
//            while (true) {
//                try {
//                    response = client.syncInvoke(request, shopVo.getToken());
//                    // 如果没有错误或者错误不是频率限制错误，则退出循环
//                    if (response.getErrorResponse() == null ||
//                            (!response.getErrorResponse().getErrorMsg().contains("调用过于频繁，请调整调用频率") &&
//                            !response.getErrorResponse().getErrorMsg().contains("系统内部异常"))) {
//                        break;
//                    }
//                } catch (Exception e) {
//                    System.out.println(e.getMessage());
//                }
//            }
//            System.out.println(JsonUtil.transferToJson(response));
//        }
//    }

    /**
     * 表格更新商品上下级状态
     */
    @Override
    public void editGoodsIsOnSale(Map map, TaskBo taskBo, Long userId) {
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        Map data = (Map) map.get("data");
        List<SuccessDataItemDto> rawList = null;
        try {
            rawList = EasyExcelUtil.readExcelFromUrl(data.get("url").toString(),SuccessDataItemDto.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 获取原始数据并过滤掉所有字段都为空的无效行
        List<SuccessDataItemDto> list = rawList.stream()
                .filter(dto -> dto.isValidData())
                .collect(Collectors.toList());
        //根据isbn查询商品信息
        for(String shopId : shopIdsArr){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            Long usageCount = shopService.checkUsageCount(shopVo);
            // 拼多多
            String createResStr = map.get("createResStr").toString();
            Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
            String taskId = createResMap.get("data").toString();
            Map setTaskBodyMap = new HashMap();
            setTaskBodyMap.put("task_id",taskId);
            List<Map<String,Object>> bodyList = new ArrayList<>();
            int runNum = 0;
            for (SuccessDataItemDto bookVo : list) {
                runNum++;
                Map body = new HashMap();
                Map bookInfo = new HashMap();
                bookInfo.put("isbn",bookVo.getIsbn());
                bookInfo.put("trilateralId",bookVo.getTrilateralId());
                bookInfo.put("goodsCode",bookVo.getGoodsCode());
                body.put("book_info",bookInfo);
                Map detail = new HashMap();
                // 1 上架  2 下架
                detail.put("status",bookVo.getIsOnSale().equals("0") ? 2 : 1);
                body.put("detail",detail);
                bodyList.add(body);
                if (bodyList.size() % 500 == 0 || runNum == list.size()){
                    NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
                    // 清空列表，准备下一批
                    bodyList.clear();
                }
                usageCount--;
                if (usageCount == 0){
                    break;
                }
            }
            // 处理剩余数据
            if (!bodyList.isEmpty()) {
                NewTaskUtils.newTaskPost(taskId,shopVo.getId().toString(),bodyList);
            }

            // 更新使用次数
            shopService.updateUsageCount(shopVo,usageCount);
        }
    }

    @Override
    public void updateGoodsTask(Map map, TaskBo taskBo, Long userId){
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        // 图书列表
        Map data = (Map) map.get("data");
        List<BookVo> list = null;
        try {
            list = EasyExcelUtil.readExcelFromUrl(data.get("url").toString(),BookVo.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        for(String shopId : shopIdsArr){
            for (BookVo bookVo : list) {
                Map goMap = new HashMap();
                goMap.put("priority","3");
                goMap.put("retry_count","3");
                goMap.put("isbn", bookVo.getBookNum());
                goMap.put("totalPrice",  bookVo.getPrice());
                goMap.put("stock", bookVo.getStock());
                goMap.put("bookName", bookVo.getBookName());
                goMap.put("code", bookVo.getCode());
                goMap.put("imgBigUrl", bookVo.getBookImgUrl());
                goMap.put("artNo", bookVo.getArtNo());
                goMap.put("taskId", taskBo.getId().toString());
                goMap.put("shopId",shopId);
                goMap.put("imageSelect", map.get("imageSelect"));
                goMap.put("imageChoice", map.get("imageChoice"));
                goMap.put("way",map.get("way"));
                goMap.put("serviceName","UPDATE_GOODS_TASK");
                /**
                 * 创建运行任务对象
                 */
                RunningTask runningTask = new RunningTask();
                runningTask.setTaskId(taskBo.getId());
                runningTask.setShopId(Long.valueOf(shopId));
                runningTask.setGoodsId(0L);
                runningTask.setRandomNum(System.currentTimeMillis());
                runningTask.setTaskName(taskBo.getFileName());
                runningTask.setPriority(255L);
                runningTask.setData(JsonUtil.transferToJson(goMap));
                runningTask.setTaskType(taskBo.getTaskType());
                runningTask.setStatus("0");
                runningTaskService.insert(runningTask);
            }
        }


    }

    /**
     * 手动库存同步任务
     * @param map
     * @param taskBo
     * @param userId
     */
    @Override
    public void stockSynchronize(Map map,TaskBo taskBo,Long userId){

        // 记录参数日志
        FileUtil.logParameters("stockSynchronize",map, taskBo, userId);

        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        //转换类型，确保是数值型
        List<Map<String, Object>> stockNumMapList = ((List<Map>) map.get("priceAdjustments"))
                .stream()
                .map(item -> {
                    Map<String, Object> newItem = new HashMap<>(item);

                    // 处理 proportion
                    if (newItem.containsKey("proportion")) {
                        Object proportion = newItem.get("proportion");
                        if (proportion == null) {
                            newItem.put("proportion", 100L); // 为空时默认给100
                        } else if (proportion instanceof String) {
                            String proportionStr = ((String) proportion).trim();
                            if (proportionStr.isEmpty()) {
                                newItem.put("proportion", 100L); // 空字符串时默认给100
                            } else {
                                newItem.put("proportion", Long.parseLong(proportionStr));
                            }
                        } else if (proportion instanceof Integer) {
                            newItem.put("proportion", ((Integer) proportion).longValue());
                        }
                        // 如果是 Long 类型则保持不变
                    } else {
                        newItem.put("proportion", 100L); // 不存在该字段时默认给100
                    }

                    // 处理 addNum
                    if (newItem.containsKey("addNum")) {
                        Object addNum = newItem.get("addNum");
                        if (addNum == null) {
                            newItem.put("addNum", 0L); // 为空时默认给0
                        } else if (addNum instanceof String) {
                            String addNumStr = ((String) addNum).trim();
                            if (addNumStr.isEmpty()) {
                                newItem.put("addNum", 0L); // 空字符串时默认给0
                            } else {
                                newItem.put("addNum", Long.parseLong(addNumStr));
                            }
                        } else if (addNum instanceof Integer) {
                            newItem.put("addNum", ((Integer) addNum).longValue());
                        }
                        // 如果是 Long 类型则保持不变
                    } else {
                        newItem.put("addNum", 0L); // 不存在该字段时默认给0
                    }

                    return newItem;
                })
                .collect(Collectors.toList());

        for (String shopId : shopIdsArr){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("taskId",taskBo.getId().toString());
            jsonObject.put("shopId",shopId);
            jsonObject.put("token",shopVo.getToken());
            jsonObject.put("shopType",shopVo.getShopType());
            if(shopVo.getShopType().equals("5")){
                //咸鱼
                jsonObject.put("appId", shopVo.getMallId().toString());
                jsonObject.put("shopKey",shopVo.getShopKey());
            }

            jsonObject.put("priceAdjustments",stockNumMapList);
            String json = jsonObject.toString();
            Map dataMap = new HashMap();
            dataMap.put("data",json);
            InterfaceUtils.postForm("http://36.212.12.247:8115","/api/stockSynchronize",dataMap);
//            InterfaceUtils.postForm("http://localhost:8115","/api/stockSynchronize",dataMap);
        }
    }

    @Override
    public void deleteShopGoods(Map map, TaskBo taskBo, Long userId) {
        // 店铺ids
        String[] shopIdsArr = map.get("shopIds").toString().split(",");
        int deleteNum = Integer.parseInt(map.get("deleteNum").toString());
        int numDay = deleteNum / 5000;
        int num = deleteNum % 5000;
        if(num > 0){
            numDay = numDay + 1;
        }
        //根据isbn查询商品信息
        for(String shopId : shopIdsArr){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            String taskId = taskBo.getId().toString();
            //存储redis
            RedisUtils.setCacheObject("deleteGoods_"+taskId,taskId+","+shopId+","+shopVo.getToken(), Duration.ofDays(numDay));
        }
    }


    // 线程暂停
    public void taskWait(String threadId) {
        if (runMap.get(threadId)) {
            try {
                synchronized (lockMap.get(threadId)) {
                    lockMap.get(threadId).wait();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public int zanTing(String threadId) {
        if (runMap.get(threadId) == null) {
            return 0;
        }
        runMap.put(threadId, true);
        return 1;
    }

    @Override
    public int huanXing(String threadId) {
        if (lockMap.get(threadId) == null) {
            return 0;
        }
        synchronized (lockMap.get(threadId)) {
            runMap.put(threadId, false);
            lockMap.get(threadId).notify();
        }
        return 1;
    }

    /**
     * 修改任务列表
     *
     * @param bo 任务列表
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TaskBo bo) {
        Task update = MapstructUtils.convert(bo, Task.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Task entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除任务列表信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public void editTaskDataNum(String shopIds, Long dataNum, String taskType) {
        baseMapper.editTaskDataNum(shopIds,dataNum,taskType);
    }


    /**
     * 处理拉取任务
     */
    @Override
    public Map<String, Object> handlePullTask(TaskVo taskVo) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> shopDataList = new ArrayList<>();

        long shopId = Long.parseLong(taskVo.getShopIds());
        ShopVo shopVo = shopService.queryById(shopId);

        Map<String, Object> shopData = createShopDataMap(taskVo.getId(), shopVo);

        String tableName = "t_running_task_" + shopId;
        if (runningTaskByShopService.checkTableExists(tableName) == 0) {
            // 表不存在
            setDefaultCounts(shopData);
        } else {
            int taskCount = runningTaskByShopService.selectGetShopGoodsNumByTasKId(tableName, taskVo.getId().toString());
            if (taskCount == 0) {
                // 不是最新任务
                setDefaultCounts(shopData);
            } else {
                String status = runningTaskByShopService.selectStatus(tableName);
                shopData.put("num", taskCount);
                if ("2".equals(status)) {
                    // 未完成
                    shopData.put("successCount", 0);
                    shopData.put("waitCount", taskCount);
                } else {
                    // 已完成
                    shopData.put("successCount", taskCount);
                    shopData.put("waitCount", 0);
                }
            }
        }

        shopDataList.add(shopData);

        result.put("successCount", shopData.get("successCount"));
        result.put("waitCount", shopData.get("waitCount"));
        result.put("allData", shopDataList);

        return result;
    }

    /**
     * 处理其他类型任务
     */
    @Override
    public Map<String, Object> handleOtherTask(TaskVo taskVo) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> shopDataList = new ArrayList<>();

        // 从文件获取数据
        int allNum = getTaskCountFromFile(taskVo.getId());

        // 从数据库获取任务数据
        List<RunningTaskNumVo> taskNumList = runningTaskService.selectTaskAllNum(taskVo.getId());

        // 处理数据库中的任务数据
        processTaskDataFromDatabase(taskNumList, shopDataList);

        // 合并文件数据和数据库数据
        mergeFileAndDatabaseData(allNum, shopDataList);

        // 计算总计
        calculateTotalCounts(result, shopDataList);

        result.put("allData", shopDataList);
        return result;
    }

    /**
     * 从文件获取任务数量
     */
    private int getTaskCountFromFile(Long taskId) {
        String fileUrl = "https://book.center.file.buzhiyushu.cn/task_log/task-log-csv/" +
                taskId + "/" + taskId + "_count.json";

        try {
            Map<String, Object> numMap = JsonObjUtil.parseJsonFromUrl(fileUrl);
            return Integer.parseInt(numMap.get("totalTaskCount").toString());
        } catch (IOException e) {
            log.warn("无法从文件获取任务数量: {}", fileUrl, e);
            return 0;
        }
    }

    /**
     * 处理数据库中的任务数据
     */
    private void processTaskDataFromDatabase(List<RunningTaskNumVo> taskNumList,
                                             List<Map<String, Object>> shopDataList) {
        // 使用Map按shopId分组，避免重复处理
        Map<Long, Map<String, Object>> shopDataMap = new HashMap<>();
        Map<Long, String> shopNameCache = new HashMap<>();

        for (RunningTaskNumVo vo : taskNumList) {
            Long shopId = vo.getShopId();

            // 获取或创建店铺数据
            Map<String, Object> shopData = shopDataMap.computeIfAbsent(shopId, k -> {
                ShopVo shopVo = shopService.queryById(shopId);
                shopNameCache.put(shopId, shopVo.getShopName());
                return createShopDataMap(vo.getTaskId(), shopId, shopVo.getShopName());
            });

            // 更新计数
            updateShopCounts(shopData, vo);
        }

        // 添加到结果列表
        shopDataList.addAll(shopDataMap.values());
    }

    /**
     * 合并文件和数据库数据
     */
    private void mergeFileAndDatabaseData(int fileTaskCount, List<Map<String, Object>> shopDataList) {
        if (fileTaskCount > 0) {
            // 这里需要根据实际情况调整合并逻辑
            // 假设文件数据是额外的成功任务
            for (Map<String, Object> shopData : shopDataList) {
                int currentSuccess = (int) shopData.get("successCount");
                shopData.put("successCount", currentSuccess + fileTaskCount);
                shopData.put("num", (int) shopData.get("num") + fileTaskCount);
            }
        }
    }

    /**
     * 计算总计数量
     */
    private void calculateTotalCounts(Map<String, Object> result, List<Map<String, Object>> shopDataList) {
        int totalSuccess = 0;
        int totalWait = 0;

        for (Map<String, Object> shopData : shopDataList) {
            totalSuccess += (int) shopData.get("successCount");
            totalWait += (int) shopData.get("waitCount");
        }

        result.put("successCount", totalSuccess);
        result.put("waitCount", totalWait);
    }

    /**
     * 创建店铺数据Map
     */
    private Map<String, Object> createShopDataMap(Long taskId, ShopVo shopVo) {
        return createShopDataMap(taskId, shopVo.getId(), shopVo.getShopName());
    }

    private Map<String, Object> createShopDataMap(Long taskId, Long shopId, String shopName) {
        Map<String, Object> shopData = new HashMap<>();
        shopData.put("taskId", taskId);
        shopData.put("shopId", shopId);
        shopData.put("shopName", shopName);
        shopData.put("num", 0);
        shopData.put("successCount", 0);
        shopData.put("waitCount", 0);
        return shopData;
    }

    /**
     * 设置默认计数
     */
    private void setDefaultCounts(Map<String, Object> shopData) {
        shopData.put("num", 0);
        shopData.put("successCount", 0);
        shopData.put("waitCount", 0);
    }

    /**
     * 更新店铺计数
     */
    private void updateShopCounts(Map<String, Object> shopData, RunningTaskNumVo vo) {
        int currentNum = (int) shopData.get("num");
        shopData.put("num", currentNum + vo.getAllNum());

        if ("3".equals(vo.getStatus()) || "4".equals(vo.getStatus())) {
            int currentSuccess = (int) shopData.get("successCount");
            shopData.put("successCount", currentSuccess + vo.getAllNum());
        } else {
            int currentWait = (int) shopData.get("waitCount");
            shopData.put("waitCount", currentWait + vo.getAllNum());
        }
    }

    @Override
    public List<ShopVo> getShopsBatch(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        return taskMapper.selectShopsByIds(ids);
    }
    @Override
    public List<ShopDetailVo> getShopDetailsBatch(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        return taskMapper.selectShopDetailsByIds(ids);
    }

    /**
     * 暂停任务
     * @param taskId
     * @return
     */
    @Override
    public Boolean taskPause(Long taskId){
        Long userId = LoginHelper.getUserId();
        TaskVo taskVo = taskMapper.selectVoById(taskId);
        String[] shopIds = taskVo.getShopIds().split(",");
        for(String shopId:shopIds){
            TaskPause taskPause = new TaskPause();
            taskPause.setCreateBy(userId);
            taskPause.setTaskId(taskId);
            taskPause.setShopId(Long.parseLong(shopId));
           taskPauseService.insert(taskPause);
        }
        //修改任务的状态为5
        TaskBo bo = new TaskBo();
        bo.setId(taskVo.getId());
        bo.setTaskStatus("5");
        return updateByBo(bo);
    }

    /**
     * 恢复任务
     * @param taskId
     * @return
     */
    @Override
    public Boolean taskRecover(Long taskId){
        TaskVo taskVo = taskMapper.selectVoById(taskId);
        TaskBo bo = new TaskBo();
        bo.setId(taskVo.getId());
        bo.setTaskStatus("0");
        taskPauseService.deleteByTaskId(taskId);
        return updateByBo(bo);
    }

    @Override
    public Task getTaskBoById(String id) {
        return this.baseMapper.selectById(id);
    }

    @Override
    public Task getTaskBoByRelationId(String id) {
        return this.baseMapper.getTaskBoByRelationId(id);
    }
}
