package com.bizzan.bitrade.consumer;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.bizzan.bitrade.entity.CoinThumb;
import com.bizzan.bitrade.entity.ExchangeWallet;
import com.bizzan.bitrade.service.ExchangeWalletService;
import com.bizzan.bitrade.service.SpotWalletSnapshotService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class SpotListener implements MessageListener {

	@Autowired
	private RedisTemplate redisTemplate;
	@Autowired
	private ExchangeWalletService exchangeWalletService;
	@Autowired
	private SpotWalletSnapshotService spotWalletSnapshotService;

	private Map<String, BigDecimal> currentPriceMap = new ConcurrentHashMap<>();
	private Map<String, BigDecimal> clearPriceMap   = new ConcurrentHashMap<>();

	@Override
	public void onMessage(Message message, byte[] pattern) {
		byte[] messageBody = message.getBody();
		Object msg = redisTemplate.getValueSerializer().deserialize(messageBody);
		CoinThumb thumb = JSON.parseObject(msg.toString(), CoinThumb.class);
		thumb.setTime(System.currentTimeMillis() / 1000);
		this.updatePrice(thumb.getSymbol(), thumb.getClose());
	}

	public void updatePrice(String symbol, BigDecimal price) {
		currentPriceMap.put(symbol, price);
	}

	public Map<String, BigDecimal> getCurrentPriceMap() {
		return currentPriceMap;
	}

	public Map<String, BigDecimal> getClearPriceMap() {
		return clearPriceMap;
	}

	/**
	 * 零点任务：
	 * 1. 将当前价格快照为 clearPriceMap（作为次日计算今日盈亏的基准价格）
	 * 2. 遍历所有有现货账户的会员，保存持仓快照到 spot_wallet_snapshot
	 * 3. 清理 30 天以前的旧快照数据
	 */
	@Scheduled(cron = "0 0 0 * * ?")
	public void recordClearPrice() {
		// 1. 保存今日收盘价作为明日基准
		clearPriceMap.putAll(currentPriceMap);
		log.info("[SpotListener] clearPriceMap updated, {} coins", clearPriceMap.size());

		// 2. 现货持仓快照
		takeSpotWalletSnapshot();

		// 3. 清理旧数据（保留 30 天）
		try {
			spotWalletSnapshotService.cleanOldSnapshots(30);
		} catch (Exception e) {
			log.error("[SpotListener] cleanOldSnapshots error", e);
		}
	}

	private void takeSpotWalletSnapshot() {
		if (clearPriceMap.isEmpty()) {
			log.warn("[SpotListener] clearPriceMap is empty, skip spot wallet snapshot");
			return;
		}
		try {
			List<Long> memberIds = exchangeWalletService.findAllMemberIds();
			log.info("[SpotListener] takeSpotWalletSnapshot for {} members", memberIds.size());
			for (Long memberId : memberIds) {
				try {
					List<ExchangeWallet> wallets = exchangeWalletService.findWallets(memberId);
					spotWalletSnapshotService.saveSnapshot(memberId, wallets, clearPriceMap);
				} catch (Exception e) {
					log.error("[SpotListener] snapshot error for memberId={}", memberId, e);
				}
			}
		} catch (Exception e) {
			log.error("[SpotListener] takeSpotWalletSnapshot error", e);
		}
	}
}
