<?php
namespace app\apicom\model;
use app\apicom\model\StockSubAccount;
use app\apicom\model\SubAccountMoney;
use app\apicom\model\StockSubAccountRisk;
use think\Model;
use think\facade\Db;

use util\RedisUtil;
use util\QuotationRedis;

class Trust extends Base
{
    // 设置当前模型对应的完整数据表名称
    protected $name = 'stock_trust';
    // 自动写入时间戳
    protected $autoWriteTimestamp = true;
    // 买入时检查
    public static function execute($data, $trustModel)
    {
        //检测是否为禁买股票
        $res = self::checkStatus($data['code']);
        if ($res) return ['status'=>0, 'message'=>'该股票禁止交易'];
        //判断购买数量书否正确
		if (($data['count'] % 100) != 0) return ['status'=>0, 'message'=>'交易数量必须是100的整数倍'];
		$bs_res = Db::name('stock_borrow')->where(array('stock_subaccount_id' => $data['subid']))->find();
		if (empty($bs_res)) {
			return ['status'=>0, 'message'=>'没有对应的配资'];
		}
		if ($bs_res['end_time'] <= time()){
			return ['status'=>0, 'message'=>'该账户已逾期，请先续期'];
		}
		if($trustModel == 'buy'){
		    return self::trustBuy($data,$bs_res);
		}
		if($trustModel == 'sell'){
		    return self::trustSell($data);
		}
		
    }
    
    
    public static function trustBuy($data,$bs_res)
    {
		//查询股票最新行情
		$Qdata = RedisUtil::getQuotationData($data['code'],toMarket($data['code']));
		$price = $data['price'] <= 0 ? $Qdata['Price'] : $data['price'];
		//判断股票价格是否符号购买条件
		if (sysConfig('stock_buy_price') > 0) {
			if ($price < sysConfig('stock_buy_price')) {
				return ['status'=>0, 'message'=>'系统设定低于'.sysConfig('stock_buy_price').'元一股的股票不能购买'];
			}
		}
		//检查卖量是否正常
		$trade_money = self::checkTranMoney($Qdata, $data['count'], $price);
		if ($trade_money <= 0) return ['status'=>0, 'message'=>'卖量不足或网络错误'];
		//判断卖量和股票限额
		$pos_sum = self::checkPositionSum($Qdata, $data['subid'],$data['code'],$data['count'],$price,$trade_money);
		if (isset($res['quota']) && ($res['quota'] < (($pos * $Qdata['Price']) + $trade_money))) {
			return ['status'=>0, 'message'=>'该股票超过了单支股票最大购买限额'];
		}
		//检查子账户余额
		$moneymodel = new SubAccountMoney();
		$moneyinfo  = $moneymodel->getAccountMoney($data['subid']);
		if ($moneyinfo['avail'] < $trade_money){
			return ['status'=>0, 'message'=>'购买资金不足'];
		}
		
		// 免息配资结束当天不能买入
		if ($bs_res['type'] == 5) {
			if($bs_res['end_time'] < time() + 23 * 3600) {
				return ['status'=>0, 'message'=>'免息配资结束当天不能买入'];
			}
		}
		// 设置试用配资第二天不能再买入
		if ($bs_res['type'] == 4) {
			if($bs_res['end_time'] < time() + 23 * 3600) {
				return ['status'=>0, 'message'=>'试用配资结束当天不能买入'];
			}
		}
		$risk     = new StockSubAccountRisk;
		$risk_res = $risk->getRisk($data['subid']);
		if ($risk_res['prohibit_open'] == 0){
			return ['status'=>0, 'message'=>'您被禁止开新仓，请联系管理员咨询原因'];
		}
		
		
		$retData['trade_money'] = $trade_money;
		$retData['moneyinfo']   = $moneyinfo;
		$retData['price']       = $price;
		
		return $retData;
    }
    
