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 StrategyBreakdownRetestShort implements Strategy {
    private final double level;
    private volatile boolean armed = false;
    private volatile long breakdownBarTime = -1;

    public StrategyBreakdownRetestShort(double level) {
        this.level = level;
    }

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

    public Optional<Signal> evaluate(StrategyContext ctx) {
        java.util.List<Kline> h4 = ctx.getCache().lastN(Timeframe.H4, 30);
        java.util.List<Kline> m15 = ctx.getCache().lastN(Timeframe.M15, 80);
        if (h4.size() < 10 || m15.size() < 20) return Optional.empty();
        IndicatorService ind = ctx.getIndicators();
        Kline lastH4 = h4.get(h4.size() - 1);
        if (lastH4.finalBar()) {
            double avgVol = ind.smaVolume(h4, 10);
            boolean breakdown = lastH4.close() < level && lastH4.volume() >= avgVol * 1.2;
            if (breakdown) {
                armed = true;
                breakdownBarTime = lastH4.openTime();
            }
        }
        if (!armed) return Optional.empty();
        int consecutive = 0;
        for (int i = m15.size() - 1; i >= 0 && consecutive < 3; i--) {
            Kline k = m15.get(i);
            if (k.openTime() < breakdownBarTime) break;
            boolean zone = k.high() <= level + Math.abs(level) * 0.000002
                    && k.high() >= level - Math.abs(level) * 0.000005;
            if (zone) consecutive++;
            else if (consecutive > 0) break;
        }
        if (consecutive >= 2) {
            armed = false;
            double entry = level - Math.abs(level) * 0.000002;
            double stop = level + Math.abs(level) * 0.00001;
            double[] targets = new double[]{
                    level - Math.abs(level) * 0.00002,
                    level - Math.abs(level) * 0.00005,
                    level - Math.abs(level) * 0.00009
            };
            Signal sig = new Signal(java.util.UUID.randomUUID().toString(),
                    ctx.getNow(), ctx.getSymbol(), name(), "SHORT",
                    entry, stop, targets, "A", "Retest m15 consecutive=" + consecutive);
            return Optional.of(sig);
        }
        return Optional.empty();
    }
}
