package com.adx.tracking.baidu;

import com.adx.tracking.baidu.model.*;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 对应 Go internal/baidu/adx.go 的 ADXClient。
 * 负责：竞价请求(RequestBid)、曝光上报(ReportImpression)、点击上报(ReportClick)。
 */
public class AdxClient {

    public static final String AUCTION_PRICE_MACRO = "${AUCTION_PRICE}";
    public static final String BAIDU_USER_AGENT = "QTech-MeasurementNode/1.2 (Postback; Attribution; S2S)";

    private final String endpoint;
    private final HttpClient httpClient;
    private final AuctionPriceEncoder priceEncoder;
    private final ObjectMapper objectMapper;

    public AdxClient(String endpoint, AuctionPriceEncoder priceEncoder, ObjectMapper objectMapper) {
        this.endpoint = endpoint;
        this.priceEncoder = priceEncoder;
        this.httpClient = HttpClient.newHttpClient();
        this.objectMapper = objectMapper;
    }

    /**
     * 向百度 ADX 发起竞价请求，返回归一化后的 BidResponse。
     */
    public NormalizedBidResponse requestBid(Object body) throws IOException, InterruptedException {
        if (endpoint == null || endpoint.isBlank()) {
            throw new IllegalStateException("Baidu ADX endpoint is required");
        }

        byte[] payload = objectMapper.writeValueAsBytes(body);
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .POST(HttpRequest.BodyPublishers.ofByteArray(payload))
                .header("Content-Type", "application/json")
                .header("User-Agent", BAIDU_USER_AGENT)
                .build();

        HttpResponse<byte[]> response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            throw new IOException("Baidu ADX HTTP status: " + response.statusCode());
        }

        BidResponse bidResponse = objectMapper.readValue(response.body(), BidResponse.class);
        return NormalizedBidResponse.from(bidResponse);
    }

    /**
     * 曝光上报：将 ${AUCTION_PRICE} 宏替换为编码后的价格，依次 GET 所有 showURLs。
     */
    public List<TrackingResult> reportImpression(List<String> showUrls, long price)
            throws IOException, InterruptedException {
        String encodedPrice = priceEncoder.encode(price);
        List<String> urls = new ArrayList<>();
        for (String url : showUrls) {
            urls.add(url.replace(AUCTION_PRICE_MACRO, encodedPrice));
        }
        return reportTrackingUrls(urls);
    }

    /**
     * 点击上报：直接 GET 所有 clickURLs。
     */
    public List<TrackingResult> reportClick(List<String> clickUrls)
            throws IOException, InterruptedException {
        return reportTrackingUrls(clickUrls);
    }

    private List<TrackingResult> reportTrackingUrls(List<String> trackingUrls)
            throws IOException, InterruptedException {
        List<TrackingResult> results = new ArrayList<>();
        for (String url : trackingUrls) {
            HttpRequest req = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .GET()
                    .header("User-Agent", BAIDU_USER_AGENT)
                    .build();
            HttpResponse<Void> resp = httpClient.send(req, HttpResponse.BodyHandlers.discarding());
            int status = resp.statusCode();
            results.add(new TrackingResult(url, status, status >= 200 && status < 400));
        }
        return results;
    }

    // ─── 默认价格编码（不加密，直接 URL encode 数字字符串）───────────────
    public static String defaultEncodePrice(long price) {
        return URLEncoder.encode(String.valueOf(price), StandardCharsets.UTF_8);
    }
}
