package org.dromara.zhishu.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvValidationException;
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.PddGoodsListGetRequest;
import com.pdd.pop.sdk.http.api.pop.request.PddPopAuthTokenRefreshRequest;
import com.pdd.pop.sdk.http.api.pop.response.PddGoodsListGetResponse;
import com.pdd.pop.sdk.http.api.pop.response.PddGoodsSpecGetResponse;
import com.pdd.pop.sdk.http.api.pop.response.PddMallInfoGetResponse;
import com.pdd.pop.sdk.http.api.pop.response.PddPopAuthTokenRefreshResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.config.RuoYiConfig;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.PddUtil;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.service.ISysConfigService;
import org.dromara.zhishu.domain.PddShopInfo;

import org.dromara.zhishu.domain.RunningTask;
import org.dromara.zhishu.domain.TUserPlatform;
import org.dromara.zhishu.domain.bo.ShopBo;
import org.dromara.zhishu.domain.bo.TaskBo;
import org.dromara.zhishu.domain.dto.ErpGoodsDto;
import org.dromara.zhishu.domain.dto.SuccessDataItemDto;
import org.dromara.zhishu.domain.dto.SuccessDataKfz;
import org.dromara.zhishu.domain.dto.request.RenovateOnSaleRequest;
import org.dromara.zhishu.domain.dto.request.UpdateShopGoodsDataPriceCSVRequest;
import org.dromara.zhishu.domain.dto.response.PddTokenResponse;
import org.dromara.zhishu.domain.vo.AccessTokenVo;
import org.dromara.zhishu.domain.vo.MessageSubscribeVo;
import org.dromara.zhishu.domain.vo.ShopVo;
import org.dromara.zhishu.domain.vo.TaskVo;
import org.dromara.zhishu.mapper.TUserPlatformMapper;
import org.dromara.zhishu.service.*;
import org.dromara.zhishu.service.client.FileClient;
import org.dromara.zhishu.service.client.KfzClient;
import org.dromara.zhishu.service.client.PddClient;
import org.dromara.zhishu.service.impl.RunningTaskByShopServiceImpl;
import org.dromara.zhishu.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.AbstractView;
import org.springframework.web.servlet.view.RedirectView;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.dev33.satoken.SaManager.log;
import static org.dromara.zhishu.util.InterfaceUtils.getInterface;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/huidiao/pdd")
public class PddController {

    private final IPddService pddService;
    private final IShopService shopService;
    private final RuoYiConfig ruoYiConfig;
    private final ISysConfigService configService;
    private final TShopMessageSubscribeService tShopMessageSubscribeService;
    private final HttpServletRequest httpServletRequest;
    private final ITUserPlatformService userPlatformService;
    private final ITaskService taskService;
    private final IZhishuShopGoodsService zhishuShopGoodsService;
    private final IRunningTaskService runningTaskService;
    private final IRunningTaskByShopService runningTaskByShopService;
    private final PddClient pddClient;
    @Autowired
    private TUserPlatformMapper userPlatformMapper;
    @Autowired
    private KfzClient kfzClient;


    private final FileClient fileClient;


    // 授权页面url
    String url = "https://fuwu.pinduoduo.com/service-market/auth";
    String clientId = PddUtil.getClientId();
    String clientSecret = PddUtil.getClientSecret();
    // 回调url
    String redirectUri = "https://test.api.buzhiyushu.cn/huidiao/pdd";
    @Autowired
    private RunningTaskByShopServiceImpl runningTaskByShopServiceImpl;


    /**
     * 拼多多回调调用方法，获取code
     *
     * @param code
     * @param state 自定义参数，返回的是店铺id
     */
    @SaIgnore
    @GetMapping
    public ModelAndView getCode(String code, String state, HttpServletResponse response) {
        try {
            if (state == null) {
                state = "000000-2-null";
            }
            System.out.println("\n\n==================== 拼多多授权回调开始 ====================");
            System.out.println("拼多多授权回调开始处理 - code: " + code + ", state: " + state);

            // 记录请求头信息
            System.out.println("请求头信息:");
            Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                String headerValue = httpServletRequest.getHeader(headerName);
                System.out.println("  " + headerName + ": " + headerValue);
            }

            // 记录请求参数
            System.out.println("请求参数:");
            Enumeration<String> parameterNames = httpServletRequest.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String paramName = parameterNames.nextElement();
                String paramValue = httpServletRequest.getParameter(paramName);
                System.out.println("  " + paramName + ": " + paramValue);
            }

            String[] stateArr = state.split("-");
            state = stateArr[0];
            String type = stateArr[1];
            String userId = stateArr[2];
            System.out.println("解析state参数 - state: " + state + ", type: " + type);

            if (code == null || StringUtils.isEmpty(code)) {
                System.out.println("授权参数无效 - code: " + code + ", state: " + state);
                // 根据type参数决定跳转页面
                if ("2".equals(type)) {
                    return new ModelAndView(new RedirectView("https://erp.buzhiyushu.cn/login"));
                } else {
                    return new ModelAndView(new RedirectView("https://" + ruoYiConfig.getIpurl() + "/shop/shop"));
                }
            }

            if ("2".equals(type)) {
                System.out.println("开始处理用户注册流程");
                try {
                    String encodedCode = URLEncoder.encode(code, "UTF-8");
                    String redirectUrl = "https://erp.newadmin.buzhiyushu.cn/redirectUrl?code=" + encodedCode;
                    return new ModelAndView(new RedirectView(redirectUrl));

                } catch (Exception e) {
                    log.error("URL编码失败", e);
                    System.out.println("URL编码失败: " + e.getMessage());
                    // 如果编码失败，使用默认店铺名称
                    String encodedCode = URLEncoder.encode(code, "UTF-8");
                    String redirectUrl = "https://erp.newadmin.buzhiyushu.cn/redirectUrl?code=" + encodedCode;
                    System.out.println("使用默认店铺名称跳转: " + redirectUrl);

                    // 同样使用JavaScript跳转
                    String htmlContent = "<!DOCTYPE html>" +
                            "<html><head>" +
                            "<meta charset='UTF-8'>" +
                            "<meta name='viewport' content='width=device-width, initial-scale=1.0'>" +
                            "<title>正在跳转...</title>" +
                            "<style>" +
                            "body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background-color: #f5f5f5; }" +
                            ".loading { font-size: 18px; color: #666; margin-bottom: 20px; }" +
                            ".spinner { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 40px; height: 40px; animation: spin 2s linear infinite; margin: 20px auto; }" +
                            "@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }" +
                            "</style>" +
                            "</head><body>" +
                            "<div class='loading'>正在跳转到注册页面...</div>" +
                            "<div class='spinner'></div>" +
                            "<script>" +
                            "setTimeout(function() {" +
                            "  window.location.href = '" + redirectUrl + "';" +
                            "}, 1000);" +
                            "</script>" +
                            "</body></html>";

                    ModelAndView mav = new ModelAndView();
                    mav.setView(new AbstractView() {
                        @Override
                        protected void renderMergedOutputModel(Map<String, Object> model,
                                                               HttpServletRequest request, HttpServletResponse response) throws Exception {
                            response.setContentType("text/html;charset=UTF-8");
                            response.getWriter().write(htmlContent);
                            response.getWriter().flush();
                        }
                    });
                    return mav;
                }

            }

            String pddIp = configService.selectConfigByKey("pdd.ip");
            System.out.println("获取拼多多IP配置: " + pddIp);

