package com.copy.trade.util;

import com.alibaba.fastjson.JSONObject;
import com.copy.trade.constant.DogeApi;
import com.copy.trade.entity.dto.DogeAsset;
import com.copy.trade.entity.dto.DogeContractRes;
import com.copy.trade.entity.dto.Symbol;
import com.copy.trade.entity.vo.NoticeVo;
import com.copy.trade.entity.vo.TraderTotalVo;
import com.mysql.cj.protocol.x.Notice;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DogeContractUtils {
    private static final Logger log = LoggerFactory.getLogger(DogeContractUtils.class);

    public static List<Symbol> symbolList(String host) {
        String url = host + DogeApi.SYMBOL;
        String responseStr = null;
        try {
            responseStr = HttpUtils.get(url);
        } catch (Exception e) {
            log.error("查询合约交易对失败, 调用异常, url={}, 响应数据:{}", url, responseStr, e);
            return null;
        }
        if (responseStr == null) {
            log.error("查询合约交易对失败, 响应为null, url={}", url);
            return null;
        }
        String trimmed = responseStr.trim();
        if (trimmed.length() == 0) {
            // 防止 fastjson 出现 "exepct '[', but EOF" 异常
            log.error("查询合约交易对失败, 响应为空字符串, url={}", url);
            return null;
        }
        if (!trimmed.startsWith("[")) {
            // doge 返回的不是数组，记录原始内容方便排查
            log.error("查询合约交易对失败, 响应格式非数组, url={}, responseStr={}", url, trimmed);
            return null;
        }
        try {
            return JSONObject.parseArray(trimmed, Symbol.class);
        } catch (com.alibaba.fastjson.JSONException e) {
            // 捕获 fastjson 解析异常，避免抛出到 GlobalExceptionHandler
            log.error("解析合约交易对响应失败, JSON解析异常, url={}, responseStr={}, error={}", url, trimmed, e.getMessage(), e);
            return null;
        } catch (Exception e) {
            // 捕获其他异常
            log.error("解析合约交易对响应失败, 未知异常, url={}, responseStr={}", url, trimmed, e);
            return null;
        }
    }


    public static BigDecimal asset(String url, Long memberId) {
        return asset(url, memberId, null);
    }

    public static BigDecimal asset(String url, Long memberId, Map<String, String> headers) {
        // doge contract-asset-new: GET ?memberId=，返回 MessageResult<TradingAccount>，需带 session/token
        if (url != null && url.contains("contract-asset-new")) {
            return assetContractNew(url, memberId, headers);
        }
        // 旧协议：POST，header ids
        Map<String,String> headerMap= new HashMap<String,String>();
        Long[] ids = {memberId};
        headerMap.put(DogeApi.MEMBER_ID,Arrays.toString(ids));
        String responseStr = null;
        try{
            responseStr = HttpUtils.doPost(url, headerMap);
        }catch (Exception e){
            log.error("查询用户合约资产失败,响应数据:{}",responseStr);
            return null;
        }
        if(responseStr == null || responseStr.length() < 2){
            log.error("查询用户合约资产失败,响应数据为空或格式不正确:{}",responseStr);
            return null;
        }
        try {
            JSONObject pa=JSONObject.parseObject(responseStr.substring(1, responseStr.length()- 1));
            BigDecimal balance = new BigDecimal("0");
            if(pa != null) {
                balance = (StringUtils.isEmpty(pa.getString("balance")) ? new BigDecimal("0") : new BigDecimal(pa.getString("balance")))
                        .add(StringUtils.isEmpty(pa.getString("frozenBalance")) ? new BigDecimal("0") : new BigDecimal(pa.getString("frozenBalance")))
                        .add(StringUtils.isEmpty(pa.getString("frozenMargin")) ? new BigDecimal("0") : new BigDecimal(pa.getString("frozenMargin")));
            }
            return balance;
        } catch (Exception e) {
            log.error("解析合约资产响应失败:{}", responseStr);
            return null;
        }
    }

    /** doge /swap/wallet-new/contract-asset-new：GET ?memberId=，需带 x-auth-token 和 Cookie 以保持 session */
    private static BigDecimal assetContractNew(String baseUrl, Long memberId, Map<String, String> headers) {
        String url = baseUrl + (baseUrl.contains("?") ? "&" : "?") + "memberId=" + memberId;
        String responseStr = null;
        try {
            responseStr = HttpUtils.get(url, headers);
        } catch (Exception e) {
            log.error("查询用户合约资产失败(contract-asset-new),memberId={}", memberId, e);
            return null;
        }
        if (responseStr == null) {
            return null;
        }
        try {
            JSONObject json = JSONObject.parseObject(responseStr);
            if (json == null) {
                return BigDecimal.ZERO;
            }
            Integer code = json.getInteger("code");
            if (code != null && code != 0 && code != DogeApi.SUCCESS) {
                log.warn("contract-asset-new 接口返回异常 code={}, message={}", code, json.getString("message"));
                return null;
            }
            Object data = json.get("data");
            if (data != null) {
                if (data instanceof JSONObject) {
                    JSONObject pa = (JSONObject) data;
                    return (StringUtils.isEmpty(pa.getString("balance")) ? BigDecimal.ZERO : new BigDecimal(pa.getString("balance")))
                            .add(StringUtils.isEmpty(pa.getString("frozenBalance")) ? BigDecimal.ZERO : new BigDecimal(pa.getString("frozenBalance")))
                            .add(StringUtils.isEmpty(pa.getString("frozenMargin")) ? BigDecimal.ZERO : new BigDecimal(pa.getString("frozenMargin")));
                }
                if (data instanceof Number) {
                    return new BigDecimal(data.toString());
                }
            }
        } catch (Exception e) {
            log.error("解析contract-asset-new响应失败:{}", responseStr);
        }
        return BigDecimal.ZERO;
    }
    
    public static String checkTrader(String url, Long memberId, BigDecimal minBalance) {
        Map<String,String> headerMap= new HashMap<String,String>();
        Long[] ids = {memberId};
        headerMap.put(DogeApi.MEMBER_ID,Arrays.toString(ids));
        String responseStr = null;
        try{
            responseStr = HttpUtils.doPost(url, headerMap);
        }catch (Exception e){
            log.error("查询用户合约资产失败,响应数据:{}",responseStr);
            return null;
        }
        // 检查响应字符串是否为空或长度不足
        if(responseStr == null || responseStr.length() < 2){
            log.error("查询用户合约资产失败,响应数据为空或格式不正确:{}",responseStr);
            return null;
        }
        //解析接口数据
        JSONObject pa=JSONObject.parseObject(responseStr.substring(1, responseStr.length()- 1));
        BigDecimal balance = new BigDecimal("0");
        if(pa != null) {
        	balance = (StringUtils.isEmpty(pa.getString("balance")) ? new BigDecimal("0") : new BigDecimal(pa.getString("balance")))
        			.add(StringUtils.isEmpty(pa.getString("frozenBalance")) ? new BigDecimal("0") : new BigDecimal(pa.getString("frozenBalance")))
        			.add(StringUtils.isEmpty(pa.getString("frozenMargin")) ? new BigDecimal("0") : new BigDecimal(pa.getString("frozenMargin")));
        }
        if (balance.compareTo(minBalance) < 0) {
        	return "chk.applyTrader.balance.insufficient";
        }
        if (pa != null && pa.getInteger("positionType") != null && pa.getInteger("positionType") == 1) {
        	return "chk.applyTrader.positionType.incorrect";
        }
        return "";
    }
    
    public static Map<String,BigDecimal> getAllasset(String url, List<Long> memberIds) {
        Map<String,String> headerMap= new HashMap<String,String>();
        headerMap.put(DogeApi.MEMBER_ID,memberIds.toString());
        String responseStr = null;
        try{
            responseStr = HttpUtils.doPost(url, headerMap);
        }catch (Exception e){
            log.error("查询用户各种资产失败,响应数据:{}",responseStr);
            return null;
        }
        log.info("调用资产接口:memberIds:{},返回值:{}",memberIds, responseStr);
        Map<String,BigDecimal> assetMap = new HashMap<String,BigDecimal>();
        BigDecimal totalBalance = new BigDecimal("0");
        BigDecimal spotBalance = new BigDecimal("0");
        BigDecimal swapBalance = new BigDecimal("0");
        BigDecimal followBalance = new BigDecimal("0");
    	List<JSONObject> list = new ArrayList<JSONObject>();
		try {
			list = JSONObject.parseArray(responseStr, JSONObject.class);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("调用资产接口发生异常:" + e.getStackTrace(), e);
			return assetMap;
		}      
		if(list == null || list.isEmpty()) {
			return assetMap;
		}
    	for (JSONObject balance : list) {
    		totalBalance =totalBalance.add((StringUtils.isEmpty(balance.getString("totalBalance")) ? new BigDecimal("0") : new BigDecimal(balance.getString("totalBalance"))));
    		spotBalance =spotBalance.add((StringUtils.isEmpty(balance.getString("spotBalance")) ? new BigDecimal("0") : new BigDecimal(balance.getString("spotBalance"))));
    		swapBalance =swapBalance.add((StringUtils.isEmpty(balance.getString("swapBalance")) ? new BigDecimal("0") : new BigDecimal(balance.getString("swapBalance"))));
    		followBalance =followBalance.add((StringUtils.isEmpty(balance.getString("followBalance")) ? new BigDecimal("0") : new BigDecimal(balance.getString("followBalance"))));
    	}
    	assetMap.put("totalBalance", totalBalance);
    	assetMap.put("spotBalance", spotBalance);
    	assetMap.put("swapBalance", swapBalance);
    	assetMap.put("followBalance", followBalance);
        return assetMap;
    }
    
    
    public static BigDecimal assetAll(String url, List<Long> memberIds) {
    	Map<String,String> headerMap= new HashMap<String,String>();
    	headerMap.put(DogeApi.MEMBER_ID,memberIds.toString());
    	String responseStr = null;
    	try{
    		responseStr = HttpUtils.doPost(url, headerMap);
    	}catch (Exception e){
    		log.error("查询用户合约资产失败,响应数据:{}",responseStr);
    		return new BigDecimal("0");
    	}
    	//解析接口数据
    	List<JSONObject> list = JSONObject.parseArray(responseStr, JSONObject.class);

    	BigDecimal balance = new BigDecimal("0");
        for (JSONObject balanceReturn : list) {
        	balance =balance.add((StringUtils.isEmpty(balanceReturn.getString("balance")) ? new BigDecimal("0") : new BigDecimal(balanceReturn.getString("balance")))
        			.add(StringUtils.isEmpty(balanceReturn.getString("frozenBalance")) ? new BigDecimal("0") : new BigDecimal(balanceReturn.getString("frozenBalance")))
        			.add(StringUtils.isEmpty(balanceReturn.getString("frozenMargin")) ? new BigDecimal("0") : new BigDecimal(balanceReturn.getString("frozenMargin"))));
    	}
    	return balance;
    }
    
    //获取跟单总转入转出
    public static TraderTotalVo getFollowInOut(String url, List<Long> memberIds) {
    	TraderTotalVo traderTotalVo = new TraderTotalVo();
    	Map<String,String> headerMap= new HashMap<String,String>();
    	//Long[] ids = {traderTotalVo.getMemberId()};
    	headerMap.put(DogeApi.MEMBER_ID,memberIds.toString());
    	String responseStr = null;
    	try{
    		responseStr = HttpUtils.doPost(url, headerMap);
    	}catch (Exception e){
    		log.error("查询跟单总转入转出失败,响应数据:{}",responseStr);
    	}
    	//解析接口数据
    	List<JSONObject> list = JSONObject.parseArray(responseStr, JSONObject.class);
    	BigDecimal inAmount = new BigDecimal("0");
    	BigDecimal outAmount = new BigDecimal("0");
    	String username = null;
    	for (JSONObject inOutReturn : list) {
    		inAmount =inAmount.add(StringUtils.isEmpty(inOutReturn.getString("inAmount")) ? new BigDecimal("0") : new BigDecimal(inOutReturn.getString("inAmount")));
    		outAmount =outAmount.add(StringUtils.isEmpty(inOutReturn.getString("outAmount")) ? new BigDecimal("0") : new BigDecimal(inOutReturn.getString("outAmount")));
    		username = inOutReturn.getString("username");
    	}
    				
    	traderTotalVo.setInAmount(inAmount);
    	traderTotalVo.setOutAmount(outAmount);
    	traderTotalVo.setUsername(username);
    	return traderTotalVo;
    }
    
    public static Boolean vailSpecialTrader(String url, String token,Long minFollowAmount) {
    	Map<String,String> headersMap= new HashMap<String,String>();
    	headersMap.put(DogeApi.TOKEN_NAME,token);
    	Map<String,String> paramsMap= new HashMap<String,String>();
    	if(minFollowAmount != null) {
    		paramsMap.put(DogeApi.MIN_FOLLOW_AMOUNT, minFollowAmount.toString());
    	}
        String responseStr = null;
        try{
            responseStr = HttpUtils.post(url, headersMap, paramsMap);
        }catch (Exception e){
            log.error("校验跟随超级交易员失败,响应数据:{}",responseStr);
            return false;
        }
        JSONObject pa;
		try {
			pa = JSONObject.parseObject(responseStr);
		} catch (Exception e) {
			return false;
		}
        String date = pa.getString("data");
        if(!StringUtils.isEmpty(date) && "true".equals(date)) {
        	return true;
        }
        return false;
    }
    
    
  //获取跟单总转入转出
    public static List<NoticeVo> getNotice(String listUrl,String detailUrl,String id,String language) {
    	List<NoticeVo> arrayList = new ArrayList<NoticeVo>();
    	Map<String,String> headerMap= new HashMap<String,String>();
        headerMap.put("id",id);
        headerMap.put("language",language);
        String responseStr = null;
        try{
            responseStr = HttpUtils.doPost(listUrl, headerMap);
        }catch (Exception e){
        	log.error("获取通告内容失败,响应数据:{}",responseStr);
        	return null;
        }
        //System.out.println(responseStr);
    	//解析接口数据
        if(!StringUtils.isEmpty(responseStr) && responseStr.contains(",[")) {
        	String[] split = responseStr.split(",\\[");
        	responseStr = split[0].substring(1);
        }
        //JSONObject pa = JSONObject.parseObject(responseStr);
    	List<JSONObject> list = JSONObject.parseArray(responseStr, JSONObject.class);
    	String title = null;
    	String address = null;
    	int i = 0;
    	for (JSONObject noticeObject : list) {
    		if(i > 4) {
    			break;
    		}
    		NoticeVo noticeVo = new NoticeVo();
    		noticeVo.setTitle(noticeObject.getString("title"));
    		noticeVo.setAddress(detailUrl + noticeObject.getString("id"));
    		arrayList.add(noticeVo);
    		i++ ;
    	}
    				
    	return arrayList;
    }
    
    
	 public static void main(String[] args) {
	 }

}
