package top.baogutang.admin.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import top.baogutang.admin.domain.IphoneProductDto;
import top.baogutang.common.constants.ErrorCodeEnum;
import top.baogutang.common.exceptions.BusinessException;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static top.baogutang.common.constants.CacheConstant.PREFIX_APPLE_PRODUCT;

/**
 * @description:
 * @author: nikooh
 * @date: 2023/10/13 : 15:47
 */
@Component
public class IphoneProductParserUtils {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @SuppressWarnings("unchecked")
    public List<IphoneProductDto> getProducts(String code, String country) {
        String cacheKey = String.format(PREFIX_APPLE_PRODUCT, country, code);
        Object productObj = redisTemplate.opsForValue().get(cacheKey);
        if (Objects.nonNull(productObj)) {
            return (List<IphoneProductDto>) productObj;
        }
        String url = "https://www.apple.com/" + country + "/shop/buy-iphone/iphone-" + code;
        String content = sendHttpRequest(url);
        if (Objects.isNull(content)) {
            throw new BusinessException(ErrorCodeEnum.E_BIZ_ERROR);
        }
        List<IphoneProductDto> iphoneProductDtos = parseProducts(content);
        redisTemplate.opsForValue().set(cacheKey, iphoneProductDtos, 30, TimeUnit.DAYS);
        return iphoneProductDtos;
    }

    private String sendHttpRequest(String url) {
        try {
            URL urlObj = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0");

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuilder response = new StringBuilder();
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                return response.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private List<IphoneProductDto> parseProducts(String content) {
        String selectText = null;
        String[] parts = content.split("window.PRODUCT_SELECTION_BOOTSTRAP = ");
        if (parts.length > 1) {
            selectText = parts[1].split("</script>")[0].replace("productSelectionData", "\"productSelectionData\"");
        }

        if (selectText != null) {
            JSONObject selectData = JSON.parseObject(selectText);
            JSONObject productSelectionData = selectData.getJSONObject("productSelectionData");
            JSONArray productsArray = productSelectionData.getJSONArray("products");
            JSONObject displayValues = productSelectionData.getJSONObject("displayValues");
            JSONObject prices = displayValues.getJSONObject("prices");
            JSONObject colors = displayValues.getJSONObject("dimensionColor");

            List<IphoneProductDto> products = new ArrayList<>();

            for (int i = 0; i < productsArray.size(); i++) {
                JSONObject productObject = productsArray.getJSONObject(i);
                String priceTag = productObject.getString("fullPrice");
                JSONObject priceData = prices.getJSONObject(priceTag);

                IphoneProductDto product = new IphoneProductDto(
                        productObject.getString("familyType"),
                        productObject.getString("partNumber"),
                        productObject.getString("dimensionColor"),
                        productObject.getString("dimensionCapacity"),
                        colors.getJSONObject(productObject.getString("dimensionColor")).getString("value"),
                        priceData.getJSONObject("currentPrice").getDouble("raw_amount"),
                        priceData.getJSONObject("currentPrice").getString("amount"),
                        priceData.getString("priceCurrency"),
                        productObject.containsKey("carrierModel") ? productObject.getString("carrierModel") : ""
                );

                products.add(product);
            }
            return products;
        }
        return new ArrayList<>();
    }

}