            String accessTokenVoString = getInterface(pddIp, "/api/pdd/auth/getAccessToken/" + code);
            AccessTokenVo accessTokenVo = JSONObject.parseObject(accessTokenVoString, AccessTokenVo.class);
            String accessToken = accessTokenVo.getAccessToken();
            System.out.println("获取accessToken成功: " + accessToken);

            // 获取店铺信息
            Long id = 0L;
            if (StringUtils.isNotEmpty(state)) {
                id = Long.parseLong(state);
            }
            String pddMallInfoGetResponseStr = getInterface(pddIp, "/api/pdd/auth/getMallInfo/" + accessToken);

            PddMallInfoGetResponse pddMallInfoGetResponse = JsonUtils.parseObject(pddMallInfoGetResponseStr, PddMallInfoGetResponse.class);
            // 获取拼多多店铺ID和名称
            String pddMallId = String.valueOf(pddMallInfoGetResponse.getMallInfoGetResponse().getMallId());
            String pddMallName = pddMallInfoGetResponse.getMallInfoGetResponse().getMallName();
            System.out.println("获取店铺信息成功 - 店铺ID: " + pddMallId + ", 店铺名称: " + pddMallName);
            // 根据三方店铺id查询修改
            ShopVo shopVo = shopService.selectByMallId(pddMallId);
            if (shopVo != null) {
                ShopBo bo = new ShopBo();
                bo.setId(shopVo.getId());
                bo.setToken(accessToken);
                shopService.updateByBo(bo);
            }
            // 到期时间
            Date expirationTime;
            // 服务版本
            String skuSpec;
            // 获取店铺订阅服务
            String vasData = getInterface(pddIp, "/api/pdd/auth/getVasOrder?mallId=" + pddMallId);
            Map vasMap = JsonUtil.transferToObj(vasData, Map.class);
            if (vasMap.get("code").equals("200")) {
                // 成功 调用新后台
                Map vas = (Map) vasMap.get("data");
                System.out.println("获取订阅服务数据：" + JsonUtil.transferToJson(vas));
                vas = MapUtils.convertKeys(vas);
                System.out.println("转变格式：" + JsonUtil.transferToJson(vas));
                // 计算到期时间
                long payTime = Long.parseLong(vas.get("payTime").toString());
                long timeLength = Long.parseLong(vas.get("timeLength").toString());
                long newTimestamp = payTime + (timeLength * 1000);
                expirationTime = new Date(newTimestamp);

                skuSpec = vas.get("skuSpec").toString();
                try {
                    InterfaceUtils.getInterfacePost("https://newadmin.buzhiyushu.cn/", "/vas/addVas", vas);
                } catch (Exception e) {
                    System.out.println("调用新后台存储订阅服务信息失败");
                }


            } else if (vasMap.get("code").equals("401")) {
                // 未订阅服务的情况，直接跳转购买页
                return new ModelAndView(new RedirectView("https://fuwu.pinduoduo.com/service-market/service-detail?detailId=90559"));
            } else {
                String alertMessage = vasMap.get("msg").toString();
                String htmlContent = "<html><head><title>提示</title></head><body>"
                        + "<script>alert('" + alertMessage + "');</script>"
                        + "</body></html>";

                ModelAndView mav = new ModelAndView();
                mav.setView(new AbstractView() {
                    @Override
                    protected void renderMergedOutputModel(Map<String, Object> model,
                                                           HttpServletRequest request, HttpServletResponse response) throws Exception {
                        response.setContentType("text/html;charset=UTF-8");
                        response.getWriter().write(htmlContent);
                        response.getWriter().flush();
                    }
                });
                return mav;
            }

            if ("3".equals(type)) {
                // 添加拼多多店铺
                if (shopVo != null && !shopVo.getId().equals(id)) {
                    // 存在店铺
                    // 动态生成空白页并显示alert消息
                    String alertMessage = "您的拼多多店铺已绑定！！！";
                    String htmlContent = "<html><head><title>提示</title></head><body>"
                            + "<script>alert('" + alertMessage + "');</script>"
                            + "</body></html>";

                    ModelAndView mav = new ModelAndView();
                    mav.setView(new AbstractView() {
                        @Override
                        protected void renderMergedOutputModel(Map<String, Object> model,
                                                               HttpServletRequest request, HttpServletResponse response) throws Exception {
                            response.setContentType("text/html;charset=UTF-8");
                            response.getWriter().write(htmlContent);
                            response.getWriter().flush();
                        }
                    });
                    return mav;
                } else {
                    ShopBo shopBo = new ShopBo();
                    shopBo.setShopName(pddMallName);
                    shopBo.setToken(accessToken);
                    shopBo.setMallId(Long.valueOf(pddMallId));
                    shopBo.setShopAliasName(pddMallName);
                    shopBo.setShopAuthorize("1");
                    shopBo.setExpirationTime(expirationTime);
                    shopBo.setSkuSpec(skuSpec);
                    shopBo.setShopGroup("默认分组");
                    shopBo.setShopType("1");
                    shopBo.setAddTime(DateUtils.parseDate(DateUtils.getTime()));
                    shopBo.setCreateBy(Long.parseLong(userId));
                    shopBo.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
                    shopBo.setTenant_id("000000");
                    shopService.insertByBo(shopBo);
                    // 赋值id
                    id = shopBo.getId();
                    // 生成用户与店铺绑定关系
                    TUserPlatform userPlatform = new TUserPlatform();
                    userPlatform.setType("1"); // 拼多多
                    userPlatform.setUserId(Long.parseLong(userId));
                    userPlatform.setPlatformId(pddMallId);
                    userPlatform.setPlatformName(pddMallName);
                    userPlatform.setStatus("0");
                    userPlatform.setDelFlag("0");
                    userPlatform.setTenantId("000000");
                    userPlatform.setCreateBy(Long.parseLong(userId));
                    userPlatform.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
                    userPlatformService.insertTUserPlatform(userPlatform);
                }
            } else if ("4".equals(type)) {
                try {
                    System.out.println("调用新后台type" + type);
                    Map<String, String> params = new HashMap<>();
                    params.put("accessToken", accessToken);
                    params.put("pddMallId", pddMallId);
                    params.put("pddMallName", pddMallName);
                    InterfaceUtils.postForm("https://newadmin.buzhiyushu.cn/", "/shop/token", params);
                    ShopVo shopVo1 = shopService.selectByMallId(pddMallId);
                    if (shopVo1 != null) {
                        shopService.updateTokenByPddMallId(pddMallId, accessToken);
                    } else {
                        ShopBo shopBo = new ShopBo();
                        shopBo.setId(id);
                        shopBo.setMallId(Long.valueOf(pddMallId));
                        shopBo.setToken(accessToken);
                        shopBo.setShopAliasName(pddMallName);
                        shopBo.setShopAuthorize("1");
                        shopBo.setExpirationTime(expirationTime);
                        shopBo.setSkuSpec(skuSpec);
                        shopService.selectShopAssociationMall(shopBo);
                    }
                    return new ModelAndView(new RedirectView("https://erp.newadmin.buzhiyushu.cn/shop/list"));
                } catch (Exception e) {
                    System.out.println("调用新后台存储订阅服务信息失败");
                }
            } else if ("5".equals(type)) {

            } else {
                // 根据pddMallId查询是否存在相同数据
                if (shopVo != null && !shopVo.getId().equals(id)) {
                    // 动态生成空白页并显示alert消息
                    String alertMessage = "扫码的拼多多店铺与erp绑定的店铺信息不匹配！！！";
                    String htmlContent = "<html><head><title>提示</title></head><body>"
                            + "<script>alert('" + alertMessage + "');</script>"
                            + "</body></html>";

                    ModelAndView mav = new ModelAndView();
                    mav.setView(new AbstractView() {
                        @Override
                        protected void renderMergedOutputModel(Map<String, Object> model,
                                                               HttpServletRequest request, HttpServletResponse response) throws Exception {
                            response.setContentType("text/html;charset=UTF-8");
                            response.getWriter().write(htmlContent);
                            response.getWriter().flush();
                        }
                    });
                    return mav;
                } else {
                    ShopBo shopBo = new ShopBo();
                    shopBo.setId(id);
                    shopBo.setMallId(Long.valueOf(pddMallId));
                    shopBo.setToken(accessToken);
                    shopBo.setShopAliasName(pddMallName);
                    shopBo.setShopAuthorize("1");
                    shopBo.setExpirationTime(expirationTime);
                    shopBo.setSkuSpec(skuSpec);
                    shopService.selectShopAssociationMall(shopBo);
                }
            }

