<?php
declare (strict_types = 1);

namespace app\command;
use app\apicom\model\SubAccountMoney;
use app\apicom\model\Borrow as BorrowModel;
use app\apicom\model\StockPosition;
use app\apicom\model\Renewal;
use app\apicom\model\Money;
use app\apicom\model\Record as RecordModel;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
use util\RedisUtil;

use function Swoole\Coroutine\run;
use \co\Http\Client;

class Auto extends Command
{
    protected $countFlag = 0;
    //重复多少次后停止轮询
    protected $stopFlags = 10;
    
    protected function configure()
    {
        // 指令配置
        $this->setName('auto')->setDescription('风控和设置可卖数量脚本');
    }

    protected function execute(Input $input, Output $output)
    {
        // 启动协程
    	swoole_timer_tick(5000, function (){
		    //启动风控脚本
    		$this->autoClose();
    		/*启动可卖数量客户端*/
        	$this->autoSellCount();
        	//启动自动续期客户端
        	$this->autoRenewal();
		});
		\Swoole\Event::wait();
    }
    
    /*
     * 自动平仓
     */
    private function autoClose()
    {
        if(!checkTradeTime()) return false;
        //自动平仓开始
        $res = $this->getPositions();
        if(empty($res)) return false;
        foreach ($res as $key=>$val){
            $pos = StockPosition::getPositionFind($val['sub_id']);
            $market_value = 0;
            foreach ($pos as $k => $v){
                $market_value += round($v['market_value'], 2);
            }
            $inf = SubAccountMoney::getAccountMoneyInf($val['sub_id']);
            $inf['total_money'] = round($market_value + $inf['avail'] + $inf['freeze_amount'], 2);
            //print_r($inf);return;
            if ($inf['total_money'] <= $inf['loss_close_money']) {
                // 去平仓
                go(function () use($pos) {
                    $this->doClose($pos);
                });
            }
        }
    }
    /*
     * 去平仓操作
     */
    private function doClose($pos)
    {
        foreach ($pos as $key => $val) {
            $data = array(
                'subid' => $val['sub_id'],
                'code'  => $val['gupiao_code'],
                'count' => $val['canbuy_count'],
            );
            BorrowModel::savesell($data,1);
        }
    }
    /*
     * 获取可自动平仓股票
     */
    private function getPositions()
    {
        $res = Db::view("stock_position p")
            ->view('stock_borrow b','sub_account','b.stock_subaccount_id = p.sub_id','left')
            ->view("stock_subaccount_risk s",'autoclose','p.sub_id = s.stock_subaccount_id','left')
            ->where(['p.buying' => 0, 's.autoclose' => 1])
            ->where('b.status','<>',0)
            ->group('p.sub_id')
            ->select();
        return $res;
    }
    /****************************************************************************************************************************/
    /*
     * 初始化可卖数量
     */
    private function autoSellCount()
    {
	    // 达到条件：设置持仓可卖数量、设置条件单过期
	    if(checkTradeTime()) {
	        $this->countFlag = 0;
	        $this->output->writeln(date('Y-m-d H:i:s').' 当前为开市时间段，不可改变持仓可卖数量');
	        return false;
	    }elseif (intval(date('Hi')) >= 1505 || intval(date('Hi')) <= 929) {
            if($this->countFlag < $this->stopFlags){
                $res = $this->volumeForSell();
                if($res){
                    $this->output->writeln(date('Y-m-d H:i:s').' 当前为休市时间段，已改变持仓可卖数量，并跳出轮询');
                    $this->countFlag = $this->stopFlags;
                }
            }
        }
	    /*
        if (intval(date('Hi')) >= 1505 || intval(date('Hi')) <= 929) {
            if($this->countFlag < $this->stopFlags){
                $res = $this->volumeForSell();
                if($res){
                    $this->output->writeln(date('Y-m-d H:i:s').' 当前为休市时间段，已改变持仓可卖数量，并跳出轮询');
                    $this->countFlag = $this->stopFlags;
                }
            }
        }else{
            $this->countFlag = 0;
	        return false;
        }
        */
    }
    /*
     * 设置持仓可卖数量
     */
    private function volumeForSell()
    {
        $count = Db::name('stock_trust')->where('status','已委托')->count();
        if(!$count){
            $ret = Db::name('stock_position')->where(['buying'=>0,'selling'=>0])->update(['canbuy_count' => Db::raw("stock_count")]);
            $this->countFlag += 1;
            return $ret ? true : false;
        }
        return false;
    }
    /*****************************************************************************************************************************/
    /*
     * 自动续期
     */
    private function autoRenewal()
    {
        $where = ['r.renewal'=> 1];
        $where = ['b.status' => 1];
        $list  = BorrowModel::getEnd($where)->toArray();
        //return ajaxmsg('=已到期的配资=',1,$list);
        //判断获取的数组是否有效
        if(!isset($list['data']) || empty($list['data'])) return false;
        //开始分别计算出续期费用
        foreach ($list['data'] as $key => $val){
            $peiziMoney = $val['borrow_money'];
            $multiple   = intval($val['multiple']);
            switch ($val['type']){
                case '按天配资':
                    $type = 1;
                    $rateSet = arrayEol(sysConfig('day_rate'),1);
                    $rate = $rateSet[$multiple]/100;
                    break;
                case '按周配资':
                    $type = 2;
                    $rateSet = arrayEol(sysConfig('week_rate'),1);
                    $rate = $rateSet[$multiple]/100;
                    break;
                case '按月配资':
                    $type = 3;
                    $rateSet = arrayEol(sysConfig('month_rate'),1);
                    $rate = $rateSet[$multiple]/100;
                    break;
                default:
                    $type = 0;
                    $rate = 0;
                    break;
            }
            if($rate > 0){
                // 延期一次性计算利息 计算方式：利息 * 时间 * 配资金额
                $borrow_fee = $peiziMoney*$rate*1;//数字1为续期的周期，天=>1天；周=>1周；月=>1月
                $msg = "配资[".$val['sub_account']."]自动续期，扣除续期利息{$borrow_fee}元";
                $endTime = Renewal::getAddTime($type,$val['end_time'],1);//数字1为续期的周期，天=>1天；周=>1周；月=>1月
                Db::startTrans();
                $minfo = Db::name("money")->lock(true)->where('mid',$val['member_id'])->find();
                if(!$minfo){
                    Db::rollback();
                    break;
                }
                $mmoney['account'] = $minfo['account'] - $borrow_fee;
                //如果余额小于0，说明账户余额不足，就此停止
                if($mmoney['account'] < 0) break;
                $ret_m = Money::money_up($val['member_id'], $mmoney);
                $ret_b = Db::name("stock_borrow")->where("id",$val['id'])->update(['end_time' => $endTime]);
                $ret_r = RecordModel::saveData($val['member_id'], $borrow_fee, $minfo['account'], 80, $msg);
                
                if($ret_m && $ret_b){
                    Db::commit();
                }else{
                    Db::rollback();
                }
            }
            $this->output->writeln(date('Y-m-d H:i:s').' '.$msg);
            //print_r($endTime);echo "\n";
        }
    }
}
