var repeatData = [];
var successUrls = [];
var failUrls = [];
var failReasons = []
var urls;
var isNeedWait = false;
var supportPlatforms = [1, 2, 3, 4, 14, 5, 6, 7, 10, 11, 12, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35, 32, 36, 39, 38, 41, 42, 43,44];//支持批量采集的平台

//配置版本号
$.getJSON('../manifest.json', function (data) {
    $("#label-version").text("V" + data.version);
})

//初始化暂停时间
$("#stopTime").val(window.localStorage.getItem("stopTime") ? window.localStorage.getItem("stopTime") : 0);

// 进度条
function setProgress(rate) {
    var s = (rate * 100).toFixed(2) + '%';
    var progressbar = $('#progressbar');
    progressbar.attr('data-precent', s);
    progressbar.find('div').attr('style', 'width:' + s);
}

//本地保存输入的暂停间隔
$("#stopTime").on("input", function () {
    $(this).val($(this).val().replace(/-/g, ""));
    window.localStorage.setItem('stopTime', $(this).val());
});

function getPDDCookies(url, resolve) {
    chrome.cookies.getAll({
        url: url,
    }, function (cookies) {
        var token = cookies.find(item => item.name === 'PDDAccessToken');
        var userId = cookies.find(item => item.name === 'pdd_user_id');
        resolve({'accessToken': token ? token.value : '', 'userId': userId ? userId.value : ''});
    });
}

function getPddRequest(url, callback) {
    var origin = new URL(url).origin;
    getPDDCookies(origin + '/', cookie => {
        callback(origin, cookie)
    });
}

var pddInfo = {
    event: handlePddEv,
    addressInfo: {
        intval: 0,
    },
    expressInfo: {
        intval: 0,
    },
    couponInfo: {
        intval: 0
    },
    personal: {
        data: {}
    },
    orderList: {
        tabId: null,
        closeTab: function (tabId) {
            tabId && chrome.windows.remove(tabId);
        }
    }
}
var handlePddEv = {
    registry: {},

    on: function (k, v) {
        this.registry[k] = v;
    },
    trigger: function (k) {
        var args = [];
        for (var i = 1; i < arguments.length; i++) {
            args.push(arguments[i]);
        }
        return this.registry[k] && this.registry[k].apply(this.registry[k], args);
    }
};

var controller;
// '开始采集'事件
$("#urlCollectBtn").click(function () {
    urls = [];
    repeatData = [];
    successUrls = [];
    failUrls = [];
    failReasons = [];
    isNeedWait = false;
    if ($('#urlCollect').val() === '') {
        errorTip('采集地址为空，请填写采集的URL地址。');
        return;
    } else addCollectResults()

    $('.div-repeat').show();
    $('.successNum').text(0);
    $('.errorNum').text(0);
    $('.repeatNum').text(0);
    $('.copyText').text('')
    $('.wyys-main-link').html('');

    removeErrorStyle()   // 移除错误提示
    $('tbody').html('') // 移除表格内容
    setProgress(0)      //清空进度条

    urls = $('#urlCollect').val().split('\n').map(x => x.trim()).filter(x => x);
    urls = Array.from(new Set(urls))//去重

    console.log('当前总数量1：' + urls.length);
    VerifyVersion(//检验版本
        function () {
            VerifyLogin(//验证是否登录
                function () {
                    controller = newSyncExecute(urls, true, () => {
                        // 采集重复处理
                        if (repeatData.length > 0) {
                            removeCollectResults();
                            addRepeatDataTable();
                            $("#selectAll").prop("checked", false);
                            var tbody = $('tbody');
                            tbody.html('')
                            $.each(repeatData, function (index, item) {
                                var tr = $('<tr>');
                                tr.append($('<td>').append($('<input>').attr('type', 'checkbox').attr('data-id', item.CollectBoxId).addClass('select').click(select)));
                                tr.append($('<td>').append($('<img class="imgStyle">').attr('src', item.ImageUrl ? item.ImageUrl.split('|')[0] : "")));
                                tr.append($('<td>').text(item.Title));
                                /*tr.append($('<td>').text(item.CollectBoxVariants[0].Price));*/
                                tbody.append(tr);
                            });
                        }
                        failToCopy();
                        collectionResNum();
                    });
                },
                function () {
                    removeCollectResults()
                    ShowRedirectSiteBox('当前无登录用户，请先前往https://sczfai.com/进行登录！', 'warning', config.url.domain())
                }
            );
        },
        function (latestVersion, latestUrl) {
            ShowRedirectSiteBox("检测到最新插件版本为" + latestVersion + "，请先前往" + "https://www.51selling.com/HelpDocument/ShowHelpDocument/8" + "升级最新版本！给您带来的不便，敬请谅解！", 'warning', config.url.domain() + 'HelpDocument/ShowHelpDocument/8')
        }
    );

});