            // 处理订阅消息
            System.out.println("开始处理订阅消息");
            MessageSubscribeVo messageSubscribeVo = accessTokenVo.getMessageSubscribeVo();
            tShopMessageSubscribeService.insertOrUpdate(List.of(messageSubscribeVo), id);
            System.out.println("订阅消息处理完成");

            return new ModelAndView(new RedirectView("https://" + ruoYiConfig.getIpurl() + "/shop/shop"));

        } catch (Exception e) {
            log.error("拼多多授权回调处理失败", e);
            System.out.println("拼多多授权回调处理异常: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            System.out.println("==================== 拼多多授权回调结束 ====================\n\n");
        }
    }



    /**
     * 根据token授权店铺
     *
     * @param code 授权码 有效期10分钟
     */
    @SaIgnore
    @GetMapping("/tokenSq")
    public R<String> tokenSq(String code, HttpServletResponse response) {
        try {
            System.out.println("\n\n==================== 拼多多授权token码授权开始 ====================");
            Long userId = LoginHelper.getUserId();
            String pddIp = configService.selectConfigByKey("pdd.ip");
            System.out.println("获取拼多多IP配置: " + pddIp);
            // 获取店铺信息
            String accessTokenVoString = getInterface(pddIp, "/api/pdd/auth/getAccessToken/" + code);
            AccessTokenVo accessTokenVo = JSONObject.parseObject(accessTokenVoString, AccessTokenVo.class);
            String accessToken = accessTokenVo.getAccessToken();
            String pddMallInfoGetResponseStr = getInterface(pddIp, "/api/pdd/auth/getMallInfo/" + accessToken);
            PddMallInfoGetResponse pddMallInfoGetResponse = JsonUtils.parseObject(pddMallInfoGetResponseStr, PddMallInfoGetResponse.class);
            if(pddMallInfoGetResponse.getErrorResponse() != null){
                String subMsg = pddMallInfoGetResponse.getErrorResponse().getSubMsg();
                if(subMsg.equals("access_token已过期")){
                    return R.fail("授权码已过期");
                }else{
                    return R.fail(subMsg);
                }
            }
            // 获取拼多多店铺ID和名称
            String pddMallId = String.valueOf(pddMallInfoGetResponse.getMallInfoGetResponse().getMallId());
            String pddMallName = pddMallInfoGetResponse.getMallInfoGetResponse().getMallName();
            System.out.println("获取店铺信息成功 - 店铺ID: " + pddMallId + ", 店铺名称: " + pddMallName);
            // 到期时间
            Date expirationTime;
            // 服务版本
            String skuSpec;
            // 获取店铺订阅服务
            String vasData = getInterface(pddIp, "/api/pdd/auth/getVasOrder?mallId=" + pddMallId);
            Map vasMap = JsonUtil.transferToObj(vasData, Map.class);
            if (vasMap.get("code").equals("200")) {
                // 成功 调用新后台
                Map vas = (Map) vasMap.get("data");
                System.out.println("获取订阅服务数据：" + JsonUtil.transferToJson(vas));
                vas = MapUtils.convertKeys(vas);
                System.out.println("转变格式：" + JsonUtil.transferToJson(vas));
                // 计算到期时间
                long payTime = Long.parseLong(vas.get("payTime").toString());
                long timeLength = Long.parseLong(vas.get("timeLength").toString());
                long newTimestamp = payTime + (timeLength * 1000);
                expirationTime = new Date(newTimestamp);
                skuSpec = vas.get("skuSpec").toString();
                try {
                    InterfaceUtils.getInterfacePost("https://newadmin.buzhiyushu.cn/", "/vas/addVas", vas);
                } catch (Exception e) {
                    System.out.println("调用新后台存储订阅服务信息失败");
                }
            }else {
                return R.fail(vasMap.get("msg").toString());
            }
            // 根据三方店铺id查询修改
            ShopVo shopVo = shopService.selectByMallId(pddMallId);
            if (shopVo != null) {
                //判断是否绑定在自己账号下
                if(shopVo.getCreateBy().equals(userId)){
                    ShopBo bo = new ShopBo();
                    bo.setId(shopVo.getId());
                    bo.setToken(accessToken);
                    bo.setExpirationTime(expirationTime);
                    bo.setSkuSpec(skuSpec);
                    bo.setShopAuthorize("1");
                    bo.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
                    shopService.updateByBo(bo);
                }else{
                    ShopBo bo = new ShopBo();
                    bo.setId(shopVo.getId());
                    bo.setToken(accessToken);
                    shopService.updateByBo(bo);
                    return R.fail("店铺已被其他账户绑定");
                }
            }else{
                // 添加拼多多店铺
                ShopBo shopBo = new ShopBo();
                shopBo.setShopName(pddMallName);
                shopBo.setToken(accessToken);
                shopBo.setMallId(Long.valueOf(pddMallId));
                shopBo.setShopAliasName(pddMallName);
                shopBo.setShopAuthorize("1");
                shopBo.setExpirationTime(expirationTime);
                shopBo.setSkuSpec(skuSpec);
                shopBo.setShopGroup("默认分组");
                shopBo.setShopType("1");
                shopBo.setAddTime(DateUtils.parseDate(DateUtils.getTime()));
                shopBo.setCreateBy(userId);
                shopBo.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
                shopBo.setTenant_id("000000");
                shopService.insertByBo(shopBo);
                // 赋值id
                Long id = shopBo.getId();
                // 生成用户与店铺绑定关系
                TUserPlatform userPlatform = new TUserPlatform();
                userPlatform.setType("1"); // 拼多多
                userPlatform.setUserId(userId);
                userPlatform.setPlatformId(pddMallId);
                userPlatform.setPlatformName(pddMallName);
                userPlatform.setStatus("0");
                userPlatform.setDelFlag("0");
                userPlatform.setTenantId("000000");
                userPlatform.setCreateBy(userId);
                userPlatform.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
                userPlatformService.insertTUserPlatform(userPlatform);
                // 处理订阅消息
                System.out.println("开始处理订阅消息");
                tShopMessageSubscribeService.insertOrUpdate(List.of(accessTokenVo.getMessageSubscribeVo()), id);
                System.out.println("订阅消息处理完成");
            }
            return R.ok("授权成功");
        } catch (Exception e) {
           return R.fail("授权码无效");
        } finally {
            System.out.println("==================== 拼多多授权token码授权开始 ====================\n\n");
        }
    }

    @SaIgnore
    @GetMapping("/getPddToken")
    public R<PddTokenResponse> getPddToken(@NotBlank(message = "code不能为空") String code) {
        String pddIp = configService.selectConfigByKey("pdd.ip");
        System.out.println("获取拼多多IP配置: " + pddIp);

        String accessTokenVoString = getInterface(pddIp, "/api/pdd/auth/getAccessToken/" + code);
        AccessTokenVo accessTokenVo = JSONObject.parseObject(accessTokenVoString, AccessTokenVo.class);
        String accessToken = accessTokenVo.getAccessToken();
        System.out.println("获取accessToken成功: " + accessToken);

        String pddMallInfoGetResponseStr = getInterface(pddIp, "/api/pdd/auth/getMallInfo/" + accessToken);

        PddMallInfoGetResponse pddMallInfoGetResponse = JsonUtils.parseObject(pddMallInfoGetResponseStr, PddMallInfoGetResponse.class);
        // 获取拼多多店铺ID和名称
        String pddMallId = String.valueOf(pddMallInfoGetResponse.getMallInfoGetResponse().getMallId());
        String pddMallName = pddMallInfoGetResponse.getMallInfoGetResponse().getMallName();
        System.out.println("获取店铺信息成功 - 店铺ID: " + pddMallId + ", 店铺名称: " + pddMallName);
        // 根据三方店铺id查询修改
        ShopVo shopVo = shopService.selectByMallId(pddMallId);
        if (shopVo != null) {
            ShopBo bo = new ShopBo();
            bo.setId(shopVo.getId());
            bo.setToken(accessToken);
            shopService.updateByBo(bo);
            return R.fail("店铺已存在");
        }

        // 到期时间
        Date expirationTime;
        // 服务版本
        String skuSpec = "";
        // 获取店铺订阅服务
        String vasData = getInterface(pddIp, "/api/pdd/auth/getVasOrder?mallId=" + pddMallId);
        Map vasMap = JsonUtil.transferToObj(vasData, Map.class);
        if (vasMap.get("code").equals("200")) {
            // 成功 调用新后台
            Map vas = (Map) vasMap.get("data");
            System.out.println("获取订阅服务数据：" + JsonUtil.transferToJson(vas));
            vas = MapUtils.convertKeys(vas);
            System.out.println("转变格式：" + JsonUtil.transferToJson(vas));
            // 计算到期时间
            long payTime = Long.parseLong(vas.get("payTime").toString());
            long timeLength = Long.parseLong(vas.get("timeLength").toString());
            long newTimestamp = payTime + (timeLength * 1000);
            expirationTime = new Date(newTimestamp);

            skuSpec = vas.get("skuSpec").toString();
            try {
                InterfaceUtils.getInterfacePost("https://newadmin.buzhiyushu.cn/", "/vas/addVas", vas);
            } catch (Exception e) {
                System.out.println("调用新后台存储订阅服务信息失败");
            }
        }
        PddTokenResponse pddTokenResponse = new PddTokenResponse();
        pddTokenResponse.setAccessToken(accessToken);
        pddTokenResponse.setPddMallId(pddMallId);
        pddTokenResponse.setPddMallName(pddMallName);
        pddTokenResponse.setSkuSpec(skuSpec);
        return R.ok(pddTokenResponse);
    }


    /**
     * 前往拼多多授权登录页面
     *
     * @return
     */
