package com.goldenchart.service;

import com.goldenchart.entity.GcAppSettings;
import com.goldenchart.entity.GcLiveStrategySettings;
import com.goldenchart.repository.GcLiveStrategySettingsRepository;
import com.goldenchart.storage.Ta4jStorage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.Optional;
import java.util.Set;

/**
 * 종목별 전략 평가 분봉 — DB gc_live_strategy_settings.candle_type.
 */
@Service
@RequiredArgsConstructor
public class LiveStrategyTimeframeService {

    private static final Set<String> ALLOWED = Ta4jStorage.CANDLE_TYPE_MAP.keySet();

    private final GcLiveStrategySettingsRepository repo;
    private final AppSettingsService appSettingsService;

    @Transactional(readOnly = true)
    public String resolveCandleType(String market, Long userId, String deviceId) {
        Optional<GcLiveStrategySettings> row = find(userId, deviceId, market);
        if (row.isPresent() && row.get().getCandleType() != null) {
            return normalize(row.get().getCandleType());
        }
        GcAppSettings app = appSettingsService.getEntity(userId, deviceId);
        String tf = app.getDefaultTimeframe();
        if (tf != null) {
            String mapped = mapChartTfToCandleType(tf);
            if (mapped != null) return mapped;
        }
        return "1m";
    }

    /**
     * 워커 스레드 등 user/device 컨텍스트 없을 때 — 해당 마켓 활성 설정의 candle_type.
     */
    @Transactional(readOnly = true)
    public String resolveCandleTypeForMarket(String market) {
        return repo.findActiveByMarket(market).stream()
                .filter(s -> s.getCandleType() != null && !s.getCandleType().isBlank())
                .max(Comparator.comparing(
                        GcLiveStrategySettings::getUpdatedAt,
                        Comparator.nullsLast(Comparator.naturalOrder())))
                .map(GcLiveStrategySettings::getCandleType)
                .map(LiveStrategyTimeframeService::normalize)
                .orElse("1m");
    }

    public static String normalize(String candleType) {
        if (candleType == null || candleType.isBlank()) return "1m";
        String c = candleType.trim().toLowerCase();
        if ("1d".equals(c)) return "1d";
        if ("1h".equals(c)) return "1h";
        if ("4h".equals(c)) return "4h";
        if (ALLOWED.contains(c)) return c;
        return "1m";
    }

    private static String mapChartTfToCandleType(String chartTf) {
        return switch (chartTf) {
            case "1m", "3m", "5m", "15m", "30m" -> chartTf;
            case "1h", "4h" -> chartTf;
            case "1D" -> "1d";
            case "1W", "1M" -> "1d";
            default -> null;
        };
    }

    private Optional<GcLiveStrategySettings> find(Long userId, String deviceId, String market) {
        if (userId != null) return repo.findByUserIdAndMarket(userId, market);
        if (deviceId != null && !deviceId.isBlank())
            return repo.findByDeviceIdAndMarket(deviceId, market);
        return Optional.empty();
    }
}
