<?php


namespace app\market\home;


use app\market\model\Deal_stock;
use app\market\model\Delivery;
use app\market\model\Position;
use app\market\model\StockSubAccount;
use app\market\model\SubAccountMoney;
use app\market\model\Trust;
use think\Db;

class Trade extends Common
{
    protected function _initialize(){
        parent::_initialize();
        $token = $this->request->param("token");
        $mid = isLogin($token);
    }

    public function account_info()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $subId = $this->request->param("id");
        if(!$subId) return json(['status' => 0, 'message' => '缺少参数或参数获取错误']);
        $subModel = new SubAccountMoney();
        $res      = $subModel->get_account_money_inf($subId);
        if(!$res) return json(['status' => 0, 'message' => '操作失败']);
        $res['available_amount'] >= 0 ? $res['available_amount'] : 0;
        $res = $subModel->ftoy($res);
        $pos = Position::where(['sub_id'=>$subId, 'buying'=>0])->order('id desc')->select();
        $res['return_money'] = 0;
        $res['market_value'] = 0;
        foreach ($pos as $k => $v ) {
            $data = z_market($v['gupiao_code']);
            if($data['current_price'] == '') continue;
            $res['return_money'] += ($data['current_price'] - $v['buy_average_price']) * $v['stock_count'];
            $res['market_value'] += $data['current_price'] * $v['stock_count'];
        }
        // 提盈额度计算
        $all    = $res['market_value'] + $res['avail'];
        $profit = bcsub(strval($all),bcadd(strval($res['borrow_money']),strval($res['deposit_money'])),2);
        if($profit > 0){
            $res['available_amount'] = $profit < $res['available_amount'] ? $profit : $res['available_amount'];
        }else{
            $res['available_amount'] = 0;
        }
        //$res['available_amount'] = $res['available_amount'] > $res['avail'] ? $res['avail'] : $res['available_amount'];
        $res['available_amount'] = bcadd(strval($res['available_amount']),'0',2);
        // 去掉卖出委托的市值
        $weituo = 0;
        $weituo = Db::name('stock_trust')->where(['sub_id'=>$res['stock_subaccount_id'],'flag2'=>'卖出委托','status'=>'已委托'])->sum('amount');
        $res['return_money'] = bcadd(strval($res['return_money']),'0', 2); //加法，在原值上加0为了保留小数点后两位
        $res['market_value'] = bcsub(strval($res['market_value']),strval($weituo), 2);//减法
        $res['total_money']  = bcadd(strval($res['market_value']),bcadd(strval($res['avail']),strval($res['freeze_amount']),2), 2);//加法

