<?php

// --- Function NOWPayments ---
function NOWPayments($method, $endpoint, $datas = [])
{
    global $paymentKeys;

    $base_url = 'https://api.nowpayments.io/v1/';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

    switch ($method) {
        case 'GET':
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-API-KEY: ' . $paymentKeys['nowpayment']]);
            if (!empty($datas)) {
                if (is_array($datas)) {
                    $parameters = http_build_query($datas);
                    curl_setopt($ch, CURLOPT_URL, $base_url . $endpoint . '?' . $parameters);
                }
                else {
                    if ($endpoint == 'payment')
                        curl_setopt($ch, CURLOPT_URL, $base_url . $endpoint . '/' . $datas);
                }
            }
            else {
                curl_setopt($ch, CURLOPT_URL, $base_url . $endpoint);
            }
            break;

        case 'POST':
            $datas = json_encode($datas);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-API-KEY: ' . $paymentKeys['nowpayment'], 'Content-Type: application/json']);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $datas);
            curl_setopt($ch, CURLOPT_URL, $base_url . $endpoint);
            break;

        default:
            break;
    }

    $res = curl_exec($ch);

    if (curl_error($ch))
        var_dump(curl_error($ch));
    else
        return json_decode($res);
}

// --- Function getMarzbanToken ---
function getMarzbanToken($server_id)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id = ?");
    $stmt->bind_param('i', $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $username = $server_info['username'];
    $password = $server_info['password'];

    $loginUrl = $panel_url . '/api/admin/token';
    $postFields = array(
        'username' => $username,
        'password' => $password
    );


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/x-www-form-urlencoded',
        'accept: application/json'
    ));
    $response = curl_exec($curl);
    if (curl_error($curl)) {
        return (object)['success' => false, 'detail' => curl_error($curl)];
    }
    curl_close($curl);

    return json_decode($response);
}

// --- Function getMarzbanJson ---
function getMarzbanJson($server_id, $token = null)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];

    if ($token == null)
        $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }
    $panel_url .= '/api/users';
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_HTTPGET, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);

    return $response;
}

// --- Function getMarzbanUserInfo ---
function getMarzbanUserInfo($server_id, $remark)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];

    $configInfo = array();
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    for ($i = 0; $i <= 10; $i++) {
        $info = getMarzbanUser($server_id, $remark);
        $subLink = "/sub/" . (explode("/sub/", $info->subscription_url)[1]);
        $info->subscription_url = $subLink;
        curl_setopt($curl, CURLOPT_URL, $panel_url . $info->subscription_url);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 3);
        $response = curl_exec($curl);
        if ($response && !curl_error($curl)) {
            $configInfo = $info;
            break;
        }
        if ($i == 10)
            $configInfo = $info;
    }
    curl_close($curl);

    return (object)$configInfo;
}

// --- Function getMarzbanUser ---
function getMarzbanUser($server_id, $remark, $token = null)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];

    if ($token == null)
        $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }

    $panel_url .= '/api/user/' . urlencode($remark);

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_HTTPGET, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = json_decode(curl_exec($curl));

    curl_close($curl);
    return $response;
}

// --- Function getMarzbanHosts ---
function getMarzbanHosts($server_id)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];

    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }

    $panel_url .= '/api/core/config';

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_HTTPGET, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = json_decode(curl_exec($curl));

    curl_close($curl);
    return $response;
}

// --- Function addMarzbanUser ---
function addMarzbanUser($server_id, $remark, $volume, $days, $plan_id)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];
    $serverType = $server_info['type'];


    $stmt = $connection->prepare("SELECT * FROM `server_plans` WHERE `id` = ?");
    $stmt->bind_param('i', $plan_id);
    $stmt->execute();
    $planInfo = json_decode($stmt->get_result()->fetch_assoc()['custom_sni'], true);
    $stmt->close();

    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }
    $postFields = array(
        "inbounds" => $planInfo['inbounds'],
        "proxies" => $planInfo['proxies'],
        "expire" => time() + (86400 * $days),
        "data_limit" => $volume * 1073741824,
        "username" => urlencode($remark)
    );


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url . "/api/user");
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token,
        'Content-Type: application/json'
    ));
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postFields));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);
    if (isset($response->detail) || !isset($response->links)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }
    $userInfo = getMarzbanUserInfo($server_id, $remark);

    return (object)[
        'success' => true,
        'sub_link' => $userInfo->subscription_url,
        'vray_links' => $response->links
    ];
}

