"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GenerateMarginSignal = void 0;
const AppError_js_1 = require("../../shared/errors/AppError.js");
const random_js_1 = require("../../shared/utils/random.js");
const MarketDataUtils_js_1 = require("./shared/MarketDataUtils.js");
const MAX_DAILY_RECORDS = 10;
class GenerateMarginSignal {
    marketDataRepository;
    constructor(marketDataRepository) {
        this.marketDataRepository = marketDataRepository;
    }
    async execute(networkCode) {
        const tokens = await (0, MarketDataUtils_js_1.filterValerisTrendingTokens)((limit) => this.marketDataRepository.getTopTrendingTokens(limit), MAX_DAILY_RECORDS * 2, networkCode);
        if (tokens.length === 0) {
            const networkMsg = networkCode ? `for the selected network` : `on Lychee-supported networks`;
            throw new AppError_js_1.AppError(`No trending tokens ${networkMsg} are available right now.`, "NO_TRENDING_TOKENS", true);
        }
        return tokens.slice(0, MAX_DAILY_RECORDS).map((token) => this.buildSignal(token));
    }
    buildSignal(token) {
        const basePrice = token.priceUsd ?? (0, random_js_1.randomFloat)(0.01, 500, 6);
        const momentum = (0, random_js_1.randomFloat)(-8, 8, 2);
        const side = momentum >= 0 ? "LONG" : "SHORT";
        const leverage = (0, random_js_1.randomInt)(2, 10);
        const marginRequired = (0, random_js_1.randomInt)(200, 2000);
        const positionSize = marginRequired * leverage;
        const priceMovePct = (0, random_js_1.randomFloat)(3, 15, 2);
        const targetPrice = side === "LONG" ? Number((basePrice * (1 + priceMovePct / 100)).toFixed(6)) : Number((basePrice * (1 - priceMovePct / 100)).toFixed(6));
        const liquidationEstimate = side === "LONG"
            ? Number((basePrice * (1 - 1 / leverage)).toFixed(6))
            : Number((basePrice * (1 + 1 / leverage)).toFixed(6));
        const windowHours = (0, random_js_1.randomInt)(2, 48);
        return {
            tokenName: token.name,
            symbol: token.symbol,
            network: token.valerisNetwork,
            contractAddress: token.contractAddress,
            category: "Margin",
            side,
            strategyName: `${leverage}x ${side} Margin`,
            entryPrice: Number(basePrice.toFixed(6)),
            targetPrice,
            riskLevel: leverage > 7 ? "High" : leverage > 4 ? "Medium" : "Low",
            suggestedAmountUsd: positionSize,
            executionWindow: `${windowHours} hour${windowHours === 1 ? "" : "s"}`,
            reasoning: this.buildReasoning(token, side, leverage, basePrice, targetPrice, windowHours),
            confidenceScore: Math.min(10, Math.max(4, 7 - Math.abs(momentum) / 3)),
            leverage,
            liquidationEstimate,
            marginRequired
        };
    }
    buildReasoning(token, side, leverage, basePrice, targetPrice, windowHours) {
        return [
            `${token.name} (${token.symbol}) is setting up a ${side} margin trade on ${token.valerisNetwork}.`,
            ` Entry near $${basePrice.toFixed(4)}, target $${targetPrice.toFixed(4)} with ${leverage}x leverage.`,
            ` The momentum window is expected to play out within ~${windowHours} hour${windowHours === 1 ? "" : "s"}.`,
            side === "LONG"
                ? ` Use tight risk management; the leveraged long is sensitive to pullbacks.`
                : ` Monitor funding rates and short-squeeze risk closely.`
        ].join("");
    }
}
exports.GenerateMarginSignal = GenerateMarginSignal;
