<?php
/**
 * Created by PhpStorm.
 * User: stanley-king
 * Date: 2017/11/4
 * Time: 下午10:17
 */

namespace async;

use push_helper;
use order_helper;
use member_info;
use Exception;
use search;
use bonus;
use bonus_helper;
use sms_helper;
use Sms;
use fcode;
use Log;

class simple_order
{
    private $info;
    private $rgoods;
    public function __construct($order_info) {
        $this->info = $order_info;
        $this->rgoods = $this->find_recommend();
    }
    private function find_recommend()
    {
        $result = null;
        foreach ($this->info['order_goods'] as $good)
        {
            if(empty($result)) {
                $result = $good;
            }
            else
            {
                if($result['goods_price'] < $good['goods_price']) {
                    $result = $good;
                }

            }
        }

        return $result;
    }
    public function user() {
        return $this->info['order_info']['buyer_id'];
    }
    public function discount() {
        return $this->info['order_info']['pd_amount'];
    }
    public function recommend_goods() {
        return $this->rgoods;
    }
    public function total_cash() {
        return $this->info['order_info']['pay_cash'];
    }
    public function bonus_rates() {
        return $this->info['order_info']['bonus_rates'];
    }
    public function pd_amount() {
        return $this->info['order_info']['pd_amount'];
    }
    public function order_sn() {
        return $this->info['order_info']['order_sn'];
    }
}

class order extends IAsync
{
    private $simple_order;
    private $user_info;
    private $paysn;

    public function __construct($paysn)
    {
        $this->paysn = $paysn;
        $order = $this->order(['pay_sn' => $paysn]);
        if(empty($order)) throw new Exception("错误的订单");

        $this->simple_order = new simple_order($order);
        $user = $this->simple_order->user();
        $this->user_info = new member_info($user);
    }

    public function run() {
    }

    //支付成功
    public function onPaied()
    {
        push_helper::user_order_paied($this->user_info->member_id(),$this->paysn);
        $inviters = search\relation_client::instance()->fetch_inviters(['user_id' => $this->user_info->member_id()]);
        $this->notify_paided_goods($inviters);
    }

    private function notify_paided_goods($inviters)
    {
        if(empty($inviters)) return false;

        $goods = $this->simple_order->recommend_goods();
        $level = 0;
        $ex_invitee = $this->user_info->member_id();
        foreach ($inviters as $inviter)
        {
            $this->nofity_paied_inviter($inviter,$level,$goods);
            $invitees = search\relation_client::instance()->fetch_invitees(['user_id' => $inviter]);
            $invitees = $this->ex_user($invitees,$ex_invitee);
            $this->nofity_paied_invitees($inviter,$invitees,$level,$goods);
            $ex_invitee = $inviter;
            $level += 1;
        }
        return true;
    }

    private function nofity_paied_inviter($inviter,$level,$goods)
    {
        push_helper::inviter_order_paied($inviter,$this->user_info->member_id(),$level + 1,$goods);
    }
    private function nofity_paied_invitees($inviter,$invitees,$level,$goods)
    {
        $i = 0;
        foreach ($invitees as $invitee)
        {
            if($i < self::max_level_pushs) {
                push_helper::invitee_order_paied($invitee, $this->user_info->member_id(), $goods);
            }
            $i++;
        }
    }

    //发货
    public function onSended($logistics_no,$logistics_company)
    {
        $mobile = $this->user_info->mobile();
        sms_helper::send_nostore_message($mobile,Sms::order_sended,['company'=> $logistics_company,'logistics'=>$logistics_no,'time'=>'5']);
    }

