<?php
//die();
date_default_timezone_set("Asia/Tehran");
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('memory_limit', '512M');
require_once 'functions.php';

$jsonDataPath = 'data/BestSAR.json';
$jsonData = file_get_contents($jsonDataPath);
$data = json_decode($jsonData, true);

$bestSAR = $symbols = [];
$defaultValues = [0.03, 0.03, 0.3];//[0.02, 0.01, 0.2];//
if (json_last_error() !== JSON_ERROR_NONE || empty($data)) {
    $data = [];
    file_put_contents('readBestsError.txt', json_encode([date('Y-m-d H:i:s'), 'cant load the Bests']) . PHP_EOL, FILE_APPEND);

}
unset($data['time']);
foreach ($data as $symbol => $sarValues) {
    $bestSAR[$symbol] = !empty($sarValues) ? $sarValues : $defaultValues;
}
if (isset($_GET['test'])) {
    print_r($bestSAR);
    die();
}
//====================================================================== start main
$min = date('i');
while ($min == date('i')) {
    $syms = readJson('data/symbols.json');
    if (!$syms) {
        sleep(1);
        continue;
    }

    foreach ($syms as $val) {
        $symbolFormatted = str_replace(['100K_', '1M_', '1B_'], ['', '', '1M'], $val);
        $symbols[] = $symbolFormatted;
    }
    break;
}

$ohlc = [];
$chunkSize = 50;
for ($n = 1; $n <= 3; $n++) {
    for ($i = 0; $i < ceil(count($symbols) / $chunkSize); $i++) {
        $chunk = array_slice($symbols, $i * $chunkSize, $chunkSize);
        $data = getOHLCData($chunk);
        usleep(300000);
    }
    if (isset($_GET['v1'])) {
        print_r($ohlc['BTCUSDT']);
        die();
    }
//================================================================ read files

    $path1 = 'data/BinanceOHLC';
    $Binancefiles = scandir($path1);
    $atrResults = [];
    $atrResults['time'] = date('Y-m-d H:i:s');
    foreach ($Binancefiles as $file) {
        if ($file == '.' || $file == '..')
            continue;
        $symbol = str_replace('.json', '', $file);
        if (!in_array($symbol, $symbols)) {
            unlink($path1 . '/' . $file);
            continue;
        }
        $data = readJson('data/BinanceOHLC/' . $file);

        if (!isset($bestSAR[$symbol]))
            $bestSAR[$symbol] = $defaultValues;

        if (isset($_GET['sar'])) {
            print_r($bestSAR[$symbol]);
            die();
        }
//    echo $bestSAR[$symbol][0];

        list($atr, $maxLow, $maxHigh, $isatrshock, $maxCloseATR) = calculateATR($data);
        list($sar0, $sar1, $temp1, $temp2) = calculateSAR($data, $bestSAR[$symbol][0], $bestSAR[$symbol][1], $bestSAR[$symbol][2]);
        list($sar_long0, $sar_long1, $SAR1Value, $SAR0Value) = calculateSAR($data, 0.09, 0.09, 0.9); //($data, 0.02, 0.01, 0.2)
        /*  $bestSAR[$symbol][0] >= 0.02 ? $bestSAR[$symbol][0] - 0.01 : $bestSAR[$symbol][0],
          $bestSAR[$symbol][1] >= 0.03 ? $bestSAR[$symbol][1] - 0.02 : $bestSAR[$symbol][1],
          $bestSAR[$symbol][2] >= 0.2 ? $bestSAR[$symbol][2] - 0.1 : $bestSAR[$symbol][2]
      );*/
        //[0.02, 0.01, 0.2];
        //calculateSAR($data);
        $lastCandle = $data[count($data) - 2];
        $bigcandle = calculateBiggestCandle($data, 5);

        $atrResults[$symbol] = [
            'ATR' => change1symbols($symbol, $atr),
            'MaxLow' => change1symbols($symbol, $maxLow),
            'MaxHigh' => change1symbols($symbol, $maxHigh),
            'MaxCloseATR' => change1symbols($symbol, $maxCloseATR),
            'isatrshock' => $isatrshock,
            'sar0' => $sar0,
            'sar1' => $sar1,
            'sar_long0' => $sar_long0,
            'sar_long1' => $sar_long1,
            'sar_long0Value' => $SAR0Value,
            'sar_long1Value' => $SAR1Value,
            'LastHigh' => change1symbols($symbol, $lastCandle[2]),
            'LastClose' => change1symbols($symbol, $lastCandle[4]),
            'biggestCandle' => $bigcandle,
            'trend' => checkLowestLowInLastCandles($data)
        ];
        if (str_ends_with($symbol, 'FLOKIUSDT')) {
            $atrResults['100K_FLOKIUSDT'] = $atrResults[$symbol];
        }
        if (str_ends_with($symbol, 'BABYDOGEUSDT')) {
            $atrResults['1B_BABYDOGEUSDT'] = $atrResults[$symbol];
        }
        if (str_ends_with($symbol, 'PEPEUSDT')) {
            $atrResults['1M_PEPEUSDT'] = $atrResults[$symbol];
        }
        if (str_ends_with($symbol, 'BONKUSDT')) {
            $atrResults['1K_BONKUSDT'] = $atrResults[$symbol];
        }
    }
// ذخیره نتایج ATR در فایل جیسون
    file_put_contents('data/BinanceIndicators.json', json_encode($atrResults, JSON_PRETTY_PRINT));
//    file_put_contents('BinanceIndicators_bug.txt', json_encode([date('Y-m-d H:i:s')]) . PHP_EOL, FILE_APPEND);
    if (date('s') + 17 > 50) break;
    sleep(17);
    if ($min != date('i')) break;
}