// 采集调度处理器
const AcquisitionDispatchHandlers = {
    GetDocumentCookies: (data, t3) => {
        t3(null);
    },
    GetAjaxResult: (data, t3) => {
        $.ajax({
            type: data.RequestMethod,
            headers: data.RequestHeaders,
            xhrFields: { withCredentials: true },
            url: data.RequestUrl,
            async: false,
            contentType: data.RequestContentType,
            dataType: data.RequestDataType,
            data: data.RequestData,
            success: response => t3({ IsSuccess: true, Data: response }),
            error: jqXHR => t3({ IsSuccess: false, Data: jqXHR })
        });
    },
    GetOnbuyVariationsInfo: (data, t3) => {
        let skuFirstImage = '';
        let price = 0;
        try {
            const dom = new DOMParser();
            const imageDoc = dom.parseFromString(data.HtmlStr, 'text/html');
            const imagesElement = imageDoc.querySelector("#image-gallery").querySelectorAll("a");
            skuFirstImage = imagesElement[0].attributes["href"].value;
            const priceString = imageDoc.querySelector(".q-p").querySelector(".price").innerText;
            price = parseFloat(priceString.replace(/[^\d.]/g, ''));
        } catch (e) { }
        t3({ SkuFirstImage: skuFirstImage, Price: price });
    },
    GetOnbuyProductInfo: (data, t3) => {
        let desc = '', title = '', categoryId = '', categoryName = '', productId = '';
        let skus = [], parameters = [], imageList = [], propertyNames = [];
        let price = 0, hasMoreSku = false;

        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(data.HtmlStr, 'text/html');
            title = doc.querySelectorAll(".product-name")[0].innerHTML;
            desc = doc.querySelector("#product-description").outerHTML;
            const topModel = JSON.parse(doc.querySelector(".top-info").querySelector('script').textContent);
            const divElement = doc.createElement('div');
            divElement.innerHTML = topModel.itemListElement[topModel.itemListElement.length - 2].name;
            categoryName = divElement.textContent;

            if (doc.querySelector(".product-features")) {
                doc.querySelector(".product-features").querySelectorAll("li").forEach(element => {
                    const match = element.textContent.trim().match(/(.+):(.+)/);
                    if (match) {
                        const key = match[1].trim(), value = match[2].trim();
                        if (!parameters.some(z => z.Key == key)) parameters.push({ Key: key, Value: value });
                    }
                });
            }

            categoryId = doc.querySelector(".product-code").attributes["data-category_id"].value;
            price = parseFloat(doc.querySelector(".q-p").querySelector(".price").innerText.replace(/[^\d.]/g, ''));
            doc.querySelector("#image-gallery").querySelectorAll("a").forEach(element => imageList.push(element.attributes["href"].value));

            if (doc.querySelector(".product-options div")) {
                hasMoreSku = true;
                productId = doc.querySelector(".product-options").attributes["data-product_id"].value;
                const attributes = doc.querySelector(".product-options").querySelectorAll("div");
                const properties = [];
                attributes.forEach(element => {
                    const name = element.querySelector("label").textContent;
                    propertyNames.push(name.replace(":", ""));
                    const options = element.querySelector("select").querySelectorAll("option");
                    const values = [];
                    options.forEach(option => {
                        const id = option.attributes["value"].value;
                        if (id) values.push({ id: id, value: option.textContent });
                    });
                    properties.push({ key: name, value: values });
                });

                const generateCombinations = (props) => {
                    const combinations = [];
                    const helper = (idx, combination) => {
                        if (idx === props.length) {
                            combinations.push(combination);
                            return;
                        }
                        props[idx].value.forEach(val => {
                            const newCombination = { ...combination };
                            newCombination[`attributeKey${idx + 1}`] = props[idx].key.replace(":", '');
                            newCombination[`attributeValue${idx + 1}`] = val.value;
                            newCombination[`attribute${idx + 1}Id`] = val.id;
                            newCombination['imageUrl'] = '';
                            newCombination['hasStock'] = 0;
                            helper(idx + 1, newCombination);
                        });
                    };
                    helper(0, {});
                    return combinations;
                };

                skus = generateCombinations(properties);
                doc.querySelector(".variant-list").querySelectorAll(".variant").forEach(element => {
                    const attributeLable = element.querySelectorAll(".detail");
                    const val1 = attributeLable.length > 0 ? attributeLable[0].querySelector(".value").textContent : '';
                    const val2 = attributeLable.length > 1 ? attributeLable[1].querySelector(".value").textContent : '';
                    for (let sku of skus) {
                        if ((sku.attributeValue1 || '') == val1 && (sku.attributeValue2 || '') == val2) {
                            sku.hasStock = 1;
                            break;
                        }
                    }
                });
            }
        } catch (e) { }

        t3({ Title: title, Desc: desc, CategoryId: categoryId, CategoryName: categoryName, ProductId: productId, Price: price, HasMoreSku: hasMoreSku, Skus: skus, Parameters: parameters, ImageList: imageList, PropertyNames: propertyNames });
    },
    GetFruugoProductInfo: (data, t3) => {
        let desc = '', categoryId = '', categoryName = '', otherSkuIds = [];
        let skus = [], parameters = [], propertyNames = [], imageList = [], skuAttr = [];
        let price = 0, currency = '', hasMoreSku = false;
        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(data.HtmlStr, "text/html");
            const skuInfo = extractAttributesAndValues(doc);
            const skuid = Number(doc.querySelector('input[name="skuId"]').value);
            desc = doc.querySelector("#description").outerHTML;
            const lastItemLink = doc.querySelector("ol.breadcrumb > li.breadcrumb-item:last-child a");
            categoryName = lastItemLink.textContent.trim();
            categoryId = (lastItemLink.getAttribute("href").match(/\/a-(\d+)/) || [])[1] || "";

            doc.querySelector(".product-description-spec-list").querySelectorAll("li").forEach((item) => {
                const strong = item.querySelector("strong"), valueElement = item.querySelector("a, span");
                if (strong && valueElement) parameters.push({ key: strong.textContent.replace(":", "").trim(), value: valueElement.textContent.trim() });
            });

            Array.from(doc.querySelectorAll('script')).filter(script => script.textContent.includes('window.skuInfo')).forEach(script => {
                const jsonMatch = script.textContent.match(/window\.skuInfo\s*=\s*({.*?});/);
                if (jsonMatch) {
                    const skuInfoJson = JSON.parse(jsonMatch[1]);
                    imageList = skuInfoJson.images.urls;
                    skuAttr = (skuInfoJson.attributes || []).filter(item => item.type !== "OTHER").map(item => ({ key: item.title, value: item.value }));
                }
            });

            const pricemetaTag = doc.querySelector('meta[property="product:sale_price:amount"]') || doc.querySelector('meta[property="product:price:amount"]');
            price = pricemetaTag ? pricemetaTag.getAttribute('content') : 0;
            const currencyMetaTag = doc.querySelector('meta[property="product:sale_price:currency"]') || doc.querySelector('meta[property="product:price:currency"]');
            currency = currencyMetaTag ? currencyMetaTag.getAttribute('content') : 'USD';

            if (skuInfo !== null) {
                propertyNames = skuInfo.propertyName;
                hasMoreSku = true;
                otherSkuIds = skuInfo.uniqueIds.filter(item => item !== skuid);
            }
        } catch (e) { }
        t3({ Currency: currency, Desc: desc, CategoryId: categoryId, CategoryName: categoryName, Price: price, HasMoreSku: hasMoreSku, Skus: skus, OtherSkuids: otherSkuIds, Parameters: parameters, ImageList: imageList, PropertyNames: propertyNames, SkuAttr: skuAttr });
    },
    GetFruugoVariationsInfo: (data, t3) => {
        let imageList = [], price = 0, currency = '', skuAttr = [];
        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(data.HtmlStr, "text/html");
            Array.from(doc.querySelectorAll('script')).filter(script => script.textContent.includes('window.skuInfo')).forEach(script => {
                const jsonMatch = script.textContent.match(/window\.skuInfo\s*=\s*({.*?});/);
                if (jsonMatch) {
                    const skuInfoJson = JSON.parse(jsonMatch[1]);
                    imageList = skuInfoJson.images.urls;
                    skuAttr = (skuInfoJson.attributes || []).filter(item => item.type !== "OTHER").map(item => ({ key: item.title, value: item.value }));
                }
            });
            const pricemetaTag = doc.querySelector('meta[property="product:sale_price:amount"]') || doc.querySelector('meta[property="product:price:amount"]');
            price = pricemetaTag ? pricemetaTag.getAttribute('content') : 0;
            const currencyMetaTag = doc.querySelector('meta[property="product:sale_price:currency"]') || doc.querySelector('meta[property="product:price:currency"]');
            currency = currencyMetaTag ? currencyMetaTag.getAttribute('content') : 'USD';
        } catch (e) { }
        t3({ Currency: currency, Price: price, ImageList: imageList, SkuAttr: skuAttr });
    },
    GetSaleyeeProductInfo: (data, t3) => {
        let desc = '', categoryUrl = '', categoryName = '', skus = [], parameters = [], propertyNames = [], imageList = [], allProductIds = [];
        let price = 0, currency = '', spuCode = '', productId = 0, width2 = 0, weight2 = 0, height2 = 0, length2 = 0, title = '';
        try {
            const parser = new DOMParser();
            const doc = parser.parseFromString(data.HtmlStr, "text/html");
            const skuInfoJson = doc.querySelector(".hideAttrListData").innerText;
            const productInfo = JSON.parse(doc.querySelector(".hideDefaultSkuData").innerText);
            let skuId = '';
            if (productInfo && productInfo.ProductDetailRegionLogisticsProductList?.length > 0) {
                const product = productInfo.ProductDetailRegionLogisticsProductList[0];
                if (product.ProductDetailLogisticsProductList?.length > 0) {
                    price = product.ProductDetailLogisticsProductList[0].Price_d;
                    currency = product.ProductDetailLogisticsProductList[0].Price.split(" ")[0];
                }
                skuId = productInfo.PlatformGoodsCode;
                spuCode = productInfo.SPU;
                productId = productInfo.Id;
                title = productInfo.ProductNameUS;
                width2 = productInfo.Spec.SpecWidth;
                weight2 = productInfo.Spec.SpecWeight / 1000;
                height2 = productInfo.Spec.SpecHeight;
                length2 = productInfo.Spec.SpecLength;
            }
            if (productInfo.PictureModels?.length > 0) imageList = productInfo.PictureModels.map(x => x.ImageUrl);
            const attrs = doc.querySelectorAll('.li_attr');
            if (attrs && attrs.length > 0) {
                const skuInfos = JSON.parse(skuInfoJson);
                allProductIds = [...new Set(skuInfos.map(x => x.PlatformGoodsCode))];
                propertyNames = Array.from(attrs).map(attr => attr.querySelector("span").textContent.replace("：", "").trim());
                const attributes = Array.from(attrs).map(attr => ({
                    attrName: attr.querySelector("span").textContent.replace("：", "").trim(),
                    values: Array.from(attr.querySelectorAll(".em_attr")).map(em => ({
                        code: attr.getAttribute("data-attrcode"),
                        name: attr.querySelector("span").textContent.replace("：", "").trim(),
                        value: em.getAttribute("data-attrval"),
                    }))
                }));
                const combinations = attributes.reduce((acc, curr) => acc.flatMap(d => curr.values.map(v => [...d, { v }])), [[]]);
                combinations.forEach(item => skus.push({ SkuId: '', Price: price, Property: item.map(i => ({ key: i.v.name, value: i.v.value, code: i.v.code })), Currency: currency, VariantImageUrl: imageList[0] }));
            } else {
                skus.push({ SkuId: skuId, Price: price, Property: [], Currency: currency, VariantImageUrl: imageList[0] });
            }
            desc = doc.querySelector(".layui-tab-item").outerHTML;
            const lastItemLink = doc.querySelector(".location p a:last-of-type");
            categoryName = lastItemLink.textContent.trim();
            categoryUrl = lastItemLink.getAttribute("href");
        } catch (e) { }
        t3({ allProductIds, SpuCode: spuCode, Currency: currency, Desc: desc, CategoryId: categoryUrl, CategoryName: categoryName, Price: price, Skus: skus, Parameters: parameters, ImageList: imageList, PropertyNames: propertyNames, Title: title, productId, width2, weight2, height2, length2 });
    },
    GetSaleyeeCategory: (data, t3) => {
        let categoryId = 0;
        try {
            const doc = new DOMParser().parseFromString(data.HtmlStr, "text/html");
            const scriptText = doc.querySelector(".headtopmargin").querySelector("script").innerText;
            const match = scriptText.match(/cate3:\s*(\d+)/);
            categoryId = match ? parseInt(match[1], 10) : null;
        } catch (e) { }
        t3({ id: categoryId });
    },
    GetSaleyeeDesc: (data, t3) => {
        const doc = new DOMParser().parseFromString(data.HtmlStr, "text/html");
        doc.querySelector(".choose_description").innerHTML = data.desc;
        t3({ desc: doc.querySelector(".layui-tab-item").outerHTML });
    },
    GetJF91ProductInfo: (data, t3) => {
        let goodsId = "", specData = [], dataIds = [];
        try {
            const doc = new DOMParser().parseFromString(data.HtmlStr, 'text/html');
            specData = JSON.parse(doc.querySelector('div[name="init[]"][type="specs"]').textContent.trim());
            goodsId = JSON.parse(doc.querySelector('div[name="init[]"][type="goodsid"]').textContent.trim());
            const specPicListDiv = doc.querySelector('div.spec_pic_list');
            if (specPicListDiv) dataIds = [...new Set(Array.from(specPicListDiv.querySelectorAll('div.sp_div a[data-id]')).map(a => a.getAttribute('data-id')))];
        } catch (e) { }
        t3({ goodsId, specs: specData, dataIds });
    },
    GetTiktokData: (data, t3) => {
        let resData = {};
        try {
            const doc = new DOMParser().parseFromString(data.HtmlStr, 'text/html');
            const productData1 = JSON.parse(doc.querySelector("#__MODERN_ROUTER_DATA__").innerText);
            resData = productData1.loaderData["(shop$)/(pdp)/(name$)/(id)/page"].initialData.productInfo;
        } catch (e) { }
        t3({ data: resData });
    },
    GetYandexProductInfo: (data, t3) => {
        let resData = {};
        try {
            const doc = new DOMParser().parseFromString(data.HtmlStr, 'text/html');
            const content = Array.from(doc.querySelectorAll('noframes[data-apiary="patch"]')).find(tag => (tag.textContent || tag.innerHTML).includes("oskuId"))?.textContent || "";
            if (content) {
                const argument = JSON.parse(content).widgets["@light/ToggleWishlist"]["/content/page/fancyPage/defaultPage/wishlist/wishlistToggle"];
                resData = { CardBusinessId: argument.businessId, CardOskuId: argument.oskuId, CardProductId: argument.productId };
            }
        } catch (e) { }
        t3({ data: resData });
    },
    GetYandexData: (data, t3) => {
        let resData = {};
        try {
            $.ajax({
                url: "https://market.yandex.ru/manifest.json",
                method: 'GET',
                async: false,
                error: jqXHR => {
                    const match = jqXHR.responseText.match(/window\.state\s*=\s*(\{.*\});/);
                    if (match) resData = JSON.parse(match[1]);
                }
            });
        } catch (e) { }
        t3({ data: resData });
    }
};

