<?php

namespace App\Console\Commands\Market;

use App\Events\MarketStatsLiteUpdated;
use App\Models\Market\Market;
use App\Services\Liquidity\Binance\BinanceApi;
use App\Services\Market\MarketService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class MarketStatsWatcherCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'market-watcher:stats';

    protected $markets;

    protected $initialMarkets;

    protected $lastMarkets;

    protected $quoteMarkets;

    protected $discounts;

    protected $baseMarkets;

    protected $lastRefreshed;

    protected $iteration = 0;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->prepareMarkets();

        $binanceApi = new BinanceApi();

        $marketService = new MarketService();

        //try {

        $ticketIncrement = 1;

        $binanceApi->ticker(false, function ($data, $symbol, $ticker, $ws) use ($marketService, &$ticketIncrement) {

            $HOURLY_RESTART = date('i');

            // Restart hourly
            if($HOURLY_RESTART == "10") {
                $ws->close();
            }

            if($ticketIncrement > 100) $ticketIncrement = 1;

            $ticketIncrement++;

            if($ticketIncrement % 2 == 0) {

                $marketName = $this->markets[$ticker['symbol']] ?? false;

                if ($marketName) {

                    $discount = $this->discounts[$this->markets[$ticker['symbol']]];

                    $ratio = $discount * 0.01;

                    $close = math_sum($ticker['close'], (math_multiply($ticker['close'], $ratio)));
                    $high = math_sum($ticker['high'], (math_multiply($ticker['high'], $ratio)));
                    $low = math_sum($ticker['low'], (math_multiply($ticker['low'], $ratio)));

                    $marketService->updateStatsForce($this->markets[$ticker['symbol']], 'high', $high);
                    $marketService->updateStatsForce($this->markets[$ticker['symbol']], 'low', $low);
                    $marketService->updateStatsForce($this->markets[$ticker['symbol']], 'volume', $ticker['volume']);
                    $marketService->updateStatsForce($this->markets[$ticker['symbol']], 'last', $close);
                    $marketService->updateStatsForce($this->markets[$ticker['symbol']], 'qVolume', $ticker['qVolume']);

                    try {

                        event(new MarketStatsLiteUpdated([
                            'name' => $this->initialMarkets[$this->markets[$ticker['symbol']]],
                            'last' => math_formatter($close, $this->quoteMarkets[$this->markets[$ticker['symbol']]]),
                            'high' => math_formatter($high, $this->quoteMarkets[$this->markets[$ticker['symbol']]]),
                            'low' => math_formatter($low, $this->quoteMarkets[$this->markets[$ticker['symbol']]]),
                            'volume' => math_formatter($ticker['volume'], $this->baseMarkets[$this->markets[$ticker['symbol']]]),
                            'qVolume' => math_formatter($ticker['qVolume'], $this->baseMarkets[$this->markets[$ticker['symbol']]]),
                            'change' => math_percentage_between($close, $this->lastMarkets[$this->markets[$ticker['symbol']]]),
                        ]));

                    } catch (\Exception $e) {

                    }

                    if ((time() - $this->lastRefreshed) > 60) {
                        $this->prepareMarkets();
                    }
                }

            }
        });
    }

    protected function prepareMarkets() {

        $marketList = Market::where('liq', true)->pluck('name');

        $this->markets = Market::whereIn('name', $marketList)->pluck('id', 'name')->toArray();
        $this->discounts = Market::whereIn('name', $marketList)->pluck('discount', 'id')->toArray();
        $this->lastMarkets = Market::whereIn('name', $marketList)->pluck('last', 'id')->toArray();
        $this->quoteMarkets = Market::whereIn('name', $marketList)->pluck('quote_precision', 'id')->toArray();
        $this->baseMarkets = Market::whereIn('name', $marketList)->pluck('base_precision', 'id')->toArray();

        foreach($this->markets as $market=>$id) {
            unset($this->markets[$market]);
            $this->markets[market_sanitize($market)] = $id;
            $this->initialMarkets[$id] = $market;
        }

        $this->lastRefreshed = time();

    }
}