    //取消订单
    public function onCancel()
    {
        $pd_amount = $this->simple_order->pd_amount();
        $bonus_rates = $this->simple_order->bonus_rates();
        if(empty($bonus_rates)) {
            $bonus_rates = [30 => $pd_amount];
        }
        else
        {
            $tmp = [];
            foreach ($bonus_rates as $val) {
                $rate = $val['rate'];
                $amount = $val['total'];
                $tmp[$rate] = $amount;
            }
            $bonus_rates = $tmp;
        }

        $params = bonus\parameters::order_cancel($bonus_rates);
        foreach ($params as $param)
        {
            $rate_money = $param['rate_money'];
            $ret = bonus_helper::make_bonus($param,$rate_money);
            $rate = $rate_money[0]['rate'];
            $amount = $rate_money[0]['amount'];
            $user = $this->user_info->member_id();
            $order_sn = $this->simple_order->order_sn();

            if($ret != false) {
                $type_sn = $ret['type_sn'];
                bonus_helper::send($ret['type_sn'],[$user]);
                push_helper::order_cancel_bonus($user,$amount,$rate,$order_sn,$type_sn);
            } else {
                Log::record("给用户{$user}:order_sn={$order_sn},退款rate={$rate} amount={$amount}失败.");
            }
        }

        Model()->table('order')->where(['order_sn' => $this->simple_order->order_sn()])->update(['pd_amount' => 0,'bonus_rate' => '']);
    }

    //确认收货
    public function onComplete()
    {
        $num = fcode\operator::unlock($this->paysn);
        if($num > 0) {
            push_helper::fcode_unlock($this->user_info->member_id(),$num);
        }
        sms_helper::send_nostore_message($this->user_info->mobile(),Sms::order_received,['time'=>'5']);

        $this->send_complete_bonus();
        $inviters = search\relation_client::instance()->fetch_inviters(['user_id' => $this->user_info->member_id()]);
        $this->notify_complete_inviter($inviters);
    }

    private function notify_complete_inviter($inviters)
    {
        if(empty($inviters)) return false;

        $level = 0;
        $ex_invitee = $this->user_info->member_id();
        foreach ($inviters as $inviter)
        {
            $this->reward_inviter($inviter,$level);
            $invitees = search\relation_client::instance()->fetch_invitees(['user_id' => $inviter]);

            $invitees = $this->ex_user($invitees,$ex_invitee);
            $this->reward_invitees($inviter,$invitees,$level);
            $ex_invitee = $inviter;
            $level += 1;
        }
        return true;
    }

    private function reward_inviter($inviter, $level)
    {
        $cash = $this->simple_order->total_cash();
        $params = bonus\parameters::order_complete_inviter($cash,$this->user_info->nickname(),$level);
        foreach ($params as $param)
        {
            $type = bonus_helper::create_type_input($param);
            $money = $type->getTotal_amount();
            $rate  = $type->bonus_rate();
            $ret = bonus_helper::make_bonus($param,$param['rate_money']);

            if($ret != false) {
                $type_sn = $ret['type_sn'];
                bonus_helper::send($type_sn,[$inviter]);
                push_helper::inviter_order_complete_bonus($inviter,$this->user_info->member_id(),$level + 1,$money,$rate,$type_sn);
                $this->add_reward($inviter,$money);
            } else {
                return false;
            }
        }
        return true;
    }

    private function reward_invitees($inviter, $invitees, $level)
    {
        if(empty($invitees)) return false;

        $cash = $this->simple_order->total_cash();
        if($cash < 50) return false;

        $num = count($invitees);
        $params = bonus\parameters::order_complete_invitee($this->user_info->nickname(),$level,$num);
        foreach ($params as $param)
        {
            $type = bonus_helper::create_type_input($param);
            $money = $type->getTotal_amount();
            $rate  = $type->bonus_rate();
            $ret = bonus_helper::make_bonus($param,$param['rate_money']);

            if($ret != false)
            {
                $type_sn = $ret['type_sn'];
                bonus_helper::send($type_sn,$invitees);
                $i = 0;
                foreach ($invitees as $invitee)
                {
                    $amount = $money / $num;
                    $this->add_reward($invitee,$amount);

                    if($i < self::max_level_pushs) {
                        push_helper::invitee_order_complete_bonus($invitee,$this->user_info,$amount,$rate,$type_sn);
                    }
                    $i++;
                }
            }
            else {
                return false;
            }
        }
        return true;
    }