//========================================================== functions


function readJson($path)
{
    if (!file_exists($path)) {
        usleep(300000);
        if (!file_exists($path)) {
            return [];
        }
    }
    $fileSize = filesize($path);
    if ($fileSize === 0) return [];

    $file = fopen($path, "r");
    if (!$file) return [];

    $response = fread($file, $fileSize);
    fclose($file);
    return json_decode($response) ?: [];
}

function getOHLCData($symbols)
{
    global $ohlc;
    $multiCurl = curl_multi_init();
    $curlHandles = [];
    foreach ($symbols as $symbol) {

        $symbolFormatted = str_replace(['1K_', '100K_', '1M_', '1B_'], ['', '', '', '1M'], $symbol);

        $url = 'api.binance.com/api/v3/klines?symbol=' . $symbolFormatted . '&interval=1m&limit=80';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 40); // تنظیم تایم اوت
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // غیرفعال کردن SSL (در صورت نیاز)

        $curlHandles[$symbol] = $ch;
        curl_multi_add_handle($multiCurl, $ch);
    }

    $running = null;
    do {
        curl_multi_exec($multiCurl, $running);
        curl_multi_select($multiCurl);
    } while ($running > 0);

    foreach ($symbols as $market) {
        if (isset($curlHandles[$market])) {
            $response = curl_multi_getcontent($curlHandles[$market]);

            // بررسی وضعیت HTTP
            $httpCode = curl_getinfo($curlHandles[$market], CURLINFO_HTTP_CODE);
            if ($httpCode != 200) {
                echo "HTTP Error Code: $httpCode for $market\n";
                $error = curl_error($curlHandles[$market]);
                $errno = curl_errno($curlHandles[$market]);
                echo "CURL Error: $error (Error Code: $errno)\n";
                curl_multi_remove_handle($multiCurl, $curlHandles[$market]);
                curl_close($curlHandles[$market]);
                continue;
            }

            if ($response) {
                $jsonData = json_decode($response, true);
                if (json_last_error() === JSON_ERROR_NONE) {
                    $filePath = 'data/BinanceOHLC/' . $market . '.json';

                    file_put_contents($filePath, json_encode($jsonData, JSON_PRETTY_PRINT));
                    $ohlc[$market] = json_encode($jsonData);
//                    echo " $market \n";
                } else {
                    echo "Failed to fetch valid JSON data for $market.\n";
                }
            } else {
                echo "No response for $market.\n";
            }

            curl_multi_remove_handle($multiCurl, $curlHandles[$market]);
            curl_close($curlHandles[$market]);
        } else {
            echo "Curl handle for $market not found.\n";
        }

    }

    curl_multi_close($multiCurl);
}


function calculateATR($klines, $period = 10)
{
    $tr = array();

    for ($i = 1; $i < count($klines); $i++) {
        $high = $klines[$i][2];
        $low = $klines[$i][3];
        $closePrev = $klines[$i - 1][4];

        // محاسبه True Range (TR)
        $tr[] = max(
            $high - $low,
            abs($high - $closePrev),
            abs($low - $closePrev)
        );
    }

    // محاسبه ATR بر اساس دوره (Period)
    $atr = array_sum(array_slice($tr, -$period)) / $period;

    // پیدا کردن بیشترین حد بالا و پایین در دوره مورد نظر
    $maxHigh = max(array_column(array_slice($klines, -$period), 2));
    $maxLow = min(array_column(array_slice($klines, -$period), 3));
    $maxCloseArray = array_column(array_slice($klines, -4), 4);
    unset($maxCloseArray[3]);
    $maxCloseATR = max($maxCloseArray) - ($atr * 0.8);

//    $percentDifference = $atr / $klines[count($klines) - 1][4];
    $isatrshock = $klines[count($klines) - 1][4] > ($klines[count($klines) - 2][4] + ($atr * 1.2)) ? 'true' : 'false';


    return [$atr, $maxLow, $maxHigh, $isatrshock, $maxCloseATR];
}

