package com.rj.dto.hxr;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.rj.entity.LbGoods;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 兼容第三方 {@code data} 两种形态：
 * <ul>
 *   <li>对象：{@code {"list":[...],"hasmore":true,"last_page":13}}</li>
 *   <li>数组：{@code [...]}（按每页条数推断是否还有下一页）</li>
 * </ul>
 */
public class HxrLbGoodsPageDataDeserializer extends JsonDeserializer<HxrLbGoodsPageData> {

    private static final int DEFAULT_PAGE_SIZE = 20;

    @Override
    public HxrLbGoodsPageData deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        if (node == null || node.isNull()) {
            return emptyPage();
        }
        if (node.isArray()) {
            if (node.isEmpty()) {
                return emptyPage();
            }
            if (node.get(0).isTextual() || node.get(0).isNumber()) {
                return emptyPage();
            }
            List<LbGoods> list = readGoodsList(ctxt, node);
            boolean hasMore = list.size() >= DEFAULT_PAGE_SIZE;
            int lastPage = hasMore ? Integer.MAX_VALUE : 1;
            return new HxrLbGoodsPageData(list, hasMore, lastPage);
        }
        JsonNode listNode = node.get("list");
        List<LbGoods> list = listNode != null && listNode.isArray()
                ? readGoodsList(ctxt, listNode)
                : List.of();
        boolean hasmore = node.path("hasmore").asBoolean(false);
        int lastPage = node.path("last_page").asInt(1);
        if (lastPage < 1) {
            lastPage = 1;
        }
        return new HxrLbGoodsPageData(list, hasmore, lastPage);
    }

    private static List<LbGoods> readGoodsList(DeserializationContext ctxt, JsonNode listNode)
            throws IOException {
        CollectionType listType =
                ctxt.getTypeFactory().constructCollectionType(List.class, LbGoods.class);
        List<LbGoods> list = ctxt.readTreeAsValue(listNode, listType);
        return list != null ? list : new ArrayList<>();
    }

    private static HxrLbGoodsPageData emptyPage() {
        return new HxrLbGoodsPageData(List.of(), false, 1);
    }
}
