package com.diaoyun.zion.chinafrica.bis.impl;

import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import static com.diaoyun.zion.master.util.SpiderUtil.exchangeRate;

/**
 * Gucci(古驰) 数据爬虫
 * TODO 数据显示存在BUG
 * @author 爱酱油不爱醋
 */
@Component("gucciSpider")
public class GucciSpider implements IItemSpider {
    private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class);

    /**
     * Gucci(古驰) 数据爬虫
     * @param targetUrl 接收的商品详情路径
     * @return 格式化与翻译后的 Json 数据
     */
    @Override
    public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
        String[] spilt = targetUrl.split("/");
        spilt = spilt[5].split("[?]");
        String pId = spilt[0];
        String styleId = pId.substring(0, 5);
        targetUrl = "https://www.gucci.cn/zh/pr/sameStyleBuriedPoint?itemCode=" + pId +"&style=" + styleId + "&categoryPath=&_=1572859976423";
        String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.GUCCI.getValue());
        ProductResponse productResponse = formatProductResponse(content, pId);
        JSONObject resultObj = JSONObject.fromObject(productResponse);
        TranslateHelper.translateProductResponse(resultObj);
        return resultObj;
    }

    /**
     * 格式化返回数据
     * @param content 主要的网页内容
     * @param pId 截取到的商品 id
     * @return 格式化后的数据
     */
    private ProductResponse formatProductResponse(String content, String pId) {
        // 声明封装类
        ProductResponse productResponse = new ProductResponse();
        // 含有商品的属性，设置为true
        productResponse.setPropFlag(true);
        // 库存信息，如果没有可使用的库存信息则默认为999
        DynStock dynStock = new DynStock();
        dynStock.setSellableQuantity(9999);
        List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
        // 产品的原始价与优惠价
        List<OriginalPrice> originalPriceList = new ArrayList<>();
        List<ProductPromotion> promotionList = new ArrayList<>();
        // 商品的属性，常用的商品属性为颜色与尺码
        Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
        Set<ProductProp> propSet = new HashSet<>(16);
        Set<ProductProp> sizePropSet = new HashSet<>(16);
        productResponse.setStockFlag(true);
        // 商品的基本属性
        ItemInfo itemInfo = new ItemInfo();

        Document document = Jsoup.parse(content);

        //////////////////////////////////// 获取商品基本信息 ////////////////////////////
        itemInfo.setShopName("Gucci");
        itemInfo.setShopUrl("https://www.gucci.cn/");
        itemInfo.setItemId(pId);
        itemInfo.setTitle(document.select("div[class=spice-fixed-change-rel-fixed]")
                .select("a[id=product_main_image_0]").select("img").attr("alt"));
        itemInfo.setPic(document.select("div[class=spice-fixed-change-rel-fixed]")
                .select("a[id=product_main_image_0]").select("img").attr("srcset"));
        //////////////////////////////////// 获取商品基本信息End /////////////////////////

        // 转换为 JSON 对象取 impressions 的数组节点
        JSONObject dataMap = JSONObject.fromObject(content);
        JSONArray impressionsArr = dataMap.getJSONObject("ecommerce").getJSONArray("impressions");
        // 获取商品的款式 id
        List<String> pIdList = new ArrayList<>(10);
        // 声明一个集合，这个数组用来存储销售价格
        List<Double> pPrice = new ArrayList<>(15);
        for (int i = 0; i < impressionsArr.size(); i++) {
            pIdList.add(impressionsArr.getJSONObject(i).getString("id"));
        }

        for (int i = 0; i < pIdList.size(); i++) {
            // 获取每个款式的商品 id 以及网页内容
            pId = pIdList.get(i);
            String targetUrl = "https://www.gucci.cn/zh/pr/" + pId + "?listName=VariationOverlay";
            try {
                content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.GUCCI.getValue());
            } catch (URISyntaxException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            document = Jsoup.parse(content);

            String fullPrice = impressionsArr.getJSONObject(i).getString("price");
            fullPrice = exchangeRate(fullPrice);

            ///////////////////////// 获取商品颜色属性 ////////////////////////////////////////////////////////////////
            String colorNo = pId;
            String color = document.select("span[class=spice-color-material]").select("img").attr("alt");
            String imageUrl = document.select("div[class=spice-fixed-change-rel-fixed]").select("a[id=product_main_image_0]").select("img").attr("srcset");

            ProductProp productPropColor = new ProductProp();
            productPropColor.setPropId(pId);
            productPropColor.setPropName(color);
            productPropColor.setImage(imageUrl);
            propSet.add(productPropColor);
            if (productPropSet.get("颜色") == null) {
                productPropSet.put("颜色", propSet);
            } else {
                Set<ProductProp> oldPropSet = productPropSet.get("颜色");
                propSet.addAll(oldPropSet);
                productPropSet.put("颜色", propSet);
            }
            ///////////////////////// 获取商品颜色属性End ////////////////////////////////////////////////////////////////

            Elements sizeEle = document.select("div[class=spice-dropdown spice-dropdown-semi-simulation spice-none]").select("option");
            List<String> sizeNoList = sizeEle.eachAttr("spice-data-value");
            List<String> sizeList = sizeEle.eachText();
            if (sizeNoList.size() > 0) {
                for (int j = 0; j < sizeNoList.size(); j++) {

                    ///////////////////////// 获取商品尺码属性 END/////////////////////////////////////////////////////
                    String sizeNo = sizeNoList.get(j);
                    String size = sizeList.get(j);

                    ProductProp productPropSize = new ProductProp();
                    productPropSize.setPropId(sizeNo);
                    productPropSize.setPropName(size);
                    sizePropSet.add(productPropSize);
                    if (productPropSet.get("尺码") == null) {
                        productPropSet.put("尺码", sizePropSet);
                    } else {
                        Set<ProductProp> oldPropSet = productPropSet.get("尺码");
                        sizePropSet.addAll(oldPropSet);
                        productPropSet.put("尺码", sizePropSet);
                    }
                    ///////////////////////// 获取商品尺码属性 END/////////////////////////////////////////////////////

                    //////////////////////////////////// 获取库存/////////////////////////////////////////
                    // 设置 skuStr
                    String skuStr = ";" + colorNo + ";" + sizeNo + ";";

                    if (productSkuStockList == null) {
                        productSkuStockList = new ArrayList<>();
                    }
                    ProductSkuStock productSkuStock = new ProductSkuStock();
                    productSkuStock.setSellableQuantity(999);
                    productSkuStock.setSkuStr(skuStr);
                    // 存在没有对应尺码的说明
                    if (size.length() < 4) {
                        productSkuStockList.add(productSkuStock);
                        dynStock.setProductSkuStockList(productSkuStockList);
                    }
                    //////////////////////////////////// 获取库存 END/////////////////////////////////////////

                    //////////////////////////////////// 获取原始价 //////////////////////////////////
                    OriginalPrice originalPrice = new OriginalPrice();
                    originalPrice.setSkuStr(skuStr);
                    originalPrice.setPrice(fullPrice);
                    if (size.length() < 4) {
                        originalPriceList.add(originalPrice);
                    }
                    // 存储价格
                    pPrice.add(Double.valueOf(fullPrice));
                    productResponse.setPrice(fullPrice);
                    //////////////////////////////////// 获取原始价 END //////////////////////////////////
                }
            } else {
                //////////////////////////////////// 获取库存/////////////////////////////////////////
                // 设置 skuStr
                String skuStr = ";" + colorNo + ";" + "" + ";";

                if (productSkuStockList == null) {
                    productSkuStockList = new ArrayList<>();
                }
                ProductSkuStock productSkuStock = new ProductSkuStock();
                productSkuStock.setSellableQuantity(999);
                productSkuStock.setSkuStr(skuStr);
                productSkuStockList.add(productSkuStock);
                dynStock.setProductSkuStockList(productSkuStockList);

                //////////////////////////////////// 获取库存 END/////////////////////////////////////////

                //////////////////////////////////// 获取原始价 //////////////////////////////////
                OriginalPrice originalPrice = new OriginalPrice();
                originalPrice.setSkuStr(skuStr);
                originalPrice.setPrice(fullPrice);
                originalPriceList.add(originalPrice);

                // 存储价格
                pPrice.add(Double.valueOf(fullPrice));
                productResponse.setPrice(fullPrice);
                //////////////////////////////////// 获取原始价 END //////////////////////////////////
            }
        }

        // 取存储的价格的最大值
        Double minPrice = Collections.min(pPrice);
        Double maxPrice = Collections.max(pPrice);
        productResponse.setSalePrice(minPrice + "-" + maxPrice);

        productResponse.setProductPropSet(productPropSet);
        productResponse.setPlatform("Gucci");
        productResponse.setPromotionList(promotionList);
        productResponse.setOriginalPriceList(originalPriceList);
        productResponse.setItemInfo(itemInfo);
        productResponse.setDynStock(dynStock);
        return productResponse;
    }
}
