<?php
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

// Disable displaying errors publicly
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/php-error.log');

// Improve PHP Performance
ini_set('memory_limit', '512M');
set_time_limit(20); // prevents long-running stalls

include_once __DIR__ . "/mt5_api/mt5_api.php";
include_once __DIR__ . "/connection.php";

// Read JSON input faster
$input = file_get_contents("php://input");
$data = json_decode($input, true, 512, JSON_INVALID_UTF8_IGNORE);

$trade_id = $data['trade_id'] ?? null;

if (!$trade_id) {
    echo json_encode(["success" => false, "message" => "Trade ID is required"]);
    exit;
}

// Reuse MTWebAPI instance efficiently
$api = new MTWebAPI("WebAPITesterLocal", "./logs", false);
$ret = $api->Connect(MT5_SERVER_IP, MT5_SERVER_PORT, 5, MT5_SERVER_WEB_LOGIN, MT5_SERVER_WEB_PASSWORD);

// Fast fail
if ($ret !== MTRetCode::MT_RET_OK) {
    echo json_encode([
        "success" => false,
        "message" => "Failed to connect to MT5",
        "error_code" => $ret
    ]);
    exit;
}

/* =============== VALIDATE USER =============== */

$userMT5 = new MTUser();
$ret = $api->UserGet((int)$trade_id, $userMT5);

if ($ret !== MTRetCode::MT_RET_OK || empty($userMT5->Login)) {
    $api->Disconnect();
    echo json_encode([
        "success" => false,
        "message" => "User not found in MT5",
        "error_code" => $ret
    ]);
    exit;
}

/* =============== GET ACCOUNT INFO (FAST) =============== */

$total_equity = 0;
$total_volume = 0;
$total_profit_loss = 0;
$total_positions = 0;
$positions_data = [];

try {

    $account = null;
    $accRet = $api->UserAccountGet($userMT5->Login, $account);

    if ($accRet === MTRetCode::MT_RET_OK && $account) {

        // Direct property access faster
        if (isset($account->Equity)) {
            $total_equity = (float)$account->Equity;
        }

        // Slight fallback logic kept but optimized
        elseif (isset($account->Balance)) {
            $total_equity = (float)$account->Balance + (float)$total_profit_loss;
        }
    }

} catch (Throwable $e) {
    error_log("Account Fetch Error: " . $e->getMessage());
}


/* =============== GET OPEN POSITIONS (MAJOR OPTIMIZATION) =============== */

try {
    $posCount = 0;
    $ret = $api->PositionGetTotal($userMT5->Login, $posCount);

    if ($ret === MTRetCode::MT_RET_OK && $posCount > 0) {

        // Preallocate array for speed
        $positions = [];

        // Fetch all positions in a single MT5 call
        $ret = $api->PositionGetPage($userMT5->Login, 0, $posCount, $positions);

        if ($ret === MTRetCode::MT_RET_OK && $positions) {

            foreach ($positions as $pos) {

                // Skip if no volume
                if (!isset($pos->Volume)) continue;

                // Calculate once
                $volume = round($pos->Volume * 0.0001, 2);
                $profit = isset($pos->Profit) ? (float)$pos->Profit : 0.0;

                $total_volume += $volume;
                $total_profit_loss += $profit;
                $total_positions++;

                // Append cleaned small data structure
                $positions_data[] = [
                    "Symbol"       => $pos->Symbol ?? null,
                    "PriceOpen"    => $pos->PriceOpen ?? null,
                    "PriceCurrent" => $pos->PriceCurrent ?? null,
                    "PriceSL"      => $pos->PriceSL ?? null,
                    "PriceTP"      => $pos->PriceTP ?? null,
                    "Volume"       => $volume,
                    "Action"       => ($pos->Action == 1) ? "Sell" : "Buy",
                    "Profit"       => $profit,
                    "Storage"      => $pos->Storage ?? null,
                    "TimeCreate"   => isset($pos->TimeCreate) ? gmdate("Y-m-d H:i:s", $pos->TimeCreate) : null
                ];
            }
        }
    }

} catch (Throwable $e) {
    error_log("Position Fetch Error: " . $e->getMessage());
}

$api->Disconnect();

/* =============== FINAL JSON RESPONSE (FAST ENCODE) =============== */

echo json_encode([
    "success"           => true,
    "trade_id"          => $trade_id,
    "total_positions"   => $total_positions,
    "total_equity"      => round($total_equity, 2),
    "total_volume"      => round($total_volume, 2),
    "total_profit_loss" => round($total_profit_loss, 2),
    "positions"         => $positions_data
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

exit;
?>
