package com.rj.integration;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.rj.dto.hxr.HxrOrderRow;
import com.rj.dto.hxr.HxrOrderSelectResponse;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Properties;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * 手动调用 hxrd 后台「订单列表」JSON 接口（需有效 PHPSID）。
 * <p>
 * 推荐：将 {@code src/test/resources/hxr-order-integration.example.properties} 复制为
 * {@code hxr-order-integration.properties}，填写 {@code hxr.order.cookie} 或 {@code hxr.order.phpsid}
 * （该文件已加入 .gitignore）。
 * <p>
 * 覆盖优先级（从高到低）：JVM 系统属性（{@code -Dhxr.order.cookie} / {@code -Dhxr.order.phpsid}）
 * &gt; 环境变量 {@code HXR_ORDER_COOKIE} &gt; classpath 配置文件 {@code hxr-order-integration.properties}。
 * <p>
 * 不要手动设置含 {@code br}、{@code zstd} 的 {@code Accept-Encoding}：{@link HttpClient} 只会对默认协商的编码自动解压，
 * 否则服务端可能返回 Brotli/zstd，响应体会变成乱码。
 */
class HxrAdminOrderSelectHttpTest {

    private static final String CONFIG_RESOURCE = "hxr-order-integration.properties";

    private static final String PROP_COOKIE = "hxr.order.cookie";
    private static final String PROP_PHPSID = "hxr.order.phpsid";
    private static final String ENV_COOKIE = "HXR_ORDER_COOKIE";

    private static final String BASE_URL = "https://hxrdhoutai.hxrdsm.cn/app/admin/order/select";

    private static final String QUERY =
            "?page=1&limit=20"
                    + "&order_sn%5B0%5D=like&order_sn%5B1%5D="
                    + "&seller_id=&buyer_id=&status=&is_resell=0&is_show="
                    + "&buy_time%5B0%5D=&buy_time%5B1%5D=&confirm_time%5B0%5D=&confirm_time%5B1%5D=";

    private static volatile Properties integrationProps;

    private static final ObjectMapper HXR_ORDER_JSON = new ObjectMapper()
            .setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    @Test
    void getOrderSelectJson() throws Exception {
        String cookie = resolveCookie();
        Assumptions.assumeFalse(
                cookie == null || cookie.isBlank(),
                "跳过：请在 src/test/resources/ 下复制 "
                        + "hxr-order-integration.example.properties 为 "
                        + CONFIG_RESOURCE
                        + " 并填写 hxr.order.cookie 或 hxr.order.phpsid；或设置环境变量 "
                        + ENV_COOKIE
                        + " / VM 选项 -D"
                        + PROP_COOKIE
                        + " / -D"
                        + PROP_PHPSID);

        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(15))
                .followRedirects(HttpClient.Redirect.NORMAL)
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + QUERY))
                .timeout(Duration.ofSeconds(60))
                .header("Accept", "application/json, text/javascript, */*; q=0.01")
                .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .header("Cookie", cookie)
                .header("Priority", "u=1, i")
                .header("Referer", "https://hxrdhoutai.hxrdsm.cn/app/admin/order/index")
                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0")
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println("HTTP " + response.statusCode());
        assertTrue(
                response.statusCode() >= 200 && response.statusCode() < 300,
                "unexpected status: " + response.statusCode());

        HxrOrderSelectResponse body = HXR_ORDER_JSON.readValue(response.body(), HxrOrderSelectResponse.class);
        assertEquals(0, body.code(), () -> "api code != 0, msg=" + body.msg() + ", body=" + response.body());
        for (HxrOrderRow row : body.data()) {
            System.out.println(HXR_ORDER_JSON.writeValueAsString(row));
        }
    }

    @Test
    void parseSampleJson_printsOneLinePerOrder() throws Exception {
        String json =
                """
                {"code":0,"msg":"ok","count":7,"data":[{"id":358078,"old_id":null,"seller_id":97154,"buyer_id":97374,"order_sn":"47379117788104684482","total_money":"23423.95","pay_time":"2026-05-15 10:04:32","pay_img":"\\/upload\\/image\\/20260515\\/ec791c7a9ed2f5ade9450c0f50efd819_6a067f2f9317d.jpeg","status":2,"is_resell":0,"is_show":1,"consignee":"陈科亦","phone":"18810005315","province":"河北省","city":"廊坊市","area":"三河市","address":"燕郊开发区金谷爱舒荷","merchandise_id":344196,"confirm_time":"2026-05-15 10:08:04","buy_time":"2026-05-15 10:01:08","created_at":"2026-05-15 10:01:08","updated_at":"2026-05-15 10:08:04"},{"id":357968,"old_id":null,"seller_id":98719,"buyer_id":96030,"order_sn":"03069117788104035736","total_money":"27037.65","pay_time":"2026-05-15 10:02:48","pay_img":"\\/upload\\/image\\/20260515\\/37d6d7d09447d6c8ce41abd0727a39d5_6a067ec77a519.jpeg","status":1,"is_resell":0,"is_show":1,"consignee":"陈晓琴","phone":"17733627528","province":"河北省","city":"廊坊市","area":"三河市","address":"燕郊镇金谷爰舒荷十号楼","merchandise_id":344269,"confirm_time":null,"buy_time":"2026-05-15 10:00:03","created_at":"2026-05-15 10:00:03","updated_at":"2026-05-15 10:02:48"}],"all_money":"182851.70"}
                """;
        HxrOrderSelectResponse body = HXR_ORDER_JSON.readValue(json.trim(), HxrOrderSelectResponse.class);
        assertEquals(0, body.code());
        assertEquals(2, body.data().size());
        for (HxrOrderRow row : body.data()) {
            System.out.println(HXR_ORDER_JSON.writeValueAsString(row));
        }
    }

    private static String resolveCookie() {
        String fromFileCookie = firstNonBlank(integrationProps().getProperty(PROP_COOKIE));
        String fromFilePhpsid = firstNonBlank(integrationProps().getProperty(PROP_PHPSID));

        String fromProp = firstNonBlank(System.getProperty(PROP_COOKIE));
        String phpsidProp = firstNonBlank(System.getProperty(PROP_PHPSID));
        String fromEnv = firstNonBlank(System.getenv(ENV_COOKIE));

        if (fromProp != null) {
            return fromProp;
        }
        if (phpsidProp != null) {
            return "PHPSID=" + phpsidProp;
        }
        if (fromEnv != null) {
            return fromEnv;
        }
        if (fromFileCookie != null) {
            return fromFileCookie;
        }
        if (fromFilePhpsid != null) {
            return "PHPSID=" + fromFilePhpsid;
        }
        return "";
    }

    private static String firstNonBlank(String s) {
        if (s == null) {
            return null;
        }
        String t = s.trim();
        return t.isEmpty() ? null : t;
    }

    private static Properties integrationProps() {
        if (integrationProps != null) {
            return integrationProps;
        }
        synchronized (HxrAdminOrderSelectHttpTest.class) {
            if (integrationProps != null) {
                return integrationProps;
            }
            Properties p = new Properties();
            try (InputStream in =
                         HxrAdminOrderSelectHttpTest.class.getClassLoader().getResourceAsStream(CONFIG_RESOURCE)) {
                if (in != null) {
                    try (InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
                        p.load(reader);
                    }
                }
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            integrationProps = p;
            return integrationProps;
        }
    }
}