//新同步执行采集
function newSyncExecute(collectUrls, isVerifyDuplicate, successFun) {
    let index = 0; // 用于迭代处理 URL 的索引
    const abortController = new AbortController();
    const executeNext = () => {
        if (index < collectUrls.length) {
            const url = collectUrls[index];
            BatchExecuteProductAcquisitionLogic(url, isVerifyDuplicate, abortController.signal, function (data, t2, t3) {
                if (data.CollectBoxId) {
                    if (data.SourceUrl.indexOf("market.yandex.ru") > -1) {
                        data.SourceUrl = url;
                    }
                    repeatData.push(data);
                } else {
                    isNeedWait = true;
                    if (data.MessageType && data.MessageType === "success") {
                        successUrls.push(url);
                    }
                    else if (data.MessageType && data.MessageType === "error") {
                        failUrls.push(url);
                        failReasons.push(data.Message);
                    }
                    else if (data.Type && AcquisitionDispatchHandlers[data.Type]) {
                        if (AcquisitionDispatchHandlers[data.Type](data, t3)) return;
                    }
                    else {
                        console.log(data);
                        return;
                    }
                }
                collectionResNum();
                setProgress((failUrls.length + successUrls.length + repeatData.length) / collectUrls.length);

                let stopTime = 0;
                if (isNeedWait) {
                    stopTime = Math.max(parseInt($("#stopTime").val(), 10) * 1000, 100);
                    isNeedWait = false;
                }
                if (index == collectUrls.length - 1) stopTime = 0;
                
                if (!abortController.signal.aborted) {
                    setTimeout(() => {
                        index++;
                        executeNext();
                    }, stopTime);
                } else {
                    console.log('Operation aborted');
                }
            });
        } else {
            isNeedWait = false;
            successFun();
        }
    };

    executeNext();
    return abortController;
}

