package com.bb.service;

import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class EvoJsonService {

	private final ObjectMapper mapper;

    public EvoJsonService(ObjectMapper objectMapper) {
        this.mapper = objectMapper;
    }
    
    public String convert(String rawJson) {
    	try {
            JsonNode root = mapper.readTree(rawJson);
            ObjectNode unified = mapper.createObjectNode();

            // 1. Transaction ID
            String txId = root.has("id") ? root.get("id").asText() : "";
            unified.put("transaction_id", txId);

            // 2. Game Info
            ObjectNode gameInfo = mapper.createObjectNode();
            gameInfo.put("provider", root.path("gameProvider").asText("evolution"));
            gameInfo.put("category", root.path("gameType").asText("unknown"));
            gameInfo.put("started_at", root.path("startedAt").asText(""));
            gameInfo.put("settled_at", root.path("settledAt").asText(""));
            unified.set("game_info", gameInfo);

            // 3. Game Result (가변적인 결과 처리)
            ObjectNode gameResult = mapper.createObjectNode();
            JsonNode rawResult = root.path("result");
            
            // outcome 추출 (문자열 혹은 숫자 대응)
            if (rawResult.has("outcome")) {
                gameResult.set("outcome", rawResult.get("outcome"));
            }

            // 상세 데이터 (Payload) 구성
            ObjectNode payload = mapper.createObjectNode();
            String gameType = gameInfo.get("category").asText();

            switch (gameType) {
                case "baccarat":
                case "dragontiger":
                    if (rawResult.has("player")) payload.set("player", rawResult.get("player"));
                    if (rawResult.has("banker")) payload.set("banker", rawResult.get("banker"));
                    if (rawResult.has("dragon")) payload.set("dragon", rawResult.get("dragon"));
                    if (rawResult.has("tiger")) payload.set("tiger", rawResult.get("tiger"));
                    break;
                case "sicbo":
                case "lightningdice":
                    ArrayNode dices = mapper.createArrayNode();
                    if (rawResult.has("first")) dices.add(rawResult.get("first"));
                    if (rawResult.has("second")) dices.add(rawResult.get("second"));
                    if (rawResult.has("third")) dices.add(rawResult.get("third"));
                    payload.set("dices", dices);
                    break;
                case "crazytime":
                case "funkytime":
                case "lightningstorm":
                    if (rawResult.has("wheelResult")) payload.set("wheel", rawResult.get("wheelResult"));
                    break;
                case "racetrack":
                    if (rawResult.has("lanes")) payload.set("rankings", rawResult.get("lanes"));
                    break;
                case "crazyballs":
                case "monopolybigballer":
                    if (rawResult.has("drawnBalls")) payload.set("drawn_balls", rawResult.get("drawnBalls"));
                    break;
                default:
                    // 정의되지 않은 게임은 결과 객체 통째로 저장
                    payload.set("raw_details", rawResult);
            }
            gameResult.set("payload", payload);
            unified.set("game_result", gameResult);

            // 4. Bet Details (참가자 배열에서 추출)
            ArrayNode betDetails = mapper.createArrayNode();
            JsonNode participants = root.path("participants");
            if (participants.isArray() && participants.size() > 0) {
                JsonNode bets = participants.get(0).path("bets");
                for (JsonNode bet : bets) {
                    ObjectNode simplifiedBet = mapper.createObjectNode();
                    simplifiedBet.put("code", bet.path("code").asText());
                    simplifiedBet.put("stake", bet.path("stake").asLong());
                    simplifiedBet.put("payout", bet.path("payout").asDouble());
                    simplifiedBet.put("placed_at", bet.path("placedOn").asText());
                    betDetails.add(simplifiedBet);
                }
            }
            unified.set("bet_details", betDetails);

            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(unified);

        } catch (Exception e) {
            return "{\"error\": \"데이터 변환 중 오류 발생: " + e.getMessage() + "\"}";
        }
    }
}