    private function send_complete_bonus()
    {
        $total_amount = $this->simple_order->total_cash();

        $fixed_params = bonus\parameters::order_complete_fixed($total_amount);
        foreach ($fixed_params as $param)
        {
            $ret = bonus_helper::make_bonus($param,$param['rate_money']);
            if($ret != false) {
                $type_sn = $ret['type_sn'];
                $bonus = bonus_helper::send($type_sn, [$this->user_info->member_id()]);
                $bonus_value = $bonus[0]['bonus_value'];
                $bonus_rate  = $bonus[0]['bonus_rate'];
                push_helper::user_order_complete_fixed($this->user_info->member_id(),$bonus_value,$bonus_rate,$type_sn);
            }
        }

        $random_params = bonus\parameters::order_complete_random($total_amount);
        foreach ($random_params as $param)
        {
            $ret = bonus_helper::make_bonus($param,$param['rate_money']);
            if($ret != false) {
                $type_sn = $ret['type_sn'];
                bonus_helper::send($type_sn, [$this->user_info->member_id()]);
                push_helper::user_order_complete_random($this->user_info->member_id(),$param['rate_money']['num'],$type_sn);
            }
        }
    }

    //评论
    public function onEvaluate()
    {
        $this->send_evaluate_bonus();
        $inviters = search\relation_client::instance()->fetch_inviters(['user_id' => $this->user_info->member_id()]);
        $this->notify_inviter_evaluate($inviters);
    }

    private function send_evaluate_bonus()
    {
        $fixed_params = bonus\parameters::order_evaluate_fixed();
        foreach ($fixed_params as $param)
        {
            $ret = bonus_helper::make_bonus($param,$param['rate_money']);
            if($ret != false) {
                $type_sn = $ret['type_sn'];
                $bonus = bonus_helper::send($type_sn, [$this->user_info->member_id()]);
                $bonus_value = $bonus[0]['bonus_value'];
                $bonus_rate = $bonus[0]['bonus_rate'];
                push_helper::order_evaluate_bonus($this->user_info->member_id(),$bonus_value,$bonus_rate,$type_sn);
            }
        }
    }

    private function notify_inviter_evaluate($inviters)
    {
        if(empty($inviters)) return false;

        $goods = $this->simple_order->recommend_goods();
        $level = 0;
        $ex_invitee = $this->user_info->member_id();
        foreach ($inviters as $inviter)
        {
            $this->nofity_evaluate_inviter($inviter,$level,$goods);
            $invitees = search\relation_client::instance()->fetch_invitees(['user_id' => $inviter]);
            $invitees = $this->ex_user($invitees,$ex_invitee);
            $this->nofity_evaluate_invitees($inviter,$invitees,$level,$goods);
            $ex_invitee = $inviter;
            $level += 1;
        }
        return true;
    }
    private function nofity_evaluate_inviter($inviter,$level,$goods)
    {
        push_helper::inviter_order_evaluated($inviter,$this->user_info->member_id(),$level + 1,$goods);
    }
    private function nofity_evaluate_invitees($inviter,$invitees,$level,$goods)
    {
        $i = 0;
        foreach ($invitees as $invitee)
        {
            if($i < self::max_level_pushs) {
                push_helper::invitee_order_evaluated($invitee,$this->user_info->member_id(),$goods);
            }
            $i++;
        }
    }

    private function order($condition)
    {
        $model_order = Model('order');
        $order_list = $model_order->getNormalOrderList($condition,0, '*', 'order_id desc', '', ['order_common','order_address', 'order_goods']);
        $order_helper = new order_helper($order_list);
        $orders = $order_helper->format();
        if(!empty($orders)) {
            return $orders[0];
        } else {
            return false;
        }
    }
}