// 确认重复采集按钮
$(".popup-confirm").click(function () {
    $('.wyys-main-link').html('');
    $('.copyText').text('');
    $('.div-repeat').hide();
    $('.successNum').text(0);
    $('.errorNum').text(0);
    var repeatChecks = $(".select:checked");
    if (repeatChecks.length == 0) {
        rightTipError('请至少选择一个产品进行采集！');
    } else {
        // 确认选中产品再次进行采集 —— 设置弹出框 —— 进行采集 —— 收集结果
        removeRepeatDataTable();
        addCollectResults();
        setProgress(0);

        var repeatUrls = [];
        for (let i = 0; i < repeatChecks.length; i++) {
            var collectBox = repeatData.filter(x => x.CollectBoxId == $(repeatChecks[i]).attr("data-id"))[0];
            if (collectBox) {
                repeatUrls.push(collectBox.SourceUrl);
            }
        }
        urls = repeatUrls;

        repeatData = [];
        successUrls = [];
        failUrls = [];
        failReasons = [];
        setProgress(0);

        controller = newSyncExecute(repeatUrls, false, () => {
            failToCopy();
            collectionResNum();
        })
    }
});

//执行产品采集逻辑
function BatchExecuteProductAcquisitionLogic(url, isVerifyDuplicate, signal, funCallback) {
    try {
        //匹配平台
        var platformData = MatchingPlatform(url);
        var platformId = platformData.PlatformId;
        if (!supportPlatforms.some(x => x === platformId)) {
            funCallback({"Type": "Alter", "MessageType": "error", "Message": "该平台暂不支持批量采集！"})
            return;
        }
        if (platformId > 0) {
            if (isVerifyDuplicate) {
                GetSourceUrlEntity(url,
                    function (sku) {     // 获取采集过的产品数据成功的回调 —— successfulCallBack
                        if (sku !== null) {
                            funCallback(sku)
                        } else {
                            AnalyticalProducts(platformId, {
                                isLinkCollect: true,
                                isBathCollect: true
                            }, null, url, funCallback);
                        }
                    },
                    function (msg) {
                        // 获取采集过的产品数据失败的回调 —— failedCallBack
                        errorTip(msg)
                    }
                );
            } else {
                AnalyticalProducts(platformId, {isLinkCollect: true, isBathCollect: true}, null, url, funCallback);
            }
        } else {
            throw new Error("产品采集失败!");
        }
    } catch (error) {
        var errorMsg = {"Type": "Alter", "MessageType": "error", "Message": "采集地址无效，或不支持该网址采集。"}
        funCallback(errorMsg)
        // removeCollectResults()
        // if ($('#urlCollect').val()) {
        //     errorTip('采集地址无效，或不支持该网址采集。')
        // }
    }
}