// --- Function editMarzbanConfig ---
function editMarzbanConfig($server_id, $info)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->error];
    }

    $remark = $info['remark'];
    $configInfo = getMarzbanUser($server_id, $remark, $token);


    $expireTime = $configInfo->expire;
    $volume = $configInfo->data_limit;
    $configState = $configInfo->status;

    if (isset($info['plus_day'])) {
        if ($expireTime < time())
            $expireTime = time() + (86400 * $info['plus_day']);
        else
            $expireTime += (86400 * $info['plus_day']);
    }
    elseif (isset($info['days'])) {
        if ($expireTime < time())
            $expireTime = time() + (86400 * $info['days']);
        else
            $expireTime += (86400 * $info['days']);
    }

    if (isset($info['plus_volume']))
        $volume += $info['plus_volume'] * 1073741824;
    elseif (isset($info['volume'])) {
        $volume = $info['volume'] * 1073741824;
        $response = resetMarzbanTraffic($server_id, $remark, $token);

        if (!$response->success)
            return $response;
    }

    $postFields = array(
        "inbounds" => $configInfo->inbounds,
        "proxies" => $configInfo->proxies,
        "expire" => $expireTime,
        "data_limit" => $volume,
        "username" => urlencode($remark),
        "note" => $configInfo->note,
        "data_limit_reset_strategy" => $configInfo->data_limit_reset_strategy,
        "status" => "active"
    );

    $panel_url .= '/api/user/' . $remark;
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postFields));
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token,
        'Content-Type: application/json'
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    $response = json_decode($response);
    if (isset($response->detail)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }
    return (object)['success' => true];
}

// --- Function resetMarzbanTraffic ---
function resetMarzbanTraffic($server_id, $remark, $token)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    if ($token == null)
        $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }

    $panel_url .= '/api/user/' . $remark . '/reset';

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    $response = json_decode($response);
    if (isset($response->detail)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }
    return (object)['success' => true];
}

// --- Function renewMarzbanUUID ---
function renewMarzbanUUID($server_id, $remark)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }
    $panel_url .= '/api/user/' . $remark . '/revoke_sub';

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);
    if (isset($response->detail)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }
    $response = getMarzbanUserInfo($server_id, $remark);
    return $response;
}

// --- Function deleteMarzban ---
function deleteMarzban($server_id, $remark)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];
    $serverType = $server_info['type'];

    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }
    $panel_url .= '/api/user/' . urlencode($remark);

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
    curl_setopt($curl, CURLOPT_HTTPGET, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token
    ));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);

    if (isset($response->detail)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }

    return (object)['success' => true];
}

// --- Function changeMarzbanState ---
function changeMarzbanState($server_id, $remark)
{
    global $connection;

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];
    $serverType = $server_info['type'];

    $token = getMarzbanToken($server_id);
    if (isset($token->detail)) {
        return (object)['success' => false, 'msg' => $token->detail];
    }
    $configInfo = getMarzbanUser($server_id, $remark, $token);

    $panel_url .= '/api/user/' . $remark;

    $postFields = array(
        "inbounds" => $configInfo->inbounds,
        "proxies" => $configInfo->proxies,
        "expire" => $configInfo->expire,
        "data_limit" => $configInfo->data_limit,
        "username" => urlencode($remark),
        "note" => $configInfo->note,
        "data_limit_reset_strategy" => $configInfo->data_limit_reset_strategy,
        "status" => $configInfo->status == "active" ? "disabled" : "active"
    );


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($curl, CURLOPT_URL, $panel_url);
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Authorization: Bearer ' . $token->access_token,
        'Content-Type: application/json'
    ));
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postFields));

    $response = json_decode(curl_exec($curl));
    curl_close($curl);

    if (isset($response->detail)) {
        $detail = $response->detail;
        return (object)['success' => false, 'msg' => is_object($detail) ? implode("-", (array)$detail) : $detail];
    }
    return (object)['success' => true];
}
