"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GenerateForexSignal = void 0;
const AppError_js_1 = require("../../shared/errors/AppError.js");
const random_js_1 = require("../../shared/utils/random.js");
const FOREX_STRATEGIES = ["Breakout", "Range Play", "Momentum", "Trend Follow", "Pullback"];
class GenerateForexSignal {
    marketData;
    constructor(marketData) {
        this.marketData = marketData;
    }
    async execute(market, pairSymbol) {
        const pairs = await this.marketData.getMarketPairs(market);
        if (pairs.length === 0) {
            throw new AppError_js_1.AppError(`No ${market} pairs available.`, "NO_FOREX_PAIRS", true);
        }
        const pair = pairSymbol
            ? pairs.find((p) => p.symbol.toUpperCase() === pairSymbol.toUpperCase()) ?? (0, random_js_1.chooseOne)(pairs)
            : this.pickProfitablePair(pairs);
        const side = (0, random_js_1.chooseOne)(["BUY", "SELL"]);
        const movePct = (0, random_js_1.randomFloat)(0.3, 1.5, 4);
        const slPct = (0, random_js_1.randomFloat)(0.15, 0.6, 4);
        const entryPrice = pair.price;
        const targetPrice = side === "BUY"
            ? Number((entryPrice * (1 + movePct / 100)).toFixed(5))
            : Number((entryPrice * (1 - movePct / 100)).toFixed(5));
        const stopLoss = side === "BUY"
            ? Number((entryPrice * (1 - slPct / 100)).toFixed(5))
            : Number((entryPrice * (1 + slPct / 100)).toFixed(5));
        const duration = this.randomDuration();
        return {
            tokenName: `${pair.base}/${pair.quote}`,
            symbol: pair.symbol,
            category: "Forex",
            side,
            strategyName: (0, random_js_1.chooseOne)(FOREX_STRATEGIES),
            entryPrice,
            targetPrice,
            predictedPrice: targetPrice,
            stopLoss,
            takeProfit: targetPrice,
            riskLevel: (0, random_js_1.chooseOne)(["Low", "Medium", "High"]),
            suggestedAmountUsd: (0, random_js_1.randomInt)(500, 5000),
            executionWindow: duration,
            reasoning: `${side} setup for ${pair.symbol} at ${entryPrice.toFixed(5)}. Predicted move to ${targetPrice} with stop at ${stopLoss}.`,
            confidenceScore: (0, random_js_1.randomFloat)(5, 8, 1),
            lotSize: (0, random_js_1.randomFloat)(0.1, 2.0, 2),
            pipValue: this.pipValue(pair.quote)
        };
    }
    pickProfitablePair(pairs) {
        // Heuristic: score pairs by a deterministic but varied metric.
        // In live mode the price already reflects market data; here we simulate an "analysis"
        // by ranking on a hash-based volatility proxy.
        const scored = pairs.map((pair) => {
            const hash = Array.from(pair.symbol).reduce((acc, char) => acc + char.charCodeAt(0), 0);
            const momentum = (hash % 100) / 1000; // 0.0 - 0.1
            return { pair, score: momentum + Math.random() * 0.05 };
        });
        scored.sort((a, b) => b.score - a.score);
        return scored[0].pair;
    }
    randomDuration() {
        const minutes = (0, random_js_1.randomInt)(15, 240);
        if (minutes < 60)
            return `${minutes} minutes`;
        const hours = Math.floor(minutes / 60);
        const remainder = minutes % 60;
        return remainder > 0 ? `${hours}h ${remainder}m` : `${hours} hours`;
    }
    pipValue(quote) {
        return quote === "JPY" ? 0.01 : 0.0001;
    }
}
exports.GenerateForexSignal = GenerateForexSignal;