// 采集过的产品数据
function GetSourceUrlEntity(sourceUrl, successfulCallBack, failedCallBack) {
    request(config.url.getSourceUrlEntity(), {
        responseType: "json",
        body: {"SourceUrl": sourceUrl},
        method: "POST"
    }).then(res => {
        if (res !== null) {
            if (res.IsSuccess === true) {
                successfulCallBack(res.Data);
            } else {
                failedCallBack(res.Message == null ? (res.ResponseError == null ? "服务器未知异常，请联系管理员" : res.ResponseError.Message) : res.Message);
            }
        } else {
            failedCallBack("发生未知异常！请稍后重试！若长时间发生此错误，请与客服联系！");
        }
    }).catch(reason => {
        failedCallBack("服务器连接失败！请稍后重试！若长时间发生此错误，请与客服联系！");
    });
}

// 右侧弹框提示
function rightTipError(err) {
    GrowlNotification.notify({
        title: '温馨提示',
        image: {visible: true, customImage: config.logoBase64},
        description: err,
        type: 'error',
        position: 'top-right',
        closeTimeout: 3000,
    });
}

function rightTipSuccess(success) {
    GrowlNotification.notify({
        title: '温馨提示',
        image: {visible: true, customImage: config.logoBase64},
        description: success,
        type: 'success',
        position: 'top-right',
        closeTimeout: 1500,
    });
}