        return json(['data'=>$res,'status' => 1, 'message' => '操作成功']);
    }

    /*
     * 持仓查询
     */
    public function position()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '未登录']);
        $subid = $this->request->param("id");
        if(!$subid) return json(['status' => 0, 'message' => '参数不正确']);
        $submodel = new StockSubAccount();
        $res = $submodel->get_account_by_id($subid);
        if (!$res) return json(['status' => 0, 'message' => '不存在的子账号']);
        if (empty($res['account_id'])) return json(['status' => 0, 'message' => '证券公司不存在']);
        $data = Position::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::get_delivery_order($subid,$item["gupiao_code"]);
            $data[$k]['canbuy_count']      = $item['canbuy_count'];
            //查询股票最新行情
            $Qdata = z_market($item["gupiao_code"],$item['market']);
            //查询子账户
            $data[$k]['sub_account']       = $res['sub_account'];
            //提取当前价格
            $data[$k]['now_price']         = $Qdata['current_price'];
            //市值 = 当前价格*数量
            $data[$k]['market_value']      = round((int)$Qdata['current_price']*(int)$item['stock_count'],2);
            //参考成本价
            $data[$k]['ck_price']          = Position::calculate($subid,$item["gupiao_code"],'price');
            //买入均价
            $data[$k]['buy_average_price'] = Position::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((int)$Qdata["current_price"]-(int)$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()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        if (!yan_time()) return json(['status' => 0, 'message' => '非交易时间']);
        if (!config('site_trade_buy')) return ajaxmsg('系统设置为禁买状态',0);
        $data  = [
            "sub_id"  => input('id','', ['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->executeData($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：卖出], 盈亏金额, 实盘相关, 股票代码)*/
        $subaccount=new SubAccountMoney();
        $ret  = $subaccount->up_moneylog($data['sub_id'], $effectMoney, 3, 0, 0, $data['code']);
        if (!$ret){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        $StockSubAccount = new StockSubAccount();
        $subres = $StockSubAccount->get_account_by_id($data['sub_id']);
        $broker = $StockSubAccount->get_broker($subres['account_id']);
        if (!$subres) return ajaxmsg('子账号或证券公司不存在!',0);
        $Trust_no  = mt_rand(101010, 999999) . substr(strval(time()), 1);
        //添加到委托表
        $Trust_res = $Trust->add_m_trust($data, $data['count'],$data['price'],$data['sub_id'],$broker['lid'],$broker['user'],$broker['stockjobber'],$Trust_no,$broker, $data['model']);
        if(!$Trust_res){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        //持仓数量查询
        $position = Db::name('stock_position')->where(['sub_id' => $data['sub_id'],'gupiao_code' => $data['code'],'buying' => 0])->find();
        $amount   = empty($position) ? $data['count'] : $position['canbuy_count'] + $data['count'];

        //提交交易费用信息
        $Delivery = new Delivery;
        $avail    = ($moneyinfo['avail']) - $effectMoney;
        $del_res  = $Delivery->add_m_delivery_order($data, $data['count'],$data['price'],$data['sub_id'],$broker['lid'],$broker['user'],$broker['stockjobber'],$commission,$transfer,$Trust_no,$avail,$amount, $data['model']);
//        $pos_res = Position::addPosition($data['code'], $data['market'],$data['count'],$data['sub_id'],$broker['lid'],$broker['user'],$broker['stockjobber'],$data['price']);
        //print_r("佣金: ".$commission." 过户费: ".$transfer." 总计：".$effectMoney);Db::rollback();exit;
        //print_r($del_res);Db::rollback();exit;
        if(!$del_res){
            Db::rollback();
            return ajaxmsg('委托失败',0);
        }else{
            Db::commit();
            return ajaxmsg('买入委托已提交',1);
        }
    }

    public function sell()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        if (!yan_time()) return json(['status' => 0, 'message' => '非交易时间']);
        if (config('site_trade_sell') == 0)
            return ajaxmsg('系统设置为不允许卖出股票',0);
        if (time() <= strtotime(date("Y-m-d 09:30:15"))) {
            return ajaxmsg('平台设置9点30分15秒后可卖出',0);
        }
        $data  = [
            "sub_id"  => input('id','', ['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->executeData($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;
        $subaccount=new SubAccountMoney();
        $ret = $subaccount->up_moneylog($data['sub_id'], $effectMoney, 4);
        if(!$ret){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        $Trust_no  = mt_rand(101010, 999999) . substr(strval(time()), 1);

        $StockSubAccount = new StockSubAccount();
        $subres = $StockSubAccount->get_account_by_id($data['sub_id']);
        $broker = $StockSubAccount->get_broker($subres['account_id']);
        if (!$subres) return ajaxmsg('子账号或证券公司不存在!',0);
        //添加到委托表
        $Trust_res = $Trust->sell_m_trust($data, $data['count'],$data['price'],$data['sub_id'],$broker['lid'],$broker['user'],$broker['stockjobber'],$Trust_no,$broker, $data['model']);
        if(!$Trust_res){
            Db::rollback();
            return ajaxmsg('委托失败!',0);
        }
        //持仓数量查询
        $position = Db::name('stock_position')->where(['sub_id' => $data['sub_id'],'gupiao_code' => $data['code'],'buying' => 0])->find();
        $amount   = $position['canbuy_count'] - $data['count'];
        //持仓减少
        $pos_res  = Db::name('stock_position')->where(['sub_id' => $data['sub_id'],'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, $data['count'],$data['price'],$data['sub_id'],$broker['lid'],$broker['user'],$broker['stockjobber'],$commission,$transfer,$Trust_no,$avail,$amount, $data['model']);
        if(!$del_res || !$pos_res){
            Db::rollback();
            return ajaxmsg('委托失败',0);
        }
        Db::commit();
        return ajaxmsg('卖出委托已提交',1);
    }
    /*委托记录*/
    public function trust()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $sub_id    = input('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->get_account_by_id($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);


        if(!$data) return ajaxmsg('没有数据',0);
        return ajaxmsg('操作成功',1,$data);
    }
    /*
     * 获取可撤单委托列表
     */
    public function cancel_trust()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $sub_id   = input('id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
        $submodel = new StockSubAccount;
        $res = $submodel->get_account_by_id($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()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $sub_id   = input('id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
        $trust_no = input('trust_no', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
        $submodel = new StockSubAccount;
        $res = $submodel->get_account_by_id($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');
        $subaccount=new SubAccountMoney();
        if ($tempinfo['flag2'] == '买入委托'){
            $subm_res = $subaccount->up_moneylog($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 = $subaccount->up_moneylog($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_stock()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $sub_id    = input('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->get_account_by_id($sub_id);
        if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
        $deal_stack = new Deal_stock();
        $data = $deal_stack->get_deal_stock($sub_id,$startDate,$endDate);
        if(!$data) return ajaxmsg('没有数据',0);
        return ajaxmsg('操作成功',1,$data);
    }
    /*
     * 交割记录
     */
    public function delivery()
    {
        $token = $this->request->param("token");
        $mid = isLogin($token);
        if(!$mid) return json(['status' => 0, 'message' => '登陆后才能进行查看']);
        $sub_id    = input('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->get_account_by_id($sub_id);
        if (!$res['account_id']) return ajaxmsg('不存在的子账号',0);
        $deal_stack = new Delivery;
        $data = $deal_stack->get_delivery_order($sub_id,$startDate,$endDate);
        if(!$data) return ajaxmsg('没有数据',0);
        return ajaxmsg('操作成功',1,$data);
    }
}