<?php
/**
 * Created by PhpStorm.
 * User: rlgyzhcn
 * Date: 18-6-27
 * Time: 下午12:04
 */

namespace common\business;

use common\models\psources\Coin;
use common\service\coin\CoinFactory;
use common\service\exchange\ExchangeFactory;
use Yii;

/**
 * Class ExchangeBusiness
 * 各大交易所交易所api逻辑层
 *
 * @package common\business
 */
class ExchangeBusiness
{
    /**支持的交易所
     *
     * @var array
     */
    private static $exchanges = [
        0 => 'Bty',
        1 => 'HuoBi',
        2 => 'Hadax',
        3 => 'Bitfinex',
        4 => 'Bittrex',
        5 => 'Zb',
        6 => 'Token7',
        7 => 'Zg',
        8 => 'Go',
        9 => 'Zhaobi',
        10 => 'Ex',
        11 => 'Zt',
        12 => 'Tsc',
        13 => 'Binance',
        14 => 'Biki',
        15 => 'Bilaxy',
        16 => 'Bitnasdaq',
        17 => 'Dag',
        18 => 'Boc',

        //1 => 'Hadax', //不需要
        //2 => 'Bitfinex', //不需要
        //3 => 'Bittrex', //不需要
        //4 => 'Zb', //不需要
        //5 => 'Zg',//不需要
        //6 => 'Biki',//不需要
        //7 => 'S',//已挂
        //7 => 'Gdpro',//已挂
        //8 => 'Ceohk', //已挂
    ];