// 添加重复采集的表格
function addRepeatDataTable() {
    $(".popup").addClass("visible");
    $(".popup-mask").addClass("visible");
}

// 移除重复采集的表格
function removeRepeatDataTable() {
    $(".popup").removeClass("visible");
    $(".popup-mask").removeClass("visible");
}

// 添加采集结果提示框
function addCollectResults() {
    $(".collect_results").addClass("visible");
    $(".popup-mask").addClass("visible");
}

// 移除采集结果提示框
function removeCollectResults() {
    $(".collect_results").removeClass("visible");
    $(".popup-mask").removeClass("visible");
}

// 渲染失败采集链接
function failToCopy() {
    if (failUrls.length > 0) {
        $('.copyText').text('复制失败链接')
        $('div.wyys-main-link').html('');
        for (i = 0; i < failUrls.length; i++) {
            var a = $("<a>").text(failUrls[i]).addClass('failUrl');
            var reasons=failReasons[i].replace('执行失败，','');
            var p = $("<p>").text(reasons).addClass('reasonP');
            $("div.wyys-main-link").append(p);
            $("div.wyys-main-link").append(a);
        }
    }
}

// 渲染采集结果数量
function collectionResNum() {
    $('.successNum').text(successUrls.length)
    $('.errorNum').text(failUrls.length)
    $('.repeatNum').text(repeatData.length)
}

