<?php
declare (strict_types = 1);

namespace app\apicom\controller;
use app\apicom\model\StockSubAccount;
use app\apicom\model\SubAccountMoney;
use app\apicom\model\StockPosition;
use app\apicom\model\StockDeliveryOrder as Delivery;
use app\apicom\model\StockSubAccountRisk;
use app\apicom\model\Trust;
use app\apicom\model\StockDealStock;
use app\apicom\model\Borrow;
use think\Log;
use think\facade\Db;
use util\RedisUtil;

class Trade extends BaseController
{
	/*
	 * 持仓查询
	 */
	public function position()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$subid = input('subid', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);//子账户ID
		if(!$subid) return ajaxmsg('参数不正确',0);
		$res = StockSubAccount::getAccountById($subid);
		if (!$res) return ajaxmsg('不存在的子账号',0);
		if (empty($res['account_id'])) return ajaxmsg('证券公司不存在', 0);
		$data = StockPosition::where(['sub_id' => $subid,'buying' => 0])->where('stock_count','>',0)->order('id desc')->paginate(20, false, ['query' => request()->param()]);
		if (!$data || count($data) === 0) return ajaxmsg('没有数据',0,$data);
        foreach ($data as $k => $item){
            //查询当天交易的数量 T+1 交易
            //$todayCount = Delivery::getDeliveryOrder($subid,$item["gupiao_code"]);
            $data[$k]['canbuy_count']      = $item['canbuy_count'];
            //查询股票最新行情
            $Qdata = RedisUtil::getQuotationData($item["gupiao_code"],toMarket($item["gupiao_code"]),true);
            //查询子账户
            $data[$k]['sub_account']       = $res['sub_account'];
            //提取当前价格
            $data[$k]['now_price']         = $Qdata['Price'];
            //市值 = 当前价格*数量
            $data[$k]['market_value']      = round($Qdata['Price']*$item['stock_count'],2);
            //参考成本价
            $data[$k]['ck_price']          = StockPosition::calculate($subid,$item["gupiao_code"],'price');
            //买入均价
            $data[$k]['buy_average_price'] = StockPosition::calculate($subid,$item["gupiao_code"],'average');
            //参考盈亏
            //$data[$k]['ck_profit']         = $item['stock_count'] > 0 ? round(($Qdata['Price']-$data[$k]['buy_average_price'])*$item['stock_count'], 2) : 0;
            $data[$k]['ck_profit']         = $item['stock_count'] > 0 ? bcmul(strval($Qdata["Price"]-$data[$k]['buy_average_price']),strval($item['stock_count']),2) : 0;//参考浮动盈亏
            //盈亏比例
            //$data[$k]['profit_rate']       = $item['stock_count'] > 0 ? round(($data[$k]['ck_profit'] / ($data[$k]['buy_average_price'] * $item['stock_count'])) * 100, 2) : 0;
            //$data[$k]['profit_rate']       = $item['stock_count'] > 0 ? bcdiv(strval($data[$k]['ck_profit']),strval($data[$k]['buy_average_price']*$item['stock_count']*100),2) : 0;//盈亏比例
            //当天可卖数量计算
            //$data[$k]['canbuy_count']      = StockPosition::getCanbuyCount($subid,$item["gupiao_code"]);
        }
		return ajaxmsg('操作成功',1,$data);
	}
	/*
	 * 证券买入
	 */
	public function buy()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		if (!checkTradeTime()) return ajaxmsg('非交易时间',0);
		if (!sysConfig('site_trade_buy')) return ajaxmsg('系统设置为禁买状态',0);
        $data  = [
            "subid"  => input('subid','', ['trim', FILTER_SANITIZE_NUMBER_INT]),//子账户ID,
    	    "code"   => input('code' ,'', ['trim', FILTER_SANITIZE_NUMBER_INT]),//股票代码
    	    "name"   => input('name' ,''),//股票名称
    	    "market" => input('market',''),//交易所代码
    	    "count"  => input('count', 0, ['trim', FILTER_SANITIZE_NUMBER_INT]),//购买数量
    	    "price"  => input('price', 0, ['trim']),
    	    'model'  => input('model', 1, ['trim', FILTER_SANITIZE_NUMBER_INT]),//1：是委托状态
        ];
        //验证数据
        $result = $this->validate($data, 'Trade.trade');
        if(!$result) return ajaxmsg($result,0);
		//检查其他买入条件是否符合
        $trade_res  = Trust::execute($data,'buy');
        if(isset($trade_res['status'])&&!$trade_res['status']) return ajaxmsg($trade_res['message'],0);
		
		$trade_money = $trade_res['trade_money'];
		$moneyinfo   = $trade_res['moneyinfo'];
		$price       = $trade_res['price'];
		//计算佣金  commission_scale：佣金比例（单位：万分之几） 如：5 代表万分之五；  min_commission：最低佣金（单位：元）
		$commission  = commission($trade_money,$moneyinfo['commission_scale'],$moneyinfo['min_commission']);
		//计算过户费
		$transfer    = transfer($trade_money);
		//写入子账户资金变化表
		Db::startTrans();
		$effectMoney = $trade_money + $commission + $transfer;
		/*(子账户ID, 金额*100, 买卖方向[1：买入 2：卖出], 盈亏金额, 实盘相关, 股票代码)*/
		$ret  = SubAccountMoney::upMoneyLog($data['subid'], $effectMoney, 3, 0, 0, $data['code']);
		if (!$ret){
			Db::rollback();
			return ajaxmsg('委托失败!',0);
		}
		$Trust_no  = mt_rand(101010, 999999) . substr(strval(time()), 1);
		//添加到委托表
		$Trust_res = Trust::add_m_trust($data, $price, $Trust_no);
		if(!$Trust_res){
			Db::rollback();
			return ajaxmsg('委托失败!',0);
		}
        //持仓数量查询
		$position = Db::name('stock_position')->where(['sub_id' => $data['subid'],'gupiao_code' => $data['code'],'buying' => 0])->find();
		$amount   = empty($position) ? $data['count'] : $position['canbuy_count'] + $data['count'];
		
		//提交交易费用信息
		$Delivery = new Delivery;
		$avail    = ($moneyinfo['avail']) - $effectMoney;
		//print_r("佣金: ".$commission." 过户费: ".$transfer." 总计：".$effectMoney);Db::rollback();exit;
		$del_res  = $Delivery->add_m_delivery_order($data['code'], $data['count'], $price, $data['subid'], $commission, $transfer, $Trust_no, $avail, $amount, $data['model']);
		//print_r($del_res);Db::rollback();exit;
		if(!$del_res){
			Db::rollback();
			return ajaxmsg('委托失败',0);
		}else{
		    Db::commit();
		    return ajaxmsg('买入委托已提交',1);
		}
	}
	
	public function sell()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		if (!checkTradeTime()) return ajaxmsg('非交易时间',0);
		if (sysConfig('site_trade_sell') == 0) 
			return ajaxmsg('系统设置为不允许卖出股票',0);
		if (time() <= strtotime(date("Y-m-d 09:30:15"))) {
			return ajaxmsg('平台设置9点30分15秒后可卖出',0);
		}
		$data  = [
            "subid"  => input('subid','', ['trim', FILTER_SANITIZE_NUMBER_INT]),//子账户ID,
    	    "code"   => input('code' ,'', ['trim', FILTER_SANITIZE_NUMBER_INT]),//股票代码
    	    "name"   => input('name' ,''),//股票名称
    	    "market" => input('market', ''),//交易所代码
    	    "count"  => input('count', 0, ['trim', FILTER_SANITIZE_NUMBER_INT]),//购买数量
    	    "price"  => input('price', 0, ['trim']),
    	    'model'  => input('model', 1, ['trim', FILTER_SANITIZE_NUMBER_INT]),//1：是委托状态
        ];
		//验证数据
        $result = $this->validate($data, 'Trade.trade');
        if(!$result) return ajaxmsg($result,0);
        
		$Trust      = new Trust;
        $trade_res  = $Trust->execute($data,'sell');
        //print_r($trade_res['message']);exit;
        if(isset($trade_res['status'])&&!$trade_res['status']) return ajaxmsg($trade_res['message'],0);
		
		$trade_money = $trade_res['trade_money'];
		$moneyinfo   = $trade_res['moneyinfo'];
		$price       = $trade_res['price'];
		//计算佣金
		$commission  = commission($trade_money,$moneyinfo['commission_scale'],$moneyinfo['min_commission']);
        //印花税
        $stamps      = stamps($trade_money);
		//计算过户费
		$transfer    = transfer($trade_money);
        //写入子账户资金变化表
		Db::startTrans();
		$effectMoney = $trade_money - $transfer - $stamps - $commission;
		$ret = SubAccountMoney::upMoneyLog($data['subid'], $effectMoney, 4);
        if(!$ret){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        $Trust_no  = mt_rand(101010, 999999).substr(strval(time()),1);
        //添加到委托表
        $Trust_res = $Trust->sell_m_trust($data, $price, $Trust_no);
        if(!$Trust_res){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        //持仓数量查询
		$position = Db::name('stock_position')->where(['sub_id' => $data['subid'],'gupiao_code' => $data['code'],'buying' => 0])->find();
		$amount   = $position['canbuy_count'] - $data['count'];
		//持仓减少
		$pos_res  = Db::name('stock_position')->where(['sub_id' => $data['subid'],'gupiao_code' => $data['code'],'buying' => 0])->dec('canbuy_count',intval($data['count']))->update();
        $Delivery = new Delivery;
        $avail    = $moneyinfo["avail"] + $effectMoney;
        $del_res  = $Delivery->sell_m_delivery_order($data['code'], $data['count'], $price, $data['subid'], $commission, $transfer, $Trust_no, $stamps, $avail, $amount, $data['model']);
        if(!$del_res || !$pos_res){
			Db::rollback();
			return ajaxmsg('委托失败',0);
		}
		Db::commit();
		return ajaxmsg('卖出委托已提交',1);
	}
	/*委托记录*/
	public function trust()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$sub_id    = input('sub_id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$startDate = input('start_date', '');
		$endDate   = input('end_date', '');
		$page      = input('page', 1, ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$submodel  = new StockSubAccount;
		$res = $submodel->getAccountById($sub_id);
		if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
        $trust = new Trust;
        //print_r($startDate);print_r($endDate);exit;
		$data  = $trust->get_trust($sub_id,$startDate,$endDate,$page);
		
		
		if(!$data) return ajaxmsg('没有数据',0);
		return ajaxmsg('操作成功',1,$data);
	}
	/*
	 * 获取可撤单委托列表
	 */
	public function cancel_trust()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$sub_id   = input('sub_id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$submodel = new StockSubAccount;
		$res = $submodel->getAccountById($sub_id);
		if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
		$trust    = new Trust;
		$res      = $trust->get_cancel_trust($sub_id);

		if(!$res) return ajaxmsg('没有数据',0);
		return ajaxmsg('操作成功',1,$res);
	}
	/*
	 * 当天撤销委托
	 */
	public function cancel()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$sub_id   = input('sub_id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$trust_no = input('trust_no', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		
		$res = StockSubAccount::getAccountById($sub_id);
		if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);

		Db::startTrans();
		$yes = false;
		$tempinfo = Db::name('stock_trust')->where(['trust_no' => $trust_no])->lock(true)->find();
		if (!$tempinfo){
			Db::rollback();
			return ajaxmsg('没找到对应委托，撤单失败',0);
		}
		$trust['status'] = '已撤';
		$trust['cancel_order_flag']  = '1';
		$trust['cancel_order_count'] = $tempinfo['trust_count'];
		$trust_res    = Db::name('stock_trust')->where(['trust_no' => $trust_no])->update($trust);
		$affect_money = Db::name('stock_delivery_order')->where(array('trust_no' => $trust_no))->value('liquidation_amount');
		if ($tempinfo['flag2'] == '买入委托'){
			$subm_res = SubAccountMoney::upMoneyLog($sub_id, $affect_money, 8);
			$position = true;
		}
		if ($tempinfo['flag2'] == '卖出委托'){
			$position = Db::name('stock_position')->where(['sub_id' => $sub_id,'gupiao_code' => $tempinfo['gupiao_code'],'buying' => 0])->find();
			$position['canbuy_count'] = $position['canbuy_count'] + $tempinfo['trust_count'];
			$position = Db::name('stock_position')->where(['sub_id' => $sub_id,'gupiao_code' => $tempinfo['gupiao_code']])->update($position);
			$subm_res = SubAccountMoney::upMoneyLog($sub_id, $affect_money, 9);
		}
		$delivery = Db::name('stock_delivery_order')->where(array('trust_no' => $trust_no))->delete();
		if($trust_res && $subm_res && $position && $delivery){
		    Db::commit();
		    return ajaxmsg('撤单成功',1);
		}
		Db::rollback();
		return ajaxmsg('撤单失败',0);
	}
	/*
	 * 成交记录
	 */
	public function deal()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$sub_id    = input('sub_id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$startDate = input('start_date', '');
		$endDate   = input('end_date', '');
		$page      = input('page', 1, ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$submodel  = new StockSubAccount;
		$res       = $submodel->getAccountById($sub_id);
		if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
		$deal_stack = new StockDealStock;
		$data = $deal_stack->get_deal_stock($sub_id,$startDate,$endDate,$page);
		if(!$data) return ajaxmsg('没有数据',0);
		return ajaxmsg('操作成功',1,$data);
	}
	/*
	 * 交割记录
	 */
	public function comp()
	{
		if(!$this->token || $this->userId == '') return ajaxmsg('未登录',500);
		$sub_id    = input('sub_id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$startDate = input('start_date', '');
		$endDate   = input('end_date', '');
		$page      = input('page', 1, ['trim', FILTER_SANITIZE_NUMBER_INT]);
		$submodel  = new StockSubAccount;
		$res       = $submodel->getAccountById($sub_id);
		if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
		$deal_stack = new Delivery;
		$data = $deal_stack->get_delivery_order($sub_id,$startDate,$endDate,$page);
		if(!$data) return ajaxmsg('没有数据',0);
		return ajaxmsg('操作成功',1,$data);
	}
}