//    @SaCheckPermission("zhishu:authorize:getCode")
    @GetMapping("/toPddGetCode")
    @SaIgnore
    public String toPddGetCode(String id, String type) {

        Long userId = LoginHelper.getUserId();

        if (StringUtils.isEmpty(id)) {
            type = "3";
        }

        String redirectUri = configService.selectConfigByKey("pdd.redirect.url");

        String authorizationUrl = url +
                "?response_type=code"
                + "&client_id=" + clientId +
                "&redirect_uri=" + redirectUri +
                "&state=" + id + "-" + type + "-" + userId;

        return authorizationUrl;
    }


    /**
     * 获取商品运费模版接口
     */
    @GetMapping("/getLogisticsTemplate/{shopId}")
    public List getLogisticsTemplate(@PathVariable Long shopId, HttpServletRequest request) {
        try {
            Map<String, String> headers = PddResultUtil.getPddHeaderMap(request);

            ShopVo shopVo = shopService.queryById(shopId);
            String pddIp = configService.selectConfigByKey("pdd.ip");
            String logisticsTemplateListStr = getInterface(pddIp, "/api/pdd/auth/getLogisticsTemplate/" + shopVo.getToken(), headers);
            List list = JsonUtils.parseObject(logisticsTemplateListStr, List.class);
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/getPageCode/{mallId}")
    public String getPageCode(@PathVariable("mallId") String mallId) {
        try {
            String pddIp = configService.selectConfigByKey("pdd.ip");
            return getInterface(pddIp, "/api/pdd/auth/getPageCode/" + mallId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 商品标准类目接口
     */
    @GetMapping("/getCats")
    public ArrayList<Map<String, Object>> getCats(HttpServletRequest request) {
        Map<String, String> headers = PddResultUtil.getPddHeaderMap(request);
        // 从文件中获取数据字符串
        Map<String, Object> map;
        ArrayList<Map<String, Object>> mapList = new ArrayList<>();
        String content = RedisUtils.getCacheObject("catsMapStr");
        if (content == null || StringUtils.isEmpty(content)) {
            String pddIp = configService.selectConfigByKey("pdd.ip");
            String catsMapStr = getInterface(pddIp, "/api/pdd/auth/getCats", headers);
            RedisUtils.setCacheObject("catsMapStr", catsMapStr);
        }
        map = JsonUtils.parseObject(content, Map.class);
        mapList.add(map);
        return mapList;
    }

    /**
     * 商品属性类目接口
     */
    @GetMapping("/getSpec/{shopId}")
    public List<PddGoodsSpecGetResponse.GoodsSpecGetResponseGoodsSpecListItem> getSpec(@PathVariable String shopId, HttpServletRequest request) throws Exception {
        Map<String, String> headers = PddResultUtil.getPddHeaderMap(request);
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        String pddIp = configService.selectConfigByKey("pdd.ip");
        String goodsSpecListStr = getInterface(pddIp, "/api/pdd/auth/getSpec/" + shopVo.getToken(), headers);
        return JsonUtils.parseObject(goodsSpecListStr, List.class);
    }


    /**
     * 从拼多多商铺获取商品信息
     */
    @PostMapping("/selPddShop")
    public PddGoodsListGetResponse selPddShop(@RequestBody PddShopInfo search) throws Exception {
        return this.pddGetGoods(search);
    }


    public PddGoodsListGetResponse pddGetGoods(PddShopInfo search) throws Exception {

        PopClient client = new PopHttpClient(clientId, clientSecret);
        PddGoodsListGetRequest request = new PddGoodsListGetRequest();
//        request.setCostTemplateId(1L); // 模版Id
//        request.setCreatedAtEnd(1654099200L); // 商品创建时间结束时间的时间戳
//        request.setCreatedAtFrom(1654012800L); // 商品创建时间开始时间的时间戳
        request.setGoodsName("中国"); // 商品名称模糊查询
        request.setIsOnsale(0);    // 上下架状态，0-下架，1-上架
//        request.setOuterGoodsId("1"); //商家外部商品编码，支持多个，用逗号隔开，最多10个
//        request.setOuterId("str"); // 	商品外部编码
        request.setPage(1); // 返回页码 默认 1
        request.setPageSize(10); // 返回数量，默认 100，最大100
        PddGoodsListGetResponse response = client.syncInvoke(request, PddUtil.getToken());
        System.out.println(JsonUtil.transferToJson(response));
        return response;
    }


    // 超时
    public void tokenCs() {
        // 获取所有已授权店铺的token
        List<String> shopIds = shopService.getShopId(LoginHelper.getUserId());
        for (String shopId : shopIds) {
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
            if (shopVo == null) {
                continue;
            }
            // 获取店铺的token
            String token = shopVo.getToken();
            // 获取店铺的授权过期时间
            Date expirationTime = shopVo.getExpirationTime();
            // 校验店铺过期时间是否超过当前时间
            if (expirationTime.getTime() < System.currentTimeMillis()) {
                // 店铺已过期，进行注销操作
                System.out.println("店铺授权已过期，进行超时操作");
                // 2代表授权已过期
                ShopBo shopBo = new ShopBo();
                shopBo.setId(shopVo.getId());
                shopBo.setStatus("2");
                shopService.updateByBo(shopBo);
            }
        }
    }

    // 更新
    public void updateShop(Long shopId) throws Exception {
        // 获取店铺信息
        ShopVo shopVo = shopService.queryById(shopId);
        // 获取刷新token
        String refreshToken = shopVo.getRefreshToken();
        String clientId = PddUtil.getClientId();
        String clientSecret = PddUtil.getClientSecret();

        PopClient client = new PopHttpClient(clientId, clientSecret);
        PddPopAuthTokenRefreshRequest request = new PddPopAuthTokenRefreshRequest();
        request.setRefreshToken(refreshToken);
        PddPopAuthTokenRefreshResponse response = client.syncInvoke(request);
        System.out.println(JsonUtil.transferToJson(response));

        // 获取刷新后的token，重新赋值给店铺
        String token = response.getPopAuthTokenRefreshResponse().getAccessToken();

        ShopBo shopBo = new ShopBo();
        shopBo.setId(shopVo.getId());
        shopBo.setToken(token);
        shopService.updateByBo(shopBo);
    }


    // 删除店铺处理
    public void deleteShop(Long shopId) {
        // 将店铺注销，并清空token
        ShopVo shopVo = shopService.queryById(shopId);
        ShopBo shopBo = new ShopBo();
        shopBo.setId(shopVo.getId());
        // 店铺注销，进行注销操作
        shopBo.setStatus("3");
        // 清空token 操作
        shopBo.setToken("0");
        shopService.updateByBo(shopBo);
    }

    @GetMapping("/getShopGoodsTotalNum")
    @SaIgnore
    public R<Integer> getShopGoodsTotalNum(String shopId, Integer isOnsale) {
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        String pddIp = configService.selectConfigByKey("pdd.ip");
        String url = "/api/pdd/auth/getShopGoodsList?" +
                "accessToken=" + shopVo.getToken();
        if (isOnsale != null) {
            url += "&isOnsale=" + isOnsale;
        }
        String dataStr = getInterface(pddIp, url + "&page=1&pageSize=100");
        Map dataMap = JsonUtil.transferToObj(dataStr, Map.class);
        Integer totalCount = dataMap.get("total_count") == null ? 0 : Integer.parseInt(dataMap.get("total_count").toString());
        return R.ok(totalCount);
    }

    @GetMapping("/createShopGoodsList")
    @SaIgnore
    public R<Void> createShopGoodsList(String shopId, Long createdAtFrom, Long createdAtEnd, Integer isOnsale, Integer sycFlag,String account, String password) {
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        // 判断是2-孔网店铺还是1-拼多多店铺
        String shopType = shopVo.getShopType();
        TaskBo taskBo = new TaskBo();
        // 存储任务信息
        if (Objects.equals(shopType, "1") || Objects.equals(shopType, "5")) {
            if (shopType.equals("5")){
                List<ShopVo> shopVoList = shopService.selectListByMallId(shopVo.getMallId());
                for (ShopVo shop : shopVoList){
                    // 根据shopId查询数据表是否存在
                    int checkMark = runningTaskByShopService.checkTableExists("t_running_task_" + shop.getId());
                    if (checkMark == 0) {
                        // 不存在则创建表
                        runningTaskByShopService.createTable("t_running_task_" + shop.getId());
                    }
                    runningTaskByShopService.deleteAll("t_running_task_"+shop.getId());
                }
            }
            taskBo.setTaskType("GET_SHOP_GOODS");
            taskBo.setFileName("拉取商品任务");
            Map createMap = new HashMap();
            createMap.put("shop_id",shopVo.getId().toString());
            createMap.put("shop_type",shopVo.getShopType());
            createMap.put("task_count","1");
            // 任务类型
            createMap.put("task_type","3");
            // img_type 必须传1
            createMap.put("img_type","1");
            String createResStr = InterfaceUtils.postFormWithSign(UrlUtil.getNewTaskUrl(),"/task/create",createMap);
            Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
            if (!createResMap.get("code").equals("200")){
                return R.fail(createResMap.get("msg").toString());
            }
            return R.ok("创建同步任务成功,请前往任务列表查看任务进度");
        }
        return R.fail("店铺类型错误");
    }

    /**
     * 继续执行拉取任务
     * @param shopId
     * @return
     */
    @GetMapping("/continueGetGoodsTask")
    @SaIgnore
    public R<Void> continueGetGoodsTask(String taskId,String shopId){
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        String shopType = shopVo.getShopType();
        if (Objects.equals(shopType, "1")) {
            TaskVo taskVo = taskService.queryById(Long.parseLong(taskId));
            String tableName = "t_running_task_" + shopId;
            String lastFinishTimeStr = runningTaskByShopService.selectLastFinishTime(tableName);


            for (int i = 0; i < 10; i++){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    System.out.println("休息异常");
                }
                String lastFinishTimeStrMark = runningTaskByShopService.selectLastFinishTime(tableName);
                if (StringUtils.isEmpty(lastFinishTimeStr) || StringUtils.isEmpty(lastFinishTimeStrMark)){
                    return R.fail("任务已经执行完毕");
                }
                if(!lastFinishTimeStr.equals(lastFinishTimeStrMark)){
                    return R.fail("任务正在运行中");
                }
            }

            // 时间格式转换
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                // 将字符串时间转换为Date对象
                Date lastFinishTime = sdf.parse(lastFinishTimeStr);
                // 获取秒级时间戳
                long lastFinishTimestamp = lastFinishTime.getTime() / 1000;

                // 计算一个月后的时间
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(lastFinishTime);
                calendar.add(Calendar.DATE, 29); // 增加29天
                Date oneMonthLater = calendar.getTime();
                // 获取一个月后的秒级时间戳
                long oneMonthLaterTimestamp = oneMonthLater.getTime() / 1000;
                // 获取当前时间的秒级时间戳
                long currentTimestamp = System.currentTimeMillis() / 1000;

                // 如果一个月后的时间大于当前时间，则使用当前时间作为结束时间
                long endTimestamp = oneMonthLaterTimestamp;
                if (oneMonthLaterTimestamp > currentTimestamp) {
                    endTimestamp = currentTimestamp;
                }

                String startTime = String.valueOf(lastFinishTimestamp);
                String endTime = String.valueOf(endTimestamp);

                Map<String, String> mapData = new HashMap();
                mapData.put("taskId", taskId);
                mapData.put("shopId", shopId);
                mapData.put("shopType", shopVo.getShopType());
                mapData.put("token", shopVo.getToken());
//                mapData.put("isOnsale", isOnsale == null ? "" : isOnsale.toString());
                if(taskVo.getFileName().contains("详细")){
                    mapData.put("taskType", "2");
                }else{
                    mapData.put("taskType", "1");
                }
                mapData.put("startTime", startTime);
                mapData.put("endTime", endTime);
                mapData.put("serviceName","GET_SHOP_GOODS");
                // 调用接口
                InterfaceUtils.postForm(UrlUtil.getShopGoodsTaskUrl(), "/task/verifyPricePublishGoods", mapData);
//                InterfaceUtils.postForm("http://localhost:18099", "/task/verifyPricePublishGoods", mapData);
            } catch (ParseException e) {
                // 时间解析异常处理
                e.printStackTrace();
                return R.fail("时间格式解析错误");
            }
            return R.ok("任务继续");
        }else{
            return R.ok("目前只支持拼多多店铺");
        }
    }

    @GetMapping("/createTask")
    @SaIgnore
    public R<String> createTask (String shopId){
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        // 判断是2-孔网店铺还是1-拼多多店铺
        String shopType = shopVo.getShopType();
        TaskBo taskBo = new TaskBo();
        taskBo.setTaskType("GET_KW_SHOP_GOODS");
        taskBo.setFileName("拉取孔网商品任务");
        taskBo.setShopIds(shopId);
        taskBo.setShopNames(shopVo.getShopName());
        taskBo.setDataNum(0L);
        taskBo.setTaskStatus("0");
        taskBo.setCreateBy(shopVo.getCreateBy());
        taskService.insertByBo(taskBo);
      return R.ok("true", taskBo.getId().toString());
    }


    @SaCheckPermission("zhishu:pddGoods:tongbu")
    @GetMapping("/createShopGoodsDetailList")
    @SaIgnore
    public R<Void> createShopGoodsDetailList(String shopId, Long createdAtFrom, Long createdAtEnd, Integer isOnsale) {
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        Map createMap = new HashMap();
        createMap.put("shop_id",shopVo.getId().toString());
        createMap.put("shop_type",shopVo.getShopType());
        createMap.put("task_count","1");
        // 任务类型
        createMap.put("task_type","4");
        // img_type 必须传1
        createMap.put("img_type","1");
        String createResStr = InterfaceUtils.postFormWithSign(UrlUtil.getNewTaskUrl(),"/task/create",createMap);
        Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
        if (!createResMap.get("code").equals("200")){
            return R.fail(createResMap.get("msg").toString());
        }
        return R.ok("创建同步任务成功,请前往任务列表查看任务进度");
    }


    @GetMapping("/createShopGoodsmovie")
    @SaIgnore
    public R<Void> createShopGoodsmovie(String shopId, Long createdAtFrom, Long createdAtEnd, Integer isOnsale,String targetShopIds) {
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        TaskBo taskBo = new TaskBo();
        // 存储任务信息
        taskBo.setTaskType("GET_MOVE_GOODS");
        taskBo.setFileName("拼多多店铺搬家");
        taskBo.setShopIds(shopId);
        taskBo.setShopNames(shopVo.getShopName());
        taskBo.setDataNum(0L);
        taskBo.setTaskStatus("0");
        taskService.insertByBo(taskBo);

        // 异步执行任务
        ThreadPoolUtils.execute(() -> {
            pddService.sendPddGoodsToTargetShop(shopId, targetShopIds,taskBo,shopVo);
        });


        return R.ok("创建同步任务成功,请前往任务列表查看任务进度");
    }




    @GetMapping("/getShopGoodsList")
    @SaIgnore
    public TableDataInfo<Map<String, Object>> getShopGoodsList(String shopId, String isOnsale,String isbn,
                                                               String priceDown,String priceUp,String startDate,
                                                               String endDate, Integer page, Integer pageSize,
                                                               String goodsName,String stockDown,String stockUp,String trilateralId,String goodsCode,String skuCode) {
        return pddService.getShopGoodsList(shopId, isOnsale,isbn,priceDown,priceUp,startDate,endDate, page, pageSize,goodsName,stockDown,stockUp, trilateralId, goodsCode, skuCode);
    }

    @GetMapping("/delShopGoods")
    public R<Void> delShopGoods(String shopId, String isOnsale,String isbn,String priceDown,String priceUp,String startDate,String endDate){
        String shopName = "";
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        shopName = shopVo.getShopName();

        //任务列表中添加删除操作记录

        TaskBo taskBo = new TaskBo();
        //存储任务信息
        taskBo.setTaskType("DEL");
        taskBo.setFileName("删除店铺商品列表");
        taskBo.setShopIds(shopId);
        taskBo.setShopNames(shopName);
        taskBo.setDataNum(runningTaskByShopServiceImpl.countAll("t_running_task_" + shopId).longValue());
        taskBo.setTaskStatus("3");
        taskService.insertByBo(taskBo);

        pddService.clearRedisBuffer(shopId);

        runningTaskByShopServiceImpl.delShopGoods("t_running_task_" + shopId, isOnsale,isbn,priceDown,priceUp,startDate,endDate);
        return R.ok();
    }


    /**
     * 导出商品列表
     *
     * @param
     * @param
     * @param response
     */
    @PostMapping("/emportShopGoods")
    @SaIgnore
    public void emportShopGoods(ErpGoodsDto erpGoodsDto, HttpServletResponse response) {
        erpGoodsDto.setTableName("t_running_task_" + erpGoodsDto.getShopId());
        List<SuccessDataItemDto> list = runningTaskByShopServiceImpl.selectShopGoodsList(erpGoodsDto);
        ExcelUtil.exportExcel(list, "sheet", SuccessDataItemDto.class, response);
    }

    /**
     * 孔夫子专用导出商品列表
     * @param erpGoodsDto
     * @param response
     */
    @PostMapping("/emportKfzShopGoods")
    @SaIgnore
    public void emportKfzShopGoods(ErpGoodsDto erpGoodsDto, HttpServletResponse response) {
        erpGoodsDto.setTableName("t_running_task_" + erpGoodsDto.getShopId());
        List<SuccessDataKfz> list = runningTaskByShopServiceImpl.selectKfzShopGoodsList(erpGoodsDto);
        ExcelUtil.exportExcel(list, "sheet", SuccessDataKfz.class, response);
    }


    @GetMapping("/checkFile")
    public Boolean checkFile(String shopId) {
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));

        int numMark = 0;

        String filePath = "ShopGoodsDataCSV/" + shopVo.getMallId() + "/" + numMark + ".csv";
        // 通过FileClient获取文件内容（Base64格式）
        R<String> dataResult = fileClient.get(UrlUtil.getFileServiceUrl(), filePath, "base64");

        return R.isSuccess(dataResult);
    }

    /**
     * 一键上下架功能
     */
    @PostMapping("/editShopGoodsAllByIsOnSale")
    public R<Void> editShopGoodsAllByIsOnSale(String shopId, String isOnSale, String isbn, String priceDown, String priceUp, String startDate, String endDate,String goodsName,String stockDown,String stockUp,String trilateralId,String goodsCode,String skuCode) {
        String[] shopIds = shopId.split(",");
        List<String> errorMessages = new ArrayList<>();
        List<String> successMessages = new ArrayList<>();
        for (String shopIdStr : shopIds) {
            try {
                // 获取店铺信息
                ShopVo shopVo = shopService.queryById(Long.parseLong(shopIdStr));
                if (shopVo == null) {
                    errorMessages.add("店铺" + shopIdStr + "不存在");
                    continue;
                }

                int num = runningTaskByShopService.checkTableExists("t_running_task_" + shopIdStr);
                String isOnsaleStr = isOnSale.equals("0") ? "下架" : "上架";
                // 检查表是否存在
                if (num == 0) {
                    errorMessages.add("店铺" + shopIdStr + "请先同步店铺商品");
                    continue;
                }

                if (!shopVo.equals("1")){
                    // 检查是否存在正在进行的任务
                    Long markNum = runningTaskService.selectTaskStatusByTaskTypeAndIsbn(Long.parseLong(shopIdStr), "EDIT_ISONSALE_GOODS", isbn);
                    if (markNum > 0) {
                        errorMessages.add("店铺" + shopIdStr + "正在执行商品上下架操作，请稍后再试");
                        continue;
                    }
                }

                // 检查符合条件的商品数量
                int count = runningTaskByShopService.selectGetShopGoodsListCount("t_running_task_" + shopIdStr, isOnSale.equals("0") ? "1" : "0", isbn, priceDown, priceUp, startDate, endDate,goodsName,stockDown,stockUp,trilateralId,goodsCode,skuCode);
                if (count == 0) {
                    errorMessages.add("店铺" + shopIdStr + "没有符合条件的商品");
                    continue;
                }
                // 创建任务
                TaskBo taskBo = new TaskBo();
                // 拼多多执行新任务
                Map createMap = new HashMap();
                createMap.put("shop_id",shopVo.getId().toString());
                createMap.put("shop_type",shopVo.getShopType());
                createMap.put("task_count",count+"");
                createMap.put("task_type","5");
                createMap.put("img_type","1");
                String createResStr = InterfaceUtils.postFormWithSign(UrlUtil.getNewTaskUrl(),"/task/create",createMap);
                Map createResMap = JsonUtil.transferToObj(createResStr,Map.class);
                if (createResMap.get("code").equals("500")){
                    errorMessages.add("店铺" + shopIdStr + "创建任务异常："+createResMap.get("msg").toString());
                    continue;
                }else{
                    taskBo.setId(Long.parseLong(createResMap.get("data").toString()));
                }

                // 异步执行任务
                new Thread(() -> {
                    pddService.editShopGoodsAllByIsOnSale(shopVo, taskBo, isOnSale, isbn, priceDown, priceUp, startDate, endDate, goodsName, stockDown, stockUp, trilateralId, goodsCode, skuCode);
                }).start();
                successMessages.add("店铺" + shopIdStr + "(" + shopVo.getShopName() + ")创建" + isOnsaleStr + "任务成功");
            } catch (Exception e) {
                errorMessages.add("店铺" + shopIdStr + "处理异常: " + e.getMessage());
                log.error("处理店铺{}时发生异常", shopIdStr, e);
            }
        }
            // if (!skipMessages.isEmpty()) {
        //     if (resultMessage.length() > 0) resultMessage.append("\n");
        //     resultMessage.append("跳过处理：").append(String.join("；", skipMessages)).append("。");
        // }
        // if (!errorMessages.isEmpty()) {
        //     if (resultMessage.length() > 0) resultMessage.append("\n");
        //     resultMessage.append("处理失败：").append(String.join("；", errorMessages)).append("。");
        // }

        // if (successMessages.isEmpty() && skipMessages.isEmpty()) {
        //     return R.fail(resultMessage.toString());
        // }

        if(!errorMessages.isEmpty()){
            errorMessages.addAll(successMessages);
            return R.fail(errorMessages.toString());
        }

        return R.ok(successMessages.toString());
    }

    /**
     * 获取商品核价文件下载链接
     */
    @SaIgnore
    @GetMapping("/getVerifyPriceUrl")
    public R<String> getVerifyPriceUrl(String shopId) {
        StringBuilder allContent = new StringBuilder();

        String[] shopIds = shopId.split(",");
        for (String shopIdStr : shopIds){
            ShopVo shopVo = shopService.queryById(Long.parseLong(shopIdStr));

            if (shopVo == null) {
                return R.fail("店铺不存在");
            }

            String filePath = "task_log/goods-list-csv/" + shopIdStr + "/online_goods.csv";
            // 通过FileClient获取文件内容（url格式）
            R<String> dataResult=   dataResult= fileClient.get(UrlUtil.getFileServiceUrl(), filePath, "url");
            if (dataResult.isSuccess(dataResult) && dataResult.getData() != null) {
                allContent.append(dataResult.getData()).append("\n");
            }
        }

        return R.ok(allContent.toString());

        // 通过FileClient获取文件内容（url格式）

        //
        // if (R.isSuccess(dataResult)) {
        //     return R.ok("true", dataResult.getData());
        // } else {
        //     return R.fail("未查询到店铺商品，请重新同步后再试");
        // }
    }

    /**
     * 修改店铺商品CSV表格价格
     *
     * @param request 修改商品价格请求参数
     * @return 修改成功状态
     */
    @SaIgnore
    @PostMapping("/updateShopGoodsDataPriceCSV")
    public R<Boolean> updateShopGoodsDataPriceCSV(@Validated @RequestBody UpdateShopGoodsDataPriceCSVRequest request) {
        // 1. 构建文件路径
        String filePath = "ShopGoodsDataCSV/" + request.getMallId() + ".csv";

        // 2. 获取CSV文件内容
        R<String> dataResult = fileClient.get(UrlUtil.getFileServiceUrl(), filePath, "base64");
        if (!R.isSuccess(dataResult)) {
            throw new ServiceException("获取文件失败");
        }

        // 3. 解码Base64并读取CSV内容
        byte[] decodedBytes = Base64.getDecoder().decode(dataResult.getData());
        String csvContent = new String(decodedBytes, StandardCharsets.UTF_8);

        // 4. 将请求中的商品列表转换为Map以便快速查找(key: platformId, value: SkuItem)
        Map<Long, UpdateShopGoodsDataPriceCSVRequest.SkuItem> skuItemMap = request.getSkuItemList().stream()
                .collect(Collectors.toMap(
                        UpdateShopGoodsDataPriceCSVRequest.SkuItem::getPlatformId,
                        Function.identity()
                ));

        try (StringReader stringReader = new StringReader(csvContent);
             CSVReader reader = new CSVReader(stringReader);
             StringWriter writer = new StringWriter();
             CSVWriter csvWriter = new CSVWriter(writer)) {

            // 5. 读取CSV表头
            String[] header = reader.readNext();
            if (header == null) {
                throw new ServiceException("CSV文件格式错误，缺少表头");
            }

            // 6. 查找关键列索引
            int goodsIdIndex = -1;
            int isOnsaleIndex = -1;
            int priceIndex = -1;
            for (int i = 0; i < header.length; i++) {
                switch (header[i]) {
                    case "goods_id":
                        goodsIdIndex = i;
                        break;
                    case "is_onsale":
                        isOnsaleIndex = i;
                        break;
                    case "price":
                        priceIndex = i;
                        break;
                }
            }

            if (goodsIdIndex == -1) {
                throw new ServiceException("CSV文件缺少goods_id列");
            }

            // 7. 写入表头
            csvWriter.writeNext(header);

            // 8. 处理每一行数据
            String[] row;
            while ((row = reader.readNext()) != null) {
                try {
                    Long goodsId = Long.parseLong(row[goodsIdIndex]);

                    // 检查当前商品是否需要修改
                    if (skuItemMap.containsKey(goodsId)) {
                        UpdateShopGoodsDataPriceCSVRequest.SkuItem skuItem = skuItemMap.get(goodsId);

                        // 修改is_onsale字段
                        if (request.getIsOnSale() != null && isOnsaleIndex != -1) {
                            row[isOnsaleIndex] = request.getIsOnSale().toString();
                        }

                        // 修改price字段
                        if (skuItem.getGroupPrice() != null && priceIndex != -1) {
                            row[priceIndex] = skuItem.getGroupPrice().toString();
                        }
                    }

                    // 写入处理后的行
                    csvWriter.writeNext(row);
                } catch (NumberFormatException e) {
                    log.error("解析goods_id失败，行内容: {}", Arrays.toString(row), e);
                    csvWriter.writeNext(row); // 解析失败时保留原行
                }
            }

            // 9. 生成新的CSV内容并编码为Base64
            String newCsvContent = writer.toString();
            String newBase64Content = Base64.getEncoder().encodeToString(newCsvContent.getBytes(StandardCharsets.UTF_8));

            // 10. 上传修改后的文件
            R<String> uploadResult = fileClient.upload(UrlUtil.getFileServiceUrl(), newBase64Content, "ShopGoodsDataCSV", request.getMallId() + ".csv");
            if (!R.isSuccess(uploadResult)) {
                throw new ServiceException("更新文件失败");
            }

            return R.ok(true);
        } catch (Exception e) {
            log.error("处理CSV文件失败", e);
            throw new ServiceException("处理CSV文件失败:" + e.getMessage());
        }
    }

    /**
     * 批量设置商品下架
     *
     * @return 批量设置成功状态
     */
    @SaIgnore
    @PostMapping("/batchSetSoldOut/{shopId}")
    public R<Boolean> batchSetSoldOut(@PathVariable("shopId") Long shopId) {
        pddService.batchSetSoldOut(shopId);
        return R.ok(true);
    }

    // 批次大小
    private static final int BATCH_SIZE = 1000;
    // 每个批次最大线程数
    private static final int MAX_THREADS_PER_BATCH = 10;

    /**
     * 通过csv批量翻新商品上架拼多多
     *
     * @param file   文件
     * @param shopId 店铺ID
     * @return 响应
     */
    @SaIgnore
    @PostMapping("/batchRenovateOnSaleByCsv")
    public R<Boolean> batchRenovateOnSaleByCsv(@RequestParam("file") MultipartFile file, @NotBlank(message = "店铺Id不能为空") String shopId) {
        // 判断是否上传了file文件
        if (file == null || file.isEmpty()) {
            return R.fail("请上传文件");
        }
        // 判断是否是csv文件
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".csv")) {
            return R.fail("请上传CSV格式的文件");
        }
        // 根据店铺查询店铺名称及token
        ShopVo shopVo = shopService.queryById(Long.parseLong(shopId));
        if (shopVo == null) {
            return R.fail("店铺不存在");
        }

        // 获取总条数
        Long totalCount = getCsvFileTotalCount(file);

        // 创建任务
        TaskBo taskBo = new TaskBo();
        // 存储任务信息
        taskBo.setTaskType("1");
        taskBo.setFileName("excel表格上传:批量翻新商品上架");
        taskBo.setShopIds(shopId);
        taskBo.setShopNames(shopVo.getShopName());
        taskBo.setDataNum(totalCount);
        taskBo.setTaskStatus("0");
        taskService.insertByBo(taskBo);

        // 调用方法异步处理文件数据
        pddService.batchRenovateOnSaleByCsv(file, taskBo, shopVo);

        return R.ok("已受理", true);
    }

    // 使用 OpenCsv 获取文件总条数
    private Long getCsvFileTotalCount(MultipartFile file) {
        long totalCount = 0;
        try (Reader reader = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8)) {
            // OpenCSV 方式读取 CSV
            CSVReader csvReader = new CSVReaderBuilder(reader)
                    .withSkipLines(0) // 不跳过任何行（默认）
                    .build();

            // 遍历所有行并计数（不加载到内存）
            while (csvReader.readNext() != null) {
                totalCount++;
            }

            // 如果文件有 header，需要减 1
            if (totalCount > 0) {
                totalCount--; // 去掉 header 行
            }
        } catch (IOException e) {
            throw new ServiceException("读取CSV文件失败：" + e.getMessage());
        } catch (CsvValidationException e) {
            throw new ServiceException("CSV格式验证失败：" + e.getMessage());
        }
        return totalCount;
    }

    /**
     * 翻新单个商品上架拼多多
     *
     * @return 响应
     */
    @SaIgnore
    @PostMapping("/renovateOnSale")
    public R<Boolean> renovateOnSale(@RequestBody RenovateOnSaleRequest request) {
        pddService.renovateOnSale(request.getData(), request.getShopId(), request.getTaskId());
        return R.ok(Boolean.TRUE);
    }


    /**
     * 检查店铺价格模板
     * @param shopId 店铺ID
     * @return 价格模板信息
     */
    @GetMapping("/checkPriceTemplate")
    public ResponseEntity<Map<Long, String>> checkPriceTemplate(@RequestParam List<Long> shopId) {
        Map<Long, String> result = new HashMap<>();

        for (Long shopIdstr : shopId) {
            String saleTemplateId = pddService.getSaleTemplateIdByShopId(shopIdstr);
            result.put(shopIdstr, saleTemplateId);
        }

        return ResponseEntity.ok(result);
    }

    /**
     * 获取商品核价文件下载链接
     */
    @SaIgnore
    @GetMapping("/getPddChildrenBooksToken")
    public JSONObject getPddChildrenBooksToken() {
        JSONObject jsonObject = new JSONObject();
        String mailId = configService.selectConfigByKey("pdd_children_books_shopId");
        String pddIp = configService.selectConfigByKey("pdd.ip");
        ShopVo shopVo =  shopService.queryByMailIdbyUseing(Long.parseLong(mailId),1);
           if (shopVo==null){
               jsonObject.put("code", 500);
               jsonObject.put("msg", "token已过期");
               return jsonObject;
           }
        //验证token是否过期
        String pddMallInfoGetResponseStr = getInterface(pddIp, "/api/pdd/auth/getMallInfo/" +   shopVo.getToken());
        PddMallInfoGetResponse pddMallInfoGetResponse = JsonUtils.parseObject(pddMallInfoGetResponseStr, PddMallInfoGetResponse.class);
        // 先检查主对象是否为null
        if (pddMallInfoGetResponse == null) {
            jsonObject.put("code", 500);
            jsonObject.put("msg", "解析响应数据失败");
            return jsonObject;
        }
        if(pddMallInfoGetResponse.getErrorResponse()!=null){
            jsonObject.put("code", 500);
            jsonObject.put("msg", pddMallInfoGetResponse.getErrorResponse().getErrorMsg());
            return jsonObject;
        }
        jsonObject.put("code", 200);
        jsonObject.put("data", shopVo.getToken());
        jsonObject.put("msg", "获取成功");
        // 获取拼多多店铺ID和名称
        return jsonObject;
    }



    @GetMapping("/getToken")
    @SaIgnore
    public String getToken(){
        return configService.selectConfigByKey("image.token");
    }

}
