package shop.alien.second.util;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import shop.alien.entity.second.vo.SecondGoodsVo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 二手商品搜索 AI 接口调用工具
 * 调用 life-manager 的 second_hand/search 接口进行智能搜索
 */
@Slf4j
@Component
@RequiredArgsConstructor
@RefreshScope
public class SecondHandSearchAiUtils {

    private final RestTemplate restTemplate;
    private final AiTaskUtils aiTaskUtils;

    @Value("${second-hand-search.base-url:http://124.93.18.180:9000/ai/life-manager/api/v1/second_hand/search}")
    private String secondHandSearchUrl;

    /**
     * 调用 AI 二手搜索接口（先获取 token 再请求）
     *
     * @param query            搜索关键词，如 "我想要二手手机"
     * @param latitude         纬度
     * @param longitude        经度
     * @param page             页码，从 1 开始
     * @param pageSize         每页条数
     * @param distanceOrder    距离排序，如 1
     * @param releaseTime      发布时间，ISO 格式如 "2025-12-01T00:00:00"，可为 null
     * @param shieldedGoodsIds 屏蔽商品 id 列表
     * @param userIdList       拉黑用户 id 列表
     * @return 搜索结果的 SecondGoodsVo 列表与总数；若调用失败返回 null
     */
    public SecondHandSearchResult search(String query, Double latitude, Double longitude, int page, int pageSize,
                                         Integer distanceOrder, String releaseTime,
                                         List<Integer> shieldedGoodsIds, List<Integer> userIdList) {
        if (query == null) {
            query = "";
        }
        if (latitude == null) {
            latitude = 39.914885;
        }
        if (longitude == null) {
            longitude = 116.403874;
        }

        String token = aiTaskUtils.getAccessToken();
        if (token == null) {
            log.warn("获取 AI 服务 token 失败，无法调用二手搜索接口");
            return null;
        }

        log.info("调用 AI 二手搜索接口, url={}, query={}, page={}, pageSize={}", secondHandSearchUrl, query, page, pageSize);

        Map<String, Object> body = new HashMap<>();
        body.put("query", query);
        body.put("latitude", latitude);
        body.put("longitude", longitude);
        body.put("page", page);
        body.put("page_size", pageSize);
        if (distanceOrder != null) {
            body.put("distance_order", distanceOrder);
        }
        if (releaseTime != null && !releaseTime.isEmpty()) {
            body.put("release_time", releaseTime);
        }
        body.put("shieldedGoodsIds", shieldedGoodsIds != null ? shieldedGoodsIds : new ArrayList<>());
        body.put("userIdList", userIdList != null ? userIdList : new ArrayList<>());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + token);
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(secondHandSearchUrl, requestEntity, String.class);
            if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
                log.warn("AI 二手搜索接口返回异常, status={}", response.getStatusCode());
                return null;
            }
            return parseSearchResponse(response.getBody());
        } catch (Exception e) {
            log.error("调用 AI 二手搜索接口失败", e);
            return null;
        }
    }

    /**
     * 解析 AI 接口返回体，将 list 中每项转为 SecondGoodsVo
     * 兼容常见格式：data.list[]、data.items[]，字段支持 id/title/price 等及下划线命名
     */
    private SecondHandSearchResult parseSearchResponse(String responseBody) {
        try {
            JSONObject root = JSONObject.parseObject(responseBody);
            JSONObject data = root.getJSONObject("data");
            if (data == null) {
                data = root;
            }
            long total = data.getLongValue("total");
            JSONArray list = data.getJSONArray("list");
            if (list == null) {
                list = data.getJSONArray("items");
            }
            List<SecondGoodsVo> records = new ArrayList<>();
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    Object item = list.get(i);
                    if (item instanceof JSONObject) {
                        SecondGoodsVo vo = jsonItemToSecondGoodsVo((JSONObject) item);
                        if (vo != null) {
                            records.add(vo);
                        }
                    }
                }
            }
            return new SecondHandSearchResult(records, total);
        } catch (Exception e) {
            log.warn("解析 AI 二手搜索返回失败, body={}", responseBody, e);
            return null;
        }
    }

    /**
     * 将 AI 返回的单条 JSON 转为 SecondGoodsVo（兼容 id/user_id/title/price 等及下划线命名）
     */
    private SecondGoodsVo jsonItemToSecondGoodsVo(JSONObject o) {
        Integer id = o.getInteger("id");
        if (id == null) {
            return null;
        }
        SecondGoodsVo vo = new SecondGoodsVo();
        vo.setId(id);
        vo.setUserId(o.getInteger("user_id") != null ? o.getInteger("user_id") : o.getInteger("userId"));
        vo.setTitle(o.getString("title"));
        vo.setHomeImage(o.getString("home_image") != null ? o.getString("home_image") : o.getString("homeImage"));
        vo.setDescription(o.getString("description"));
        String priceStr = o.getString("price");
        if (priceStr != null) {
            vo.setPrice(priceStr);
        }
        if (o.get("price") instanceof Number) {
            vo.setAmount(o.getBigDecimal("price"));
        }
        vo.setPosition(o.getString("position"));
        vo.setAddressText(o.getString("address_text") != null ? o.getString("address_text") : o.getString("addressText"));
        vo.setLikeCount(o.getInteger("like_count") != null ? o.getInteger("like_count") : o.getInteger("likeCount"));
        vo.setCollectCount(o.getInteger("collect_count") != null ? o.getInteger("collect_count") : o.getInteger("collectCount"));
        vo.setCategoryOneId(o.getInteger("category_one_id") != null ? o.getInteger("category_one_id") : o.getInteger("categoryOneId"));
        vo.setCategoryTwoId(o.getInteger("category_two_id") != null ? o.getInteger("category_two_id") : o.getInteger("categoryTwoId"));
        vo.setLabel(o.getString("label"));
        vo.setTopic(o.getString("topic"));
        vo.setGoodsStatus(o.getInteger("goods_status") != null ? o.getInteger("goods_status") : o.getInteger("goodsStatus"));
        vo.setReleaseTime(o.getDate("release_time") != null ? o.getDate("release_time") : o.getDate("releaseTime"));
        vo.setCreatedTime(o.getDate("created_time") != null ? o.getDate("created_time") : o.getDate("createdTime"));
        if (o.get("distance") != null) {
            vo.setDistance(o.get("distance") instanceof Number ? String.valueOf(o.getDouble("distance")) : o.getString("distance"));
        }
        if (o.getJSONArray("image_urls") != null) {
            vo.setImageUrls(o.getJSONArray("image_urls").toJavaList(String.class));
        } else if (o.getJSONArray("imageUrls") != null) {
            vo.setImageUrls(o.getJSONArray("imageUrls").toJavaList(String.class));
        } else if (o.getJSONArray("img_url") != null) {
            vo.setImgUrl(o.getJSONArray("img_url").toJavaList(String.class));
        }
        vo.setUserName(o.getString("user_name") != null ? o.getString("user_name") : o.getString("userName"));
        vo.setUserPhone(o.getString("user_phone") != null ? o.getString("user_phone") : o.getString("userPhone"));
        vo.setUserImage(o.getString("user_image") != null ? o.getString("user_image") : o.getString("userImage"));
        vo.setCategoryOneName(o.getString("category_one_name") != null ? o.getString("category_one_name") : o.getString("categoryOneName"));
        vo.setCategoryTwoName(o.getString("category_two_name") != null ? o.getString("category_two_name") : o.getString("categoryTwoName"));
        return vo;
    }

    /**
     * AI 搜索返回结果：当前页 SecondGoodsVo 列表 + 总条数
     */
    public static class SecondHandSearchResult {
        private final List<SecondGoodsVo> records;
        private final long total;

        public SecondHandSearchResult(List<SecondGoodsVo> records, long total) {
            this.records = records != null ? records : new ArrayList<>();
            this.total = total;
        }

        public List<SecondGoodsVo> getRecords() {
            return records;
        }

        public long getTotal() {
            return total;
        }
    }
}