// 采集结果弹出框关闭按钮
$(".collect_results-no, .collect_results-close").click(function () {
    removeCollectResults()
    if (failUrls.length == 0) {
        $('#urlCollect').val('');
    }
    $('div.wyys-main-link').html('');
    setProgress(0);
    controller.abort();
});

// 重复采集表格弹出框关闭按钮
$(".popup-close").click(function () {
    $(".popup").removeClass("visible");
    $(".popup-mask").removeClass("visible");
});
// 重复采集时点击跳过
$(".popup-cancel").click(function () {
    $(".popup").removeClass("visible");
    $(".collect_results").addClass("visible");
    setProgress(1)
    collectionResNum()
});
// 重复采集时的弹出框——全选/取消全选
$("#selectAll").click(function () {
    var allChecked = $(this).prop("checked");
    $(".select").prop("checked", allChecked);
});
// 回到首页
$("#toHome").click(function () {
    window.open(config.url.domain());
});
$("#showCollected").click(function () {
    window.open(config.url.domain() + '/main#/collectbox');
})
// 输入框置空
$('#reset').click(function () {
    $('#urlCollect').val('')
    removeErrorStyle();
})
// 复制采集失败的链接
$('.copyText').click(function () {
    // 获取要复制的文本
    // var textToCopy = $("div.link a").text();
    var textToCopy = $("div.wyys-main-link a").map(function () {
        return $(this).text();
    }).get().join('\n');
    // 创建一个临时文本区域
    var tempTextArea = $("<textarea>");
    // 将要复制的文本添加到文本区域中
    tempTextArea.text(textToCopy);
    // 将文本区域添加到文档中
    $("body").append(tempTextArea);
    // 选中文本区域中的文本
    tempTextArea.select();
    try {
        // 尝试将选中的文本复制到剪贴板
        document.execCommand("copy");
        // 复制成功，弹出成功提示框
        rightTipSuccess("复制成功!")
    } catch (err) {
        rightTipError('复制失败，请手动复制!')
    }
    // 删除临时文本区域
    tempTextArea.remove();
})

