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.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.JsoupUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import com.diaoyun.zion.master.util.ValidateUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * 淘宝网数据爬虫
 */
@Component("tbItemSpider")
public class TbItemSpider implements IItemSpider {
    private static Logger logger = LoggerFactory.getLogger(TbItemSpider.class);

    /**
     * 淘宝商品详情页链接
     */
    private static final String taobaoUrl="https://item.taobao.com/item.htm?";

    @Override
    public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
        //主要是判断淘宝的url是手机端还是PC端，如果是手机端，那么还需要提取相关参数，组成新的url；还有去除链接中一些会引起请求错误的参数
        targetUrl=processUrl(targetUrl);
        List<Map<String, Object>> futureList= new ArrayList<>();
        //获取url中的网页内容
        String content = HttpClientUtil.getContentByUrl(targetUrl,PlatformEnum.TB.getValue());
        //获取商品相关信息，比如详情url
        Map<String,String> infoMap= JsoupUtil.getTbItemDetail(content);
        String usableSibUrl="https:"+infoMap.get("sibUrl");
        //解析商品sku信息
        Map<String,Object> propMap=JsoupUtil.getPropMap(content);

        if(propMap.get("hasSku")==null||(boolean)propMap.get("hasSku")) {
            //调用腾讯ai，翻译规格
            translateProp(futureList,propMap);
        }

        /* ****************获取商品详情******************* */
        //删除需要登录的模块
        usableSibUrl=deleteLoginModule(usableSibUrl);
        //需要加入头部
        BasicHeader basicHeader=new BasicHeader("referer", targetUrl);
        String sibContent = HttpClientUtil.getContentByUrl(usableSibUrl,basicHeader);
        //unicode 解码
        sibContent= StringEscapeUtils.unescapeJava(sibContent);

        //logger.info(sibMap.toString());
        //从请求结果中获取Cookie，此时的Cookie已经带有登录信息了
        //CookieStore store = httpClientContext.getCookieStore();
        /*Long c=System.currentTimeMillis();
        logger.info("获取详情时间(毫秒)："+(c-b));*/

        //等待翻译结果
        TranslateHelper.waitForResult(futureList);
        //关闭线程池 不能关闭，否则下次调用不了
        //taskLimitSemaphore.shutdown();
        /* Long d=System.currentTimeMillis();
        logger.info("翻译时间(毫秒)："+(d-c));

        logger.info("爬取数据总共耗费时间(毫秒)："+(d-a));*/
        JSONObject returnJson= JSONObject.fromObject(sibContent);
        returnJson.put("Jprop",propMap);
        returnJson.put("itemProp",infoMap);
        returnJson.put("platform", PlatformEnum.TB.getValue());
        return returnJson;
    }

    /**
     * 翻译规格属性
     * @param propMap 规格属性MAP
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private void translateProp(List<Map<String, Object>> futureList,Map<String, Object> propMap)  {
        /*腾讯翻译*/
        for(Map.Entry<String,Object>entry : propMap.entrySet()) {
            String key=entry.getKey();
            Map <String,Object> value= (Map<String, Object>) entry.getValue();
            //翻译属性名
            if(ValidateUtils.isContainChinese(key)) {
                TranslateHelper.translateText(futureList,value,key);
            }
            //翻译sku title
            if(value!=null&&value.size()>0) {
                translateTitle(futureList,value);
            }
        }
    }

    /**
     * 翻译规格说明
     * @param skuMap
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private void translateTitle(List<Map<String, Object>> futureList,Map<String, Object> skuMap) {
        for(Map.Entry<String,Object>entry : skuMap.entrySet()) {
            String key=entry.getKey();
            if(entry.getValue() instanceof Map) {
                Map<String, Object> value = (Map<String, Object>) entry.getValue();
                String title = (String) value.get("title");
                if (StringUtils.isNotBlank(title)) {
                    //翻译属性名
                    if (ValidateUtils.isContainChinese(title)) {
                        TranslateHelper.translateText(futureList,value,title);
                        //value.put("translate", translate);
                    }
                }
            }
        }
    }

    /**
     * 去除需要登录或者不需要返回的参数
     * @param usableSibUrl
     * @return
     */
    private String deleteLoginModule(String usableSibUrl) {
        usableSibUrl=usableSibUrl.replaceAll("couponActivity,","");
        usableSibUrl=usableSibUrl.replaceAll("soldQuantity,","");
        usableSibUrl=usableSibUrl.replaceAll("tradeContract,","");
        usableSibUrl=usableSibUrl.replaceAll("upp,","");
        // TODO 运费格式有问题，暂去除
        usableSibUrl=usableSibUrl.replaceAll("deliveryFee,","");
        usableSibUrl=usableSibUrl.replaceAll("delivery,","");
        return usableSibUrl;
    }

    /**
     * 主要是提取相关参数，组成新的url
     *
     * @param targetUrl
     * @return
     */
    private String processUrl(String targetUrl) throws URISyntaxException, MalformedURLException {
        String newUrl=taobaoUrl;
        //if(targetUrl.contains("h5.m.taobao.com")) {
        Map<String,String> paramMap=HttpClientUtil.getParamMap(targetUrl);
        //目前淘宝需要四个参数 spm id scm pvid
        //引起错误的 参数 ali_refid
        StringBuffer paramBuffer=new StringBuffer();
        for(Map.Entry<String,String> entry:paramMap.entrySet()) {
            if("ali_refid".equals(entry.getKey())||"track_params".equals(entry.getKey())||"utparam".equals(entry.getKey())
            ||"rmdChannelCode".equals(entry.getKey())||"locate".equals(entry.getKey())) {

            } else {
                paramBuffer.append(entry.getKey()+"="+entry.getValue()+"&");
            }
        }

        return newUrl+paramBuffer.toString();

    }

}
