package top.baogutang.strategy.strategies;

import top.baogutang.strategy.commons.enums.Timeframe;
import top.baogutang.strategy.models.Kline;
import top.baogutang.strategy.models.Signal;
import top.baogutang.strategy.models.StrategyContext;
import top.baogutang.strategy.services.IndicatorService;

import java.util.*;

public class StrategyLowReboundLong implements Strategy {
    private final double s1High, s1Low, s2High, s2Low;

    public StrategyLowReboundLong(double s1High, double s1Low, double s2High, double s2Low) {
        this.s1High = s1High;
        this.s1Low = s1Low;
        this.s2High = s2High;
        this.s2Low = s2Low;
    }

    public String name() {
        return "LowReboundLong";
    }

    public Optional<Signal> evaluate(StrategyContext ctx) {
        java.util.List<Kline> h4 = ctx.getCache().lastN(Timeframe.H4, 40);
        if (h4.size() < 12) return Optional.empty();
        Kline last = h4.get(h4.size() - 1);
        if (!last.finalBar()) return Optional.empty();
        IndicatorService ind = ctx.getIndicators();
        double avgVol = ind.smaVolume(h4, 8);
        boolean inS1 = last.low() <= s1High && last.low() >= s1Low - (s1High - s1Low) * 0.5;
        boolean inS2 = last.low() <= s2High && last.low() >= s2Low - (s2High - s2Low) * 0.5;
        if (!(inS1 || inS2)) return Optional.empty();
        double lowerRatio = ind.lowerShadowRatio(last);
        if (lowerRatio < 0.55) return Optional.empty();
        if (last.volume() < avgVol * 1.1) return Optional.empty();
        double entry = last.close();
        double stop = inS1 ? s1Low - (s1High - s1Low) * 0.7 : s2Low - (s2High - s2Low) * 0.6;
        double[] targets;
        if (inS1) {
            targets = new double[]{
                    s1High + (s1High - s1Low) * 2,
                    s1High + (s1High - s1Low) * 3,
                    s1High + (s1High - s1Low) * 5
            };
        } else {
            targets = new double[]{
                    s2High + (s2High - s2Low) * 1.5,
                    s1High,
                    s1High + (s1High - s1Low) * 2
            };
        }
        String comment = "lowerRatio=" + String.format("%.2f", lowerRatio) + " volFactor=" + String.format("%.2f", last.volume() / avgVol);
        Signal sig = new Signal(java.util.UUID.randomUUID().toString(),
                ctx.getNow(), ctx.getSymbol(), name(), "LONG",
                entry, stop, targets, "A", comment);
        return Optional.of(sig);
    }
}
