package com.fs.xiaoshouyi;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class XiaoShouYiApiUtils {

    // 业务接口路径
    private static final String GET_LINK_PATH = "/rest/mc/v2.0/cms/api/buried-point/generateMaterialTrackLink";
    private static final String SEND_PATH = "/rest/mc/v2.0/cms/api/buried-point/forwarded";

    /**
     * 发送场景枚举
     */
    public static class ForwardType {
        public static final int PRE_SEND = -1;           // 预发送，不纳入统计
        public static final int SINGLE_CHAT = 1;         // 单聊
        public static final int GROUP_CHAT = 2;          // 群聊或群发
        public static final int FORWARD = 3;             // 转发
        public static final int MOMENTS = 4;             // 客户朋友圈
        public static final int OFFICIAL_ACCOUNT = 5;    // 公众号群发
        public static final int MINI_PROGRAM = 6;        // 名片小程序
    }

    /**
     * 生成素材追踪链接
     */
    public static GenerateLinkResponse generateMaterialTrackLink(List<Long> materialIds, Long sendUserId) {
        String authHeader = XiaoShouYiOAuthUtils.getAuthorizationHeader();
        if (authHeader == null) {
            log.error("未获取到有效token");
            return GenerateLinkResponse.error("未获取到有效token，请先授权");
        }

        String url = XiaoShouYiOAuthUtils.getApiBaseUrl() + GET_LINK_PATH;

        Map<String, Object> body = new HashMap<>();
        body.put("materialIdList", materialIds);
        body.put("sendUserId", sendUserId);

        String bodyJson = JSONUtil.toJsonStr(body);
        log.info("请求URL: {}", url);
        log.info("请求参数: {}", bodyJson);

        try (HttpResponse response = HttpRequest.post(url)
                .header("Content-Type", "application/json")
                .header("Authorization", authHeader)
                .body(bodyJson)
                .timeout(30000)
                .execute()) {

            String result = response.body();
            log.info("响应结果: {}", result);

            if (response.getStatus() == 200) {
                return parseGenerateResponse(result);
            } else if (response.getStatus() == 401) {
                log.warn("token失效，清除缓存");
                XiaoShouYiOAuthUtils.clearCache();
                return GenerateLinkResponse.error("token失效，请重新授权");
            } else {
                return GenerateLinkResponse.error("HTTP状态码: " + response.getStatus() + ", 响应: " + result);
            }
        } catch (Exception e) {
            log.error("请求异常", e);
            return GenerateLinkResponse.error(e.getMessage());
        }
    }

    /**
     * 素材发送确认
     */
    public static SendConfirmResponse sendConfirm(Long forwardId, Integer forwardType) {
        String authHeader = XiaoShouYiOAuthUtils.getAuthorizationHeader();
        if (authHeader == null) {
            return SendConfirmResponse.error("未获取到有效token，请先授权");
        }

        String url = String.format("%s%s?forwardId=%d&forwardType=%d",
                XiaoShouYiOAuthUtils.getApiBaseUrl(), SEND_PATH, forwardId, forwardType);

        log.info("请求URL: {}", url);

        try (HttpResponse response = HttpRequest.get(url)
                .header("Content-Type", "application/json")
                .header("Authorization", authHeader)
                .timeout(30000)
                .execute()) {

            String result = response.body();
            log.info("响应结果: {}", result);

            if (response.getStatus() == 200) {
                return parseSendResponse(result);
            } else if (response.getStatus() == 401) {
                XiaoShouYiOAuthUtils.clearCache();
                return SendConfirmResponse.error("token失效，请重新授权");
            } else {
                return SendConfirmResponse.error("HTTP状态码: " + response.getStatus());
            }
        } catch (Exception e) {
            log.error("请求异常", e);
            return SendConfirmResponse.error(e.getMessage());
        }
    }

    // ==================== 解析方法 ====================

    private static GenerateLinkResponse parseGenerateResponse(String jsonStr) {
        JSONObject json = JSONUtil.parseObj(jsonStr);
        GenerateLinkResponse response = new GenerateLinkResponse();
        response.setSuccess(json.getBool("success", false));
        response.setCode(json.getStr("code"));
        response.setMsg(json.getStr("msg"));

        if (response.isSuccess() && json.containsKey("data")) {
            JSONObject data = json.getJSONObject("data");

            // 解析成功获取链接的素材
            if (data.containsKey("trackedMaterials")) {
                response.setTrackedMaterials(parseMaterialList(data.getJSONArray("trackedMaterials"), true));
            }

            // 解析无法获取链接的素材
            if (data.containsKey("untrackedMaterials")) {
                response.setUntrackedMaterials(parseMaterialList(data.getJSONArray("untrackedMaterials"), false));
            }
        }

        return response;
    }

    private static List<MaterialTrackItem> parseMaterialList(cn.hutool.json.JSONArray array, boolean hasTrackLink) {
        if (array == null || array.isEmpty()) {
            return java.util.Collections.emptyList();
        }

        return array.stream().map(obj -> {
            JSONObject item = (JSONObject) obj;
            MaterialTrackItem trackItem = new MaterialTrackItem();
            trackItem.setMaterialId(item.getLong("materialId"));
            trackItem.setMaterialType(item.getInt("materialType"));

            if (hasTrackLink && item.containsKey("trackLink")) {
                JSONObject link = item.getJSONObject("trackLink");
                TrackLinkInfo info = new TrackLinkInfo();
                info.setForwardId(link.getLong("forwardId"));
                info.setRedirectUrl(link.getStr("redirectUrl"));
                trackItem.setTrackLink(info);
            }

            return trackItem;
        }).collect(Collectors.toList());
    }

    private static SendConfirmResponse parseSendResponse(String jsonStr) {
        JSONObject json = JSONUtil.parseObj(jsonStr);
        SendConfirmResponse response = new SendConfirmResponse();
        response.setSuccess(json.getBool("success", false));
        response.setCode(json.getStr("code"));
        response.setMsg(json.getStr("msg"));
        return response;
    }

    // ==================== 内部类 ====================

    @Data
    public static class GenerateLinkResponse {
        private boolean success;
        private String code;
        private String msg;
        private List<MaterialTrackItem> trackedMaterials;
        private List<MaterialTrackItem> untrackedMaterials;

        public static GenerateLinkResponse error(String errorMsg) {
            GenerateLinkResponse resp = new GenerateLinkResponse();
            resp.setSuccess(false);
            resp.setCode("500");
            resp.setMsg(errorMsg);
            return resp;
        }

        public boolean hasTrackedMaterials() {
            return trackedMaterials != null && !trackedMaterials.isEmpty();
        }
    }

    @Data
    public static class SendConfirmResponse {
        private boolean success;
        private String code;
        private String msg;

        public static SendConfirmResponse error(String errorMsg) {
            SendConfirmResponse resp = new SendConfirmResponse();
            resp.setSuccess(false);
            resp.setCode("500");
            resp.setMsg(errorMsg);
            return resp;
        }
    }

    @Data
    public static class MaterialTrackItem {
        private Long materialId;
        private Integer materialType;
        private TrackLinkInfo trackLink;
    }

    @Data
    public static class TrackLinkInfo {
        private Long forwardId;
        private String redirectUrl;
    }
}