import Transaction from "../../apiwrapper/transaction/Transaction.js";
import TransactionPhase from "../../apiwrapper/transaction/TransactionPhase.js";
import AbstractStrategy from "./AbstractStrategy.js";

export default class AvgMinMaxStrategy extends AbstractStrategy {
    #lastBuySuggestionTime = 0;

    constructor(){
        super();
        this.#lastBuySuggestionTime = Date.now();
    }

    /**
     * @param {Transaction} transaction 
     * @returns {boolean}
     */
    shouldSell(transaction) {
        const winPercent = (this.getAssetData().getOrderBook().getBestBid().price / transaction.buySettings.price) * 100 - 100;

        if(!this.isAllowedToSell(transaction, winPercent)){
            return false;
        }

        if(winPercent > 2.5){
            return true;
        }

        const aggDataPoints = this.getAssetData().getAggregatedData('15m');
        const price = this.getAssetData().getOrderBook().getBestBid().price;
        const avg15m = aggDataPoints.length > 0 ? aggDataPoints.map(v => v.avgPrice).reduce((a, b) => a+b, 0) / aggDataPoints.length : 0;

        if(avg15m != 0 && avg15m * 1.005 <= price){
            this.getLogger().event("[SELL][" + this.constructor.name + "] recomendet sell for " + transaction.id + " for " + price.toFixed(6));
            return true;
        }

        return false;
    }

    /**
     * @returns {boolean}
     */
    shouldBuy() {
        if(Date.now() < this.#lastBuySuggestionTime + 300000){
            return false;
        }

        const aggDataPoints = this.getAssetData().getAggregatedData('15m');
        const price = this.getAssetData().getOrderBook().getBestBid().price;
        const avg15m = aggDataPoints.length > 0 ? aggDataPoints.map(v => v.avgPrice).reduce((a, b) => a+b, 0) / aggDataPoints.length : 0;
        
        if(avg15m != 0 && avg15m * 0.995 >= price){
            this.#lastBuySuggestionTime = Date.now();
            this.getLogger().event("[BUY][" + this.constructor.name + "] recomendet buy for " + price.toFixed(6));
            return true;
        }

        return false;
    }

    /**
     * @param {Transaction} transaction 
     * @returns {boolean}
     */
    shouldCancle(transaction) {
        if(!this.isAllowedToCancel(transaction)){
            return false;
        }
        
        const price = this.getAssetData().getOrderBook().getBestBid().price;

        if(transaction.buySettings != null && transaction.phase == TransactionPhase.BUY_IN_PROGRESS){
            if(transaction.buySettings.orderPrice * 1.002 < price){
                this.getLogger().event("[CANCEL][" + this.constructor.name + "] recomendet cancel for " + transaction.id);
                return true;
            }
        }

        return false;
    }

    /**
    * @returns {string} string representation of this object
    */
    toJson() {
        const obj = JSON.parse(super.toJson());

        return JSON.stringify(obj);
    }

    /**
     * @param {string} objString 
     * @returns {AvgMinMaxStrategy2}
     */
    static fromJson(objString) {
        return new AvgMinMaxStrategy();
    }
}