<?php

namespace trader\exchange\okx;

require_once __DIR__ . '/../../struct/ApiInfo.php';
require_once __DIR__ . '/../../../jytools/func.php';
require_once __DIR__ . '/../../../jytools/Curl.php';

use trader\struct\ApiInfo;
use jytools\Curl;
use function jytools\getMicrotime;
use function jytools\tsToISO;

class Api
{
    private ?ApiInfo $apiInfo = null;
    private string $host = "https://www.okx.com";

    public function __construct(?ApiInfo $apiInfo = null, $host = "")
    {
        if ($apiInfo != null) {
            $this->apiInfo = $apiInfo;
        }
        if ($host != "") {
            $this->host = $host;
        }
    }
    public function setHost($host)
    {
        $this->host = $host;
    }

    //-----------public interface ------------
    //所有交易产品基础信息
    public function instruments($param)
    {
        $path = '/api/v5/public/instruments';
        $method = 'GET';
        return $this->request($path, $method, $param);
    }

    public function positionTiers($param)
    {
        $path = '/api/v5/public/position-tiers';
        $method = 'GET';
        return $this->request($path, $method, $param);
    }

    //获取资金费率
    public function fundingRate($param)
    {
        $path = '/api/v5/public/funding-rate';
        $method = 'GET';
        return $this->request($path, $method, $param);
    }

    //获取k线
    public function klines($param)
    {
        $path = "/api/v5/market/candles";
        $method = 'GET';
        return $this->request($path, $method, $param);
    }

    //获取指数行情
    public function indexTickers($param)
    {
        $path = '/api/v5/market/index-tickers';
        $method = 'GET';
        return $this->request($path, $method, $param);
    }

    //-----------private interface ------------
    // 查询杠杆
    public function leverageInfo($param)
    {
        $path = '/api/v5/account/leverage-info';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }

    //设置杠杆
    public function setLeverage($param)
    {
        $path = '/api/v5/account/set-leverage';
        $method = 'POST';
        return $this->request($path, $method, $param, $this->apiInfo);
    }

    //下单
    public function placeOrder($param)
    {
        $path = '/api/v5/trade/order';
        $method = 'POST';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //查询订单
    public function getOrder($param)
    {
        $path = '/api/v5/trade/order';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //查询未成交订单
    public function getOrderPending($param)
    {
        $path = '/api/v5/trade/orders-pending';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //撤销订单
    public function cancelOrder($param)
    {
        $path = '/api/v5/trade/cancel-order';
        $method = 'POST';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //查看账户余额
    public function accountBalance($param)
    {
        $path = '/api/v5/account/balance';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //查询持仓
    public function getPositions($param)
    {
        $path = '/api/v5/account/positions';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //设置账户模式
    public function setAccountLevel($param)
    {
        $path = '/api/v5/account/set-account-level';
        $method = 'POST';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //设置持仓模式
    public function setPositionMode($param)
    {
        $path = '/api/v5/account/set-position-mode';
        $method = 'POST';
        return $this->request($path, $method, $param, $this->apiInfo);
    }
    //获取账户配置
    public function getAccountConfig($param = [])
    {
        $path = '/api/v5/account/config';
        $method = 'GET';
        return $this->request($path, $method, $param, $this->apiInfo);
    }

    //-------------------------------------

    private function createSign($timestamp, $method, $requestPath, $secretKey, $body = '')
    {
        $sign = base64_encode(hash_hmac('sha256', $timestamp . $method . $requestPath . $body, $secretKey, true));
        return $sign;
    }

    private function request($path, $method,  $param)
    {
        $header = [];
        $body = '';
        $fullPath = $path;
        if ($method == 'GET') {
            if (count($param) > 0) {
                $fullPath = $path . '?' . http_build_query($param);
            } else {
                $fullPath = $path;
            }
        } else {
            $header[] = 'Content-Type: application/json';
            $body = json_encode($param);
        }
        if ($this->apiInfo != null) {
            $timestamp = tsToISO(getMicrotime());
            $header[] = 'OK-ACCESS-KEY: ' . $this->apiInfo->key;
            $header[] = 'OK-ACCESS-PASSPHRASE: ' . $this->apiInfo->passphrase;
            $header[] = 'OK-ACCESS-TIMESTAMP: ' . $timestamp;
            $sign = $this->createSign($timestamp, $method, $fullPath, $this->apiInfo->secret, $body);
            $header[] = 'OK-ACCESS-SIGN: ' . $sign;
        }

        $url = $this->host . $path;
        $result = "";
        if ($method == 'POST') {
            $result = Curl::httpPost($url, $param, $header);
        } else if ($method == 'GET') {
            $result = Curl::httpGet($url, $param, $header);
        } else {
            $result = Curl::httpGet($url, $param, $header);
        }
        $data = json_decode($result, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            var_dump("json解析报错", $url, $param, $header, $this->apiInfo, $result);
        }
        return $data;
    }
}