    //卖出时检查
    public static function trustSell($data)
    {
		//查询股票最新行情
		$Qdata = RedisUtil::getQuotationData($data['code'],toMarket($data['code']));
		$price = $data['price'] <= 0 ? $Qdata['Price'] : $data['price'];
		
		if(sysConfig('site_trade_sell') == 0) {
            return array('status' => 0, 'message' => '系统设置不允许卖出股票');
        }
		//检测股票可卖数量
		$poscount = StockPosition::getCanbuyCount($data['subid'], $data['code']);
        if ($poscount < $data['count']) {
			return ['status'=>0, 'message'=>'可卖股票不足'];
		}
		//当股票跌停时买一至买五价格为空
        if(intval($Qdata["Bp1"]) <= 0 || intval($Qdata['Bv1']*100) < $data['count']){
            return ['status'=>0, 'message'=>'当前买盘不足，无法即时成交！'];
        }
        //检查子账户余额
		$moneyinfo  = SubAccountMoney::getAccountMoney($data['subid']);
		
		$trade_money = 0;
        if($data['price'] > 0 && $data['model'] == 1){ //model = 1 是委托状态
            $trade_money = intval($data['count']) * intval($data['price']);
        }else{
            $price = $Qdata['Price'];
            //如果没有委托价格使用下面的公式
            $trade_money = intval($data['count']) * intval($price);
        }
		
		$retData['trade_money'] = $trade_money;
		$retData['moneyinfo']   = $moneyinfo;
		$retData['price']       = $price;
		
		return $retData;
    }
    