    /**
     * 获取行情
     *
     * @param  string $tag 目标币种
     * @param  string $aim 计数币种
     * @return array|bool
     */
    public static function getquatation($tag = 'btc')
    {
        $coin_quotation_disable_items = Yii::$app->params['coin_quotation_disable_items'];
        if (strtoupper($tag) == 'CCNY' || strtoupper($tag) == 'CNYT') {
            $exchange = ExchangeFactory::createExchange("Zhaobi");
            $rate = $exchange->getTicker("BTY", "USDT");
            $rate = (float)$rate['rmb'] / $rate['last'];
            $quotation['rmb'] = 1.00;
            $quotation['low'] = 1.00;
            $quotation['high'] = 1.00;
            $quotation['last'] = (float)sprintf("%0.4f", $quotation['rmb'] / $rate);
            goto doEnd;
        }
        if (strtoupper($tag) == 'YPLUS') {
            $quotation = [
                'low' => 10,
                'high' => 10,
                'last' => 10,
                'rmb' => 10,
            ];
            goto doEnd;
        }

        if (strtoupper($tag) == 'BOSS') {
            $quotation = [
                'low' => 2000,
                'high' => 2000,
                'last' => 2000,
                'rmb' => 2000,
            ];
            goto doEnd;
        }

        if (strtoupper($tag) == 'CPF') {
            $quotation = [
                'low' => 3.4,
                'high' => 3.4,
                'last' => 3.4,
                'rmb' => 3.4,
            ];
            goto doEnd;
        }

        if (strtoupper($tag) == 'GST' || strtoupper($tag) == 'JNTK' || strtoupper($tag) == 'SPT' || strtoupper($tag) == 'STO' || strtoupper($tag) == 'GM' || strtoupper($tag) == 'BSTC' || strtoupper($tag) == 'RYH' || strtoupper($tag) == 'CNDT' || strtoupper($tag) == 'WL' || strtoupper($tag) == 'ETS' || strtoupper($tag) == 'LIMS' || strtoupper($tag) == 'AT' || strtoupper($tag) == 'BTJ') {
            $quotation = [
                'low' => 0,
                'high' => 0,
                'last' => 0,
                'rmb' => 0,
            ];
            goto doEnd;
        }

        if (in_array($tag, $coin_quotation_disable_items)) {
            return false;
        }
        $f = false;
        $quotation = [];
        if (in_array(strtoupper($tag), ['DRA'])) {
            $exchange = ExchangeFactory::createExchange("Draex");
            $quotation = $exchange->getTicker($tag, 'USDT');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['FOLI'])) {
            $exchange = ExchangeFactory::createExchange("Ex");
            $quotation = $exchange->getTicker($tag, 'USDT');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['DAG'])) {
            $exchange = ExchangeFactory::createExchange("Dag");
            $quotation = $exchange->getTicker($tag, 'USDT');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['BNC'])) {
            $exchange = ExchangeFactory::createExchange("Bitnasdaq");
            $quotation = $exchange->getTicker($tag, 'USDT');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['GM', 'BSTC'])) {
            $exchange = ExchangeFactory::createExchange("Token7");
            $quotation = $exchange->getTicker($tag, 'HA');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['BECC'])) {
            $exchange = ExchangeFactory::createExchange("S");
            $quotation = $exchange->getTicker($tag, 'ST');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['GHP'])) {
            $exchange = ExchangeFactory::createExchange("Bitnasdaq");
            $quotation = $exchange->getTicker($tag);
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['SFT'])) {
            $exchange = ExchangeFactory::createExchange("Zhaobi");
            $quotation = $exchange->getTicker($tag, 'CNY');
            $quotation['low'] = (float)sprintf("%0.4f", $quotation['low']);
            $quotation['high'] = (float)sprintf("%0.4f", $quotation['high']);
            $quotation['last'] = (float)sprintf("%0.4f", $quotation['last']);
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['CTG'])) {
            $exchange = ExchangeFactory::createExchange("Gdpro");
            $quotation = $exchange->getTicker($tag, 'CNY');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['USDT'])) {
            $exchange = ExchangeFactory::createExchange("Go");
            $quotation = $exchange->getTicker('CNY', 'USD');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['SUSD'])) {
            $exchange = ExchangeFactory::createExchange("Go");
            $quotation = $exchange->getTicker('CNY', 'USD');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['CIC'])) {
            $exchange = ExchangeFactory::createExchange("Zt");
            $quotation = $exchange->getTicker('CIC', 'USDT');
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['TSC'])) {
            $exchange = ExchangeFactory::createExchange("Tsc");
            $quotation = $exchange->getTicker('TSC', 'CNDT');
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last']);
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['TIX'])) {
            $exchange = ExchangeFactory::createExchange("Ceohk");
            $quotation = $exchange->getTicker('TIX', 'QC');
            $quotation['rmb'] = $quotation['last'];
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['KPC8'])) {
//            $exchange = ExchangeFactory::createExchange("Biki");
//            $quotation = $exchange->getTicker('KPC8', 'USDT');
//            goto doEnd;
            $quotation = [
                'low' => 1,
                'high' => 1,
                'last' => 1,
            ];
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['BVA'])) {
            $exchange = ExchangeFactory::createExchange("Bilaxy");
            $quotation = $exchange->getTicker('BVA', 'USDT');
            goto doEnd;
        }

        if (in_array(strtoupper($tag), ['SJPY'])) {
            $exchange = ExchangeFactory::createExchange("Boc");
            $quotation = $exchange->getTicker('CNY', 'JPY');
            $quotation = [
                'low' => (float)sprintf("%0.4f", $quotation['low'] / 100),
                'high' => (float)sprintf("%0.4f", $quotation['high'] / 100),
                'last' => (float)sprintf("%0.4f", $quotation['last'] / 100),
                'rmb' => (float)sprintf("%0.2f", $quotation['last'] / 100),
            ];
            goto doEnd;
        }

        foreach (self::$exchanges as $exchange) {
            /**
             * @var $exchange \common\service\exchange\Exchange
             */
            $exchange = ExchangeFactory::createExchange($exchange);
            if ($exchange->symbolExists($tag)) {
                $quotation = $exchange->getTicker($tag);
                $f = true;
                break;
            }
        }
        if (!$f) {
            //所有交易所都不能直接获取交易对的行情就通过BTC去转换
            //获取BTC_USD
            $btc_usd = ExchangeFactory::createExchange(self::$exchanges[1])->getTicker('btc');
            foreach (self::$exchanges as $exchange) {
                /**
                 * @var $exchange \common\service\exchange\Exchange
                 */
                $exchange = ExchangeFactory::createExchange($exchange);
                if ($exchange->symbolExists($tag, 'btc')) {
                    $price_btc = $exchange->getTicker($tag, 'btc');
                    //获取btcusdt
                    $result = array_map(function ($a, $b) {
                        return $a * $b;
                    }, $price_btc, $btc_usd);
                    $quotation = ['low' => $result[0], 'high' => $result[1], 'last' => $result[2]];
                    $f = true;
                    break;
                }
            }
        }
        if (!$f || empty($quotation)) {
            return false;
        }
        //格式化行情数据
        foreach ($quotation as $key => $item) {
            $quotation[$key] = (float)sprintf("%0.4f", (double)$item);
        }
        //用YCC计算汇率
        /**
         * @var $exchange \common\service\exchange\Exchange
         */
        $exchange = ExchangeFactory::createExchange("Go");
        $rate = $exchange->getTicker("CNY", "USD");
        $rate = $rate['last'] ?? '';
        if (empty($rate)) {
            $exchange = ExchangeFactory::createExchange("Bty");
            $rate = $exchange->getTicker("BTY", "USDT");
            $rate = (float)$rate['rmb'] / $rate['last'];
        }
        $quotation['rmb'] = (float)sprintf("%0.4f", $rate * $quotation['last']);

        doEnd :
        $exchange = ExchangeFactory::createExchange("Go");
        $rate = $exchange->getTicker("CNY", "USD");
        $cny_usd_rate = 1 / $rate['last'];
        if (in_array(strtoupper($tag), ['FOLI', 'CIC', 'KPC8', 'BVA', 'DAG', 'BNC', 'GHP', 'DRA'])) {
            $quotation['usd'] = (float)sprintf("%0.4f", $quotation['last']);
            $quotation['rmb'] = (float)sprintf("%0.4f", $quotation['last'] / $cny_usd_rate);
        } else if (in_array(strtoupper($tag), ['SUSD'])) {
            $quotation['usd'] = (float)sprintf("%0.4f", 1);
        } else {
            $quotation['usd'] = (float)sprintf("%0.4f", $quotation['rmb'] * $cny_usd_rate);
        }
        return $quotation;
    }

    /**
     * 保存各个交易所支持的交易对到redis,定时用crontab更新
     *
     * @return void
     */
    public static function setSupportedSymbol()
    {
        foreach (self::$exchanges as $exchange) {
            /**
             * @var $exchange \common\service\exchange\ExchangeInterface
             */
            $exchange = ExchangeFactory::createExchange($exchange);
            $exchange->setSupportedSymbol();
        }
    }

    /**
     * 更新交易所的行情数据保存到redis,定时更新
     *
     * @return void
     */
    public static function setQuotation()
    {
        foreach (self::$exchanges as $exchange) {
            /**
             * @var $exchange \common\service\exchange\ExchangeInterface
             */
            go(function () use ($exchange) {
                \Co::sleep(0.5);
                $exchange = ExchangeFactory::createExchange($exchange);
                $exchange->setQuotation();
            });
        }
    }

    /**
     * 根据name返回币种信息
     *
     * @param  array $condition 需要的币种sid列表
     * @return array
     */
    public static function getApiListForIndex($page = 1, $limit = 999, $condition = [], $fields = [])
    {
        if (count($condition[0]) > 1) {
            foreach ($condition as $val) {
                if ('null' == $val[1] || 'coin' == $val[1]) {
                    $data[] = Coin::find()->select('id,sid,icon,name,optional_name,nickname,introduce,platform,chain,address as contract_address,treaty')
                        ->where(['name' => $val[0]])
                        ->asArray()
                        ->one();
                    continue;
                }
                $data[] = Coin::find()->select('id,sid,icon,name,optional_name,nickname,introduce,platform,chain,address as contract_address,treaty')
                    ->where(['name' => $val[0]])
                    ->andWhere(['platform' => $val[1]])
                    ->asArray()
                    ->one();
            }
        } else {
            $data = Coin::find()->select('id,sid,icon,name,optional_name,nickname,introduce,platform,chain,address as contract_address,treaty')
                ->where(['in', 'name', $condition])
                ->asArray()->all();
        }
        $rows = [
            'count' => count($data),
            'data' => $data
        ];

        $count = 0;
        if (!empty($rows) && is_array($rows) && array_key_exists('count', $rows)) {
            $count = $rows['count'];
        }
        if ($rows['count'] > 0) {
            $rows = $rows['data'];
            foreach ($rows as $key => $row) {
                $rows[$key]['sid'] = ucfirst($rows[$key]['sid']);
                $quotation = self::getquatation($row['name']);
                if (!$quotation) {
                    $quotation = [];
                    if (in_array($row['name'], ['BTY', 'YCC'])) {
                        $coinServer = CoinFactory::createCoin($row['name'], $row['id'], $row['sid']);
                        $rows[$key]['sid'] = ucfirst($rows[$key]['sid']);
                        $rows[$key]['rmb'] = $coinServer->getPrice();
                        $rows[$key]['last'] = $coinServer->getDollar();
                        $rows[$key]['low'] = $coinServer->getLow();
                        $rows[$key]['high'] = $coinServer->getHigh();
                        $coinServer->__destruct();
                    } else {
                        $rows[$key]['rmb'] = 0;
                        $rows[$key]['last'] = 0;
                        $rows[$key]['low'] = 0;
                        $rows[$key]['high'] = 0;
                        $rows[$key]['usd'] = 0;
                    }
                }
                if (strtoupper($row['platform']) == 'GUODUN') {
                    $rows[$key]['rmb'] = 0;
                    $rows[$key]['last'] = 0;
                    $rows[$key]['low'] = 0;
                    $rows[$key]['high'] = 0;
                } else {
                    $rows[$key] = array_merge($rows[$key], $quotation);
                }
            }
            return ['code' => 0, 'count' => $count, 'data' => $rows];
        }
        return [];
    }

    /**
     * 根据名称搜索
     *
     * @param  int $page
     * @param  int $limit
     * @param  array $condition
     * @return array|\yii\db\ActiveRecord|\yii\db\ActiveRecord[]
     */
    public static function SearchByName($page = 1, $limit = 10, $condition = [])
    {
        $rows = Coin::getSelectList($page, $limit, ['id', 'sid', 'icon', 'name', 'optional_name', 'nickname', 'platform', 'chain', 'address as contract_address', 'treaty'],
            $condition);
        if ($rows['count'] > 0) {
            $total = $rows['count'];
            $rows = $rows['data'];
            foreach ($rows as $key => $row) {
                $rows[$key]['sid'] = ucfirst($rows[$key]['sid']);
                $platform = strtoupper($rows[$key]['platform']);
                $platform_icon = Yii::$app->redis->hget('platform_image_info', $platform);

                $rows[$key]['platform_icon'] = $platform_icon ?? '';
            }
            return ['total' => $total, 'data' => $rows];
        }
        return [];
    }

    public static function getQuatationByNames($names)
    {
        $result = [];
        foreach ($names as $key => $value) {
            $quotation = self::getquatation($value);
            if (!$quotation) {
                $quotation = [];
                //使用Coin服务
                try {
                    $coinServer = CoinFactory::createCoin($row['name'], $row['id'], $row['sid']);
                    $quotation['rmb'] = $coinServer->getPrice();
                    $quotation['last'] = $coinServer->getDollar();
                    $quotation['low'] = $coinServer->getLow();
                    $quotation['high'] = $coinServer->getHigh();
                    $coinServer->__destruct();
                } catch (\Exception $exception) {
                    $quotation['rmb'] = 0;
                    $quotation['last'] = 0;
                    $quotation['low'] = 0;
                    $quotation['high'] = 0;
                    \Yii::error($exception->getMessage());
                }
            }
            $result[$value] = $quotation;
        }
        return $result;
    }
}