package com.goldenchart.service;

import com.goldenchart.dto.TradeSignalDto;
import com.goldenchart.entity.GcTradeSignal;
import com.goldenchart.repository.GcTradeSignalRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 매매 시그널 이력 서비스.
 * 실시간 전략 체크(LiveStrategyEvaluator / LiveStrategyScheduler)에서
 * BUY/SELL 시그널이 발생하면 이 서비스를 통해 DB에 저장한다.
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class TradeSignalService {

    private final GcTradeSignalRepository repo;
    private final FcmPushService fcmPushService;

    // ── 저장 ─────────────────────────────────────────────────────────────────

    public TradeSignalDto save(String deviceId, Long userId, String market,
                               Long strategyId, String strategyName,
                               String signalType, double price,
                               long candleTime, String candleType,
                               String executionType) {
        GcTradeSignal entity = GcTradeSignal.builder()
                .deviceId(deviceId)
                .userId(userId)
                .market(market)
                .strategyId(strategyId)
                .strategyName(strategyName)
                .signalType(signalType)
                .price(price)
                .candleTime(candleTime)
                .candleType(candleType)
                .executionType(executionType)
                .build();
        GcTradeSignal saved = repo.save(entity);
        log.info("[TradeSignal] saved {} {} @ {} market={}", signalType, candleType, price, market);
        if (deviceId != null) {
            fcmPushService.sendTradeSignalIfEnabled(
                    deviceId, userId, market, signalType, price, strategyName, saved.getId());
        }
        return toDto(saved);
    }

    // ── 조회 ─────────────────────────────────────────────────────────────────

    @Transactional(readOnly = true)
    public List<TradeSignalDto> list(Long userId, String deviceId) {
        List<GcTradeSignal> list = userId != null
                ? repo.findByUserIdOrderByCreatedAtDesc(userId)
                : repo.findByDeviceIdOrderByCreatedAtDesc(deviceId != null ? deviceId : "");
        return list.stream().map(this::toDto).toList();
    }

    @Transactional(readOnly = true)
    public List<TradeSignalDto> listByMarket(Long userId, String deviceId, String market) {
        return repo.findByDeviceIdAndMarketOrderByCreatedAtDesc(
                deviceId != null ? deviceId : "", market)
                .stream().map(this::toDto).toList();
    }

    // ── 변환 ─────────────────────────────────────────────────────────────────

    private TradeSignalDto toDto(GcTradeSignal e) {
        return TradeSignalDto.builder()
                .id(e.getId())
                .market(e.getMarket())
                .strategyId(e.getStrategyId())
                .strategyName(e.getStrategyName())
                .signalType(e.getSignalType())
                .price(e.getPrice())
                .candleTime(e.getCandleTime())
                .candleType(e.getCandleType())
                .executionType(e.getExecutionType())
                .createdAt(e.getCreatedAt() != null ? e.getCreatedAt().toString() : null)
                .build();
    }
}