function calculateSAR($klines, $start = 0.02, $inc = 0.01, $max = 0.2)
{
    $sar = [];
    $ep = $klines[0][2]; // نقطه افراطی (Extreme Point)
    $af = $start; // ضریب تسریع (Acceleration Factor)
    $isUptrend = $klines[0][4] > $klines[0][1]; // روند صعودی یا نزولی
    $sar[0] = $isUptrend ? $klines[0][3] : $klines[0][2]; // SAR اولیه

    for ($i = 1; $i < count($klines); $i++) {
        $sar[$i] = $sar[$i - 1] + $af * ($ep - $sar[$i - 1]);

        if ($isUptrend) {
            if ($klines[$i][3] < $sar[$i]) {
                $isUptrend = false;
                $sar[$i] = $ep;
                $ep = $klines[$i][3];
                $af = $start;
            } else {
                if ($klines[$i][2] > $ep) {
                    $ep = $klines[$i][2];
                    $af = min($af + $inc, $max);
                }
                $sar[$i] = min($sar[$i], $klines[$i - 1][3]);
                if ($i > 1) {
                    $sar[$i] = min($sar[$i], $klines[$i - 2][3]);
                }
            }
        } else {
            if ($klines[$i][2] > $sar[$i]) {
                $isUptrend = true;
                $sar[$i] = $ep;
                $ep = $klines[$i][2];
                $af = $start;
            } else {
                if ($klines[$i][3] < $ep) {
                    $ep = $klines[$i][3];
                    $af = min($af + $inc, $max);
                }
                $sar[$i] = max($sar[$i], $klines[$i - 1][2]);
                if ($i > 1) {
                    $sar[$i] = max($sar[$i], $klines[$i - 2][2]);
                }
            }
        }
    }
    $SAR0 = $klines[count($klines) - 1][2] <= $sar[count($sar) - 1] ? 'sell' : 'buy';
    $SAR1 = $klines[count($klines) - 2][2] <= $sar[count($sar) - 2] ? 'sell' : 'buy';

    return [$SAR0, $SAR1, $sar[count($sar) - 2], $sar[count($sar) - 1]];
    // return $sar[count($klines) - 1] > $klines[count($klines) - 1][4] ? 'sell' : 'buy';
}

function change1symbols($key, $num)
{

//    if ($key == 'SHIBUSDT')
//        return $num *= 1000;
//    if (str_ends_with($key, 'FLOKIUSDT'))
//        return $num *= 100000;
//    if (str_ends_with($key, 'BABYDOGEUSDT'))
//        return $num *= 1000;
//    if (str_ends_with($key, 'PEPEUSDT'))
//        return $num *= 1000000;
//    if (str_ends_with($key, 'BONKUSDT'))
//        return $num *= 1000;

    return $num;

}

function calculateBiggestCandle($klines, $number)
{
    $biggest = 0;

    for ($i = count($klines) - $number - 1; $i < count($klines); $i++) {
        if (isset($klines[$i][2])) {
            if ($biggest < $klines[$i][2] - $klines[$i][3]) {
                $biggest = $klines[$i][2] - $klines[$i][3];
            }
        }
    }
    if (isset($klines[count($klines) - 1][1]))
        return $biggest / $klines[count($klines) - 1][1];
    else
        return 0;
}


function checkLowestLowInLastCandles($klines)
{
    $totalCandles = count($klines);
    if ($totalCandles < 65) {
        return "down";
    }

    // دریافت 50 کندل آخر
    $last50 = array_slice($klines, -60);

    // پیدا کردن پایین‌ترین low در 50 کندل اخیر
    $lowestLow = min(array_column($last50, 3));

    // دریافت 5 کندل آخر
    $last5 = array_slice($klines, -12);

    // بررسی اینکه آیا پایین‌ترین low در 5 کندل آخر بوده یا نه
    foreach ($last5 as $candle) {
        if ($candle[3] == $lowestLow) {
            return "down";
        }
    }

    return "up";
}