    /*查询禁买股票列表*/
    public static function checkStatus($code)
    {
        $res = Db::name('stock_list')->where(['code' => $code, 'status' => 0])->find();
		return $res;
    }
    /*
	 * 验证卖量是否正常
	 */
	public static function checkTranMoney($Qdata, $count, $price)
	{
	    $trade_money = 0;
		if (!(empty($price))) {
			$trade_money = $count * $price;
		}else{
			$price = 0;
			$v_arr[1] = $Qdata['Sv1'] * 100;
			$v_arr[2] = $Qdata['Sv2'] * 100;
			$v_arr[3] = $Qdata['Sv3'] * 100;
			$v_arr[4] = $Qdata['Sv4'] * 100;
			$v_arr[5] = $Qdata['Sv5'] * 100;
			$p_arr[1] = $Qdata['Sp1'];
			$p_arr[2] = $Qdata['Sp2'];
			$p_arr[3] = $Qdata['Sp3'];
			$p_arr[4] = $Qdata['Sp4'];
			$p_arr[5] = $Qdata['Sp5'];
			$tmd = 0;
			foreach ($v_arr as $key => $v ){
				$tmd = $tmd + $v;
				if ($count <= $tmd){
					$sum_money = 0;
					$sum_count = $count;
					for ($i = 1; $i < $key; $i++){
						$sum_money += $v_arr[$i] * $p_arr[$i];
						$sum_count -= $v_arr[$i];
					}
					$trade_money = $sum_money + ($sum_count * $p_arr[$key]);
					$price = round($trade_money / $count, 2);
					$trade_money = $count * $price;
					break;
				}
			}
		}
		return $trade_money ?? 0;
	}
    /*
     * 返回子账号单只股票持仓数量
     * $subid 子账号 $code 股票代码
     */
    public static function checkPositionSum($Qdata,$subid,$code,$count,$price,$trade_money)
    {
        $res = Db::name('stock_list')->where(['code' => $code, 'status' => 1])->find();
		//判断是否超过该只股票限额
		$pos = Db::name('stock_position')->where(['sub_id' => $subid,'gupiao_code' => $code,'buying' => 0])->sum('stock_count');
		return $pos;
    }
    /*
     * 存储委托记录
     * $data 持仓数据
     * $sub_id 子账号
     * $lid 安全模式id号
     * $user 证券账户
     * $soure 证券来源
     */
    public static function add_trust_broker($data,$lid,$user,$soure){
        $row=array();
        foreach ($data as $k => $value) {
            $row[$k]['lid'] = $lid;
            $row[$k]['soruce'] = $soure;
            $row[$k]['login_name'] = $user;
            $row[$k]['add_time'] = strtotime($value[0]);
            $row[$k]['trust_time'] = $value[1];
            $row[$k]['gudong_code'] = $value[2];
            $row[$k]['type'] = $value[3];
            $row[$k]['gupiao_code'] = $value[4];
            $row[$k]['gupiao_name'] = $value[5];
            $row[$k]['flag1'] = $value[6];
            $row[$k]['flag2'] = $value[7];
            $row[$k]['trust_price'] = $value[8];
            $row[$k]['trust_count'] = $value[9];
            $row[$k]['trust_no'] = $value[10];
            $row[$k]['volume'] = $value[11];
            $row[$k]['amount'] = $value[12];
            $row[$k]['cancel_order_count'] = $value[13];
            $row[$k]['status'] = $value[14];
            $row[$k]['cancel_order_flag'] = $value[15];
            $row[$k]['trust_date'] = strtotime($value[16]);
            if(isset($value[17])){
                $row[$k]['beizhu'] = $value[17];
            }else{$row[$k]['beizhu']="";}
            if(isset($value[18])){
                $row[$k]['info'] = $value[18];
            }else{$row[$k]['info'] ="";}
            $row[$k]['type_today'] = 1;
        }
        $result = Db::name('stock_trust_broker')->insertall($row,true);
        return $result;
    }
    /*
     * 存储模拟卖出委托记录
     */
    public static function sell_m_trust($data, $price, $Trust_no, $sys = 0){
        //检查子账户是否正常
		$subres = StockSubAccount::getAccountById($data['subid']);
		$broker = StockSubAccount::getBroker($subres['account_id']);
		if (!$subres) return ['status'=>0, 'message'=>'子账号或证券公司不存在'];
        $row=array();
        $row[0]['sub_id']      = $data['subid'];
        $row[0]['lid']         = $broker['lid'];
        $row[0]['soruce']      = $broker['stockjobber'];
        $row[0]['login_name']  = $broker['user'];
        $row[0]['add_time']    = time();//委托日期
        $row[0]['trust_time']  = date('H:i:s',time());//委托时间
        $row[0]['gudong_code'] = "";//股东代码
        $row[0]['type']        = 0;//帐号类别
        $row[0]['market']      = $data["market"];//股票类别
        $row[0]['gupiao_code'] = $data['code'];//证券代码
        $row[0]['gupiao_name'] = $data['name'];//证券名称
        $row[0]['flag1']       = 1;//买卖标志1
        $row[0]['flag2']       = "卖出委托";//买卖标志2
        $row[0]['trust_price'] = $price;
        $row[0]['trust_count'] = $data['count'];
        $row[0]['trust_no']    = $Trust_no;//委托编号
        $row[0]['volume']      = 0;//成交数量
        $row[0]['amount']      = 0;//成交金额
        $row[0]['status']      = "已委托";//状态说明
        $row[0]['trust_date']  = date('Y-m-d',time());//委托日期
        $row[0]['beizhu']      = $sys == 1 ? "系统强平" : "自主委托";
        $row[0]['info']        = $sys == 1 ? "system" : "self";
        $row[0]['type_today']  = 1;
        $row[0]['cancel_order_flag']  = 0;//撤单标志
        $row[0]['cancel_order_count'] = 0;
        $result = Db::name('stock_trust')->insert($row[0],true);
        return $result;
    }
    /*
     * 存储模拟买入委托记录
     */
    public static function add_m_trust($data, $price, $Trust_no)
    {
        $subres = StockSubAccount::getAccountById($data['subid']);
		$broker = StockSubAccount::getBroker($subres['account_id']);
		if (!$subres) return ['status'=>0, 'message'=>'子账号或证券公司不存在'];
        $row = array();
        $row[0]['sub_id']      = $data['subid'];
        $row[0]['lid']         = $broker['lid'];
        $row[0]['soruce']      = $broker['stockjobber'];
        $row[0]['login_name']  = $broker['user'];
        $row[0]['add_time']    = time();//委托日期
        $row[0]['trust_time']  = date('H:i:s',time());//委托时间
        $row[0]['gudong_code'] = "";//股东代码
        $row[0]['type']        = 0;//帐号类别
        $row[0]['market']      = $data["market"];//股票类别
        $row[0]['gupiao_code'] = $data['code'];//证券代码
        $row[0]['gupiao_name'] = $data['name'];//证券名称
        $row[0]['flag1']       = 0;//买卖标志1
        $row[0]['flag2']       = "买入委托";//买卖标志2
        $row[0]['trust_price'] = $price;
        $row[0]['trust_count'] = $data['count'];
        $row[0]['trust_no']    = $Trust_no;//委托编号
        $row[0]['volume']      = 0;//成交数量
        $row[0]['amount']      = 0;//成交金额
        $row[0]['status']      = "已委托";//状态说明
        $row[0]['trust_date']  = date('Y-m-d',time());//委托日期
        $row[0]['beizhu']      = "";
        $row[0]['info']        = "";
        $row[0]['type_today']  = 1;
        $row[0]['cancel_order_flag']  = 0;//撤单标志 0、可撤
        $row[0]['cancel_order_count'] = 0;
        $result = Db::name('stock_trust')->insert($row[0],true);
        return $result;
    }
    /*
     * 添加可撤单委托
     *
     */
    public static function add_cancel_trust($data,$sub_id){
        $subres = StockSubAccount::getAccountById($data['subid']);
		$broker = StockSubAccount::getBroker($subres['account_id']);
		if (!$subres) return ['status'=>0, 'message'=>'子账号或证券公司不存在'];
        $row=array();
        foreach ($data as $k => $value) {
            $row[$k]['sub_id']      = $sub_id;
            $row[$k]['lid']         = $broker['lid'];
            $row[$k]['soruce']      = $broker['stockjobber'];
            $row[$k]['login_name']  = $broker['user'];
            $row[$k]['add_time']    = strtotime($value[0]);
            $row[$k]['trust_time']  = $value[1];
            $row[$k]['gudong_code'] = $value[2];
            $row[$k]['type']        = $value[3];
            $row[$k]['gupiao_code'] = $value[4];
            $row[$k]['gupiao_name'] = $value[5];
            $row[$k]['status']      = $value[6];
            $row[$k]['flag1']       = $value[7];
            $row[$k]['flag2']       = $value[8];
            $row[$k]['trust_price'] = $value[9];
            $row[$k]['trust_count'] = $value[10];
            $row[$k]['trust_no']    = $value[11];
            $row[$k]['volume']      = $value[12];
            $row[$k]['cancel_order_count'] = $value[13];
            $row[$k]['trust_date']  = date('Y-m-d',strtotime($value[14]));
            $row[$k]['info']        = $value[15];
            $row[$k]['type_today_back'] = 1;
        }
        $result = Db::name('stock_trust')->insertAll($row,true);
        return $result;
    }
    /*
     * 返回子账号当日委托
     * $sub_id 子账号
     */
    public static function get_trust_day($sub_id){
        $time = date('Y-m-d',time());
        $res  = Db::view('stock_trust trust')
            ->view('stock_subaccount sub','sub_account','sub.id = trust.sub_id')
            ->where(['sub_id'=>$sub_id,'trust_date'=>$time])
            ->order('id desc')
            ->select()
            ->toArray();
        return $res;
    }
    /*
     * 返回子账号委托
     * $sub_id 子账号
     */
    public static function get_trust($sub_id, $beginday, $endday, $page=1, $offset=15)
    {
        $endday   = $endday ? $endday : date("Y-m-d",time());
        $beginday = $beginday ? $beginday : date("Y-m-d",time());
        
        $res = Db::view('stock_trust trust')
            ->view('stock_subaccount sub','sub_account','sub.id = trust.sub_id')
            ->where(['sub_id'=>$sub_id])
            //->whereTime('trust_date', 'between', [$beginday, $endday])
            ->order('id desc')
            ->paginate($offset, false, ['query' => request()->param()]);
        return $res;
    }
    /*
     * 返回子账号当日当日可撤委托
     * $sub_id 子账号
     */
    public static function get_cancel_trust($sub_id){
        $res  = Db::name('stock_trust')
            ->where(['sub_id'=>$sub_id])
            ->whereDay('trust_date')
            ->where('status','in',['已委托','已撤'])
            ->order('id desc')
            ->paginate();
        return $res;
    }
    /*
     * 存储历史委托记录
     * $data 持仓数据
     * $sub_id 子账号
     * $lid 安全模式id号
     * $user 证券账户
     * $soruce 证券来源
     */
    public static function add_history_trust($data,$lid,$user,$soruce){
        $row=array();
        foreach ($data as $k => $value) {
            $row[$k]['lid'] = $lid;
            $row[$k]['soruce'] = $soruce;
            $row[$k]['login_name'] = $user;
            $row[$k]['add_time'] = strtotime($value[0]);
            $row[$k]['trust_time'] = $value[1];
            $row[$k]['gudong_code'] = $value[2];
            $row[$k]['type'] = $value[3];
            $row[$k]['gupiao_code'] = $value[4];
            $row[$k]['gupiao_name'] = $value[5];
            $row[$k]['flag1'] = $value[6];
            $row[$k]['flag2'] = $value[7];
            $row[$k]['trust_price'] = $value[8];
            $row[$k]['trust_count'] = $value[9];
            $row[$k]['trust_no'] = $value[10];
            $row[$k]['volume'] = $value[11];
            $row[$k]['amount'] = $value[12];
            $row[$k]['cancel_order_count'] = $value[13];
            $row[$k]['status'] = $value[14];
            $row[$k]['cancel_order_flag'] = "";
            $row[$k]['trust_date'] = $value[15];
            $row[$k]['beizhu']="";
            $row[$k]['info'] ="";
            $row[$k]['type_today'] = 1;
        }
        $result = Db::name('stock_trust_broker')->insertall($row,true);
        return $result;
    }

}