function select() {
    var allChecked = $(".select:checked").length === $(".select").length;
    $("#selectAll").prop("checked", allChecked);
}

// 框底提示错误信息
function errorTip(errorInfo) {
    $("#errorMessage").addClass("visible");
    $("#urlCollect").addClass("visible");
    $("#errorMessage").text(errorInfo)
}

// 框底移除提示错误信息
function removeErrorStyle() {
    $("#errorMessage").removeClass("visible");
    $("#urlCollect").removeClass("visible");
}

// ========== 数据分析显示配置 ==========
const ANALYSIS_FIELDS = [
    { key: 'sku', label: '商品编码' },
    { key: 'category1', label: '一级类目' },
    { key: 'category3', label: '三级类目' },
    { key: 'sales', label: '月销量' },
    { key: 'gmv', label: '月销售额' },
    { key: 'salesDynamics', label: '月销售变化' },
    { key: 'avgPrice', label: '平均价格' },
    { key: 'minSellerPrice', label: '最低售价' },
    { key: 'brand', label: '品牌' },
    { key: 'views', label: '曝光量' },
    { key: 'convViewToOrder', label: '曝光转化率' },
    { key: 'convToCartSearch', label: '搜索转换率' },
    { key: 'convTocartPdp', label: '加购率' },
    { key: 'nullableRedemptionRate', label: '结单率' },
    { key: 'drr', label: '推广费用占比' },
    { key: 'daysWithTrafarets', label: '开模板活动天数' },
    { key: 'daysInPromo', label: '开促销天数' },
    { key: 'promoRevenueShare', label: '促销收入占比' },
    { key: 'avgDeliveryDays', label: '平均运输时间' },
    { key: 'salesSchema', label: '配送方式' },
    { key: 'sellerCount', label: '销售该商品卖家数量' },
    { key: 'hasGollowSales', label: '是否允许复制' },
    { key: 'pCreateDate', label: '出售时间' },
    { key: 'stock', label: '库存' },
    { key: 'ptj', label: '体积' },
    { key: 'pWeight', label: '重量' },
    { key: 'commission', label: '佣金' }
];

function renderAnalysisConfig() {
    const container = $('#analysisConfigFields');
    container.empty();
    chrome.storage.local.get(['analysis_display_config'], function(res) {
        const config = res.analysis_display_config || {};
        ANALYSIS_FIELDS.forEach(function(field) {
            const checked = config[field.key] !== false ? 'checked' : '';
            const html = '<label style="display:flex; align-items:center; gap:4px; font-size:13px; color:#374151; cursor:pointer; padding:4px 8px; background:#f9fafb; border-radius:6px; border:1px solid #e5e7eb; min-width:120px;">' +
                '<input type="checkbox" class="analysis-field-cb" value="' + field.key + '" ' + checked + '>' + field.label + '</label>';
            container.append(html);
        });
    });
}

$('#analysisConfigToggle').click(function() {
    const body = $('#analysisConfigBody');
    const arrow = $('#configArrow');
    if (body.is(':visible')) {
        body.slideUp(200);
        arrow.text('▼');
    } else {
        body.slideDown(200);
        arrow.text('▲');
        renderAnalysisConfig();
    }
});

$('#saveAnalysisConfig').click(function() {
    const config = {};
    $('.analysis-field-cb').each(function() {
        config[$(this).val()] = $(this).is(':checked');
    });
    chrome.storage.local.set({ analysis_display_config: config }, function() {
        rightTipSuccess('配置已保存');
    });
});

$('#resetAnalysisConfig').click(function() {
    const config = {};
    ANALYSIS_FIELDS.forEach(function(field) {
        config[field.key] = true;
    });
    chrome.storage.local.set({ analysis_display_config: config }, function() {
        renderAnalysisConfig();
        rightTipSuccess('已恢复默认');
    });
});

