<?php
/**
 * OrderLogic.php UTF-8
 * 订单逻辑
 *
 * @date    : 2018/1/19 22:43
 *
 * @license 这不是一个自由软件,未经授权不许任何使用和传播。
 * @author  : wuyonghong <wyh@huosdk.com>
 * @version : HUOSDK 8.0
 */

namespace huo\logic\order;

use huo\controller\game\GameCache;
use huo\logic\agent\AgentLogic;
use huo\model\common\CommonModel;
use huo\model\order\OrderExtModel;
use huo\model\order\OrderModel;
use huolib\constant\CommonConst;
use huolib\constant\OrderConst;
use huolib\constant\PaywayConst;
use huolib\status\OrderStatus;
use huolib\tool\StrUtils;
use huolib\tool\Time;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;
use think\Log;

class OrderLogic extends CommonModel {
    /**
     * 根据order_id 获取信息
     *
     * @param string $order_id
     *
     * @return array|bool
     */
    public function getInfoByOrderId($order_id) {
        $_map['order_id'] = $order_id;
        try {
            $_order_data = (new OrderModel())->with('payext')->where($_map)->find();
            if (is_object($_order_data)) {
                $_order_data = $_order_data->toArray();
            }

            return $_order_data;
        } catch (DataNotFoundException $_e) {
            Log::write(
                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::DATA_NOT_FOUND_EXCEPTION."&Exception"
                .$_e->getMessage(),
                LOG::ERROR
            );

            return false;
        } catch (ModelNotFoundException $_e) {
            Log::write(
                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::MODEL_NOT_FOUND_EXCEPTION."&Exception"
                .$_e->getMessage(),
                LOG::ERROR
            );

            return false;
        } catch (DbException $_e) {
            Log::write(
                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::DB_EXCEPTION."&Exception"
                .$_e->getMessage(),
                LOG::ERROR
            );

            return false;
        } catch (Exception $_e) {
            Log::write(
                "func=".__FUNCTION__."&class=".__CLASS__."&code=".OrderStatus::INNER_ERROR."&Exception"
                .$_e->getMessage(),
                LOG::ERROR
            );

            return false;
        }
    }

    /**
     * 判断是否首充
     *
     * @param $map
     *
     * @return bool true 表示为首充  false 表示为已充值过
     */
    public function isFirstCharge($map) {
        $_map = $map;
        $_map['status'] = OrderConst::PAY_STATUS_SUC;
        $_cnt = (new OrderModel())->where($_map)->count();
        if (0 < $_cnt) {
            return false;
        }

        return true;
    }

    /**
     * @param array $param
     *
     * @return array
     */
    public function getListWhere($param) {
        $_map = [];
        if (!empty($param['start_time']) && !empty($param['start_time'])) {
            $_map['order_model.create_time'] = ['between',
                                                [strtotime($param['start_time']),
                                                 CommonConst::CONST_DAY_SECONDS + strtotime($param['end_time'])]];
        } else if (!empty($param['start_time'])) {
            $_map['order_model.create_time'] = ['gt', strtotime($param['start_time'])];
        } else if (!empty($param['end_time'])) {
            $_map['order_model.create_time'] = ['lt', CommonConst::CONST_DAY_SECONDS + strtotime($param['end_time'])];
        }
        if (!empty($param['cp_order_id'])) {
            $_map['order_model.cp_order_id'] = $param['cp_order_id'];
        }
        if (!empty($param['username'])) {
            $_map['mem.username'] = ['like', $param['username'].'%'];
        }
        if (!empty($param['mem_id'])) {
            $_map['order_model.mem_id'] = $param['mem_id'];
        }
        if (!empty($param['order_id'])) {
            $_map['order_id'] = $param['order_id'];
        }
        if (empty($param['order_id']) && !empty($param['role_name'])) {
//            $_ids = (new OrderExtModel())->where(['role_name' => ['like', $param['role_name'].'%']])->column(
//                'pay_id'
//            );
            $_map['leftpayext.role_name'] = ['like', $param['role_name'].'%'];
        }
        if (!empty($param['parent_id'])) {
            $_agent_ids = (new AgentLogic())->getAgentIds($param['parent_id'], true);
            $_map['order_model.agent_id'] = ['in', $_agent_ids];
        }
        if (!empty($param['agent_id'])) {
            if (-1 == $param['agent_id']) {
                $param['agent_id'] = 0;
            }
            $_map['order_model.agent_id'] = $param['agent_id'];
        }
        if (!empty($param['app_id'])) {
            $_map['order_model.app_id'] = $param['app_id'];
        }
        if (!empty($param['is_handle'])) {
            $_map['order_model.is_handle'] = $param['is_handle'];
        }
        if (!empty($param['status'])) {
            $_map['order_model.status'] = $param['status'];
        }
        if (!empty($param['cp_status'])) {
            $_map['order_model.status'] = OrderConst::PAY_STATUS_SUC;
            $_map['order_model.cp_status'] = $param['cp_status'];
        }
        if (!empty($param['is_switch'])) {
            $_map['order_model.is_switch'] = $param['is_switch'];
        }
        if (!empty($param['os'])) {
            $_pe_map = ['os' => $param['os']];
            $_ids = (new OrderExtModel())->where($_pe_map)->column('pay_id');
            $_map['order_model.id'] = ['in', $_ids];
        }
        /* 未充值订单不显示 */
        $_map['payway'] = ['neq', ''];
        if (!empty($param['payway'])) {
            $_map['order_model.payway'] = $param['payway'];
        }

        return $_map;
    }

    /**
     * @param        $param
     * @param string $page
     * @param string $order
     *
     * @return array
     */
    public function getOrderList($param, $page = '1,10', $order = '-create_time') {
        $_map = $this->getListWhere($param);
        $_field = [];

        return $this->getList($_field, $_map, $page, $order);
    }

    /**
     * 获取订单列表
     *
     * @param array  $field
     * @param        $where
     * @param string $page
     * @param string $order
     *
     * @return array
     */
    public function getList($field = [], $where, $page = '1,10', $order = '-create_time') {
        $_sum = [
            'amount'      => 0,
            'real_amount' => 0,
            'gm_amount'   => 0,
            'ptb_cnt'     => 0,
        ];
        $_map = $where;
        $_model = new OrderModel();
        $_count = $_model->with('mem,leftpayext')->where($_map)->count();
        if (empty($_count)) {
            return [
                'count' => 0,
                'sum'   => $_sum,
                'list'  => []
            ];
        }
        $_sum_field = [
            'sum(amount)'      => 'sum_amount',
            'sum(real_amount)' => 'sum_real_amount',
            'sum(gm_amount)'   => 'sum_gm_amount',
            'sum(ptb_amount)'  => 'sum_ptb_amount'
        ];
        $_sum_data = $_model->with('mem,leftpayext')
                            ->field($_sum_field)
                            ->where($_map)
                            ->find();
        if (is_object($_sum_data)) {
            $_sum_data = $_sum_data->toArray();
        }
        $_sum['amount'] = StrUtils::formatNumber($_sum_data['sum_amount']);
        $_sum['real_amount'] = StrUtils::formatNumber($_sum_data['sum_real_amount']);
        $_sum['gm_amount'] = StrUtils::formatNumber($_sum_data['sum_gm_amount']);
        $_sum['ptb_amount'] = StrUtils::formatNumber($_sum_data['ptb_amount']);
        /* 实收金额只统计支付成功的金额 */
        $_map_bank = $_map;
        $_map_bank['order_model.status'] = OrderConst::PAY_STATUS_SUC;
        $_sum_field = [
            'sum(real_amount)' => 'sum_real_amount'
        ];
        $_sum_data_bank = $_model->with('mem,leftpayext')
                                 ->field($_sum_field)
                                 ->where($_map_bank)
                                 ->find();
        if (is_object($_sum_data_bank)) {
            $_sum_data_bank = $_sum_data_bank->toArray();
        }
        $_sum['real_amount'] = StrUtils::formatNumber($_sum_data_bank['sum_real_amount']);
        $_field = $field;
        if (empty($field)) {
            $_field = [];
        }
        $_order = $_model->orderFilter($order);
        $_datas = $_model
            ->with('mem,leftpayext,agent,game')
//            ->with('payext')
//            ->with('agent')
//            ->with('game')
            ->where($_map)
            ->field($_field)
            ->order($_order)
            ->page($page)
            ->select();
        if (is_object($_datas)) {
            $_datas = $_datas->toArray();
        }
        if (empty($_datas)) {
            return [
                'count' => $_count,
                'sum'   => $_sum,
                'list'  => []
            ];
        }
        $_list = $_datas;
        foreach ($_datas as $_k => $_v) {
            $_list[$_k]['agent_name'] = !empty($_v['agent']) ? $_v['agent']['user_login'] : '';
            $_list[$_k]['gamename'] = !empty($_v['game']) ? $_v['game']['name'] : '';
            $_list[$_k]['username'] = !empty($_v['mem']) ? $_v['mem']['username'] : '';
            $_list[$_k]['is_switch_msg'] = ($_v['is_switch'] == OrderConst::PAY_SWITCH_YES) ? lang('SWITCH')
                : lang('NOT_SWITCH');
        }

        return [
            'count' => $_count,
            'sum'   => $_sum,
            'list'  => $_list
        ];
    }

    /**
     * 统计总流水 今日流水  昨日流水
     *
     * @param int|array $agent_ids
     *
     * @return array
     *   sum_money        总流水
     *   today_money      今日流水
     *   yesterday_money  昨日流水
     */
    public function getStaticMoney($agent_ids) {
        $_agent_ids = $agent_ids;
        if (is_numeric($agent_ids)) {
            $_agent_ids = [$agent_ids];
        }
        $_map = [];
        if (!empty($agent_ids)) {
            $_map['agent_id'] = ['in', $_agent_ids];
        }
        $_map['status'] = OrderConst::PAY_STATUS_SUC;
        $_order_model = new OrderModel();
        $_rdata['sum_money'] = $_order_model->where($_map)->sum('amount');
        list($today_start, $today_end) = Time::today();
        $_map['create_time'] = ['gt', $today_start];
        $_rdata['today_money'] = $_order_model->where($_map)->sum('amount');
        $_map['create_time'] = ['between', [$today_start - CommonConst::CONST_DAY_SECONDS, $today_start]];
        $_rdata['yesterday_money'] = $_order_model->where($_map)->sum('amount');

        return $_rdata;
    }

    public function getMemOrderList($mem_id, $param = [], $page, $order = '-create_time') {
        $_rdata = ['count' => 0, 'list' => []];
        $param['mem_id'] = $mem_id;
        $_map = $this->getListWhere($param);
        $_field = [
            'order_id'     => 'order_id',
            'app_id'       => 'app_id',
            'amount'       => 'amount',
            'real_amount'  => 'real_amount',
            'product_id'   => 'product_id',
            'product_name' => 'product_name',
            'payway'       => 'payway',
            'status'       => 'status',
            'pay_time'     => 'pay_time',
            'create_time'  => 'create_time',
        ];
        $_model = new OrderModel();
        $_order = $this->orderFilter($order);
        $_count = $_model->alias('order_model')->with('game')->where($_map)->count();
        if (empty($_count)) {
            return $_rdata;
        }
        $_datas = $_model->alias('order_model')
                         ->with('game')
                         ->field($_field)
                         ->where($_map)
                         ->order($_order)
                         ->page($page)
                         ->select();
        $_list = [];
        if (!$_datas->isEmpty()) {
            $_list = $_datas->toArray();
            foreach ($_list as $key => $item) {
                $item['payway'] = PaywayConst::getMsg($item['payway']);
                $item['gamename'] = isset($item['game']) ? $item['game']['name'] : '';
                $item['pay_time'] = !empty($item['pay_time']) ? $item['pay_time'] : $item['create_time'];
                unset($item['game']);
                $_list[$key] = $item;
            }
        }

        return [
            'count' => $_count,
            'list'  => $_list
        ];
    }

    /**
     * 获取订单扩展列表--适用由角色查找订单
     *
     * @param        $server_id
     * @param        $role_id
     * @param array  $param
     * @param        $page
     * @param string $order
     *
     * @return array
     */
    public function getOrderExtList($server_id, $role_id, $param = [], $page, $order = '-create_time') {
        $_rdata = ['count' => 0, 'list' => []];
        $_map = [];
        $_map['server_id'] = $server_id;
        $_map['role_id'] = $role_id;
        if (!empty($param['start_time']) && !empty($param['start_time'])) {
            $_map['create_time'] = ['between',
                                    [strtotime($param['start_time']),
                                     CommonConst::CONST_DAY_SECONDS + strtotime($param['end_time'])]];
        } else if (!empty($param['start_time'])) {
            $_map['create_time'] = ['gt', strtotime($param['start_time'])];
        } else if (!empty($param['end_time'])) {
            $_map['create_time'] = ['lt', CommonConst::CONST_DAY_SECONDS + strtotime($param['end_time'])];
        }
        if (!empty($param['cp_order_id'])) {
            $_map['cp_order_id'] = $param['cp_order_id'];
        }
        if (!empty($param['order_id'])) {
            $_map['order_id'] = $param['order_id'];
        }
        if (!empty($param['app_id'])) {
            $_map['app_id'] = $param['app_id'];
        }
        if (!empty($param['status'])) {
            $_map['status'] = $param['status'];
        }
        if (!empty($param['cp_status'])) {
            $_map['status'] = OrderConst::PAY_STATUS_SUC;
            $_map['cp_status'] = $param['cp_status'];
        }
        /* 未充值订单不显示 */
        $_map['payway'] = ['neq', ''];
        if (!empty($param['payway'])) {
            $_map['payway'] = $param['payway'];
        }
        $_field = [
            'pay.order_id'     => 'order_id',
            'pay.cp_order_id'  => 'cp_order_id',
            'pay.app_id'       => 'app_id',
            'pay.amount'       => 'amount',
            'pay.real_amount'  => 'real_amount',
            'pay.product_id'   => 'product_id',
            'pay.product_name' => 'product_name',
            'pay.payway'       => 'payway',
            'pay.status'       => 'status',
            'pay.cp_status'    => 'cp_status',
            'pay.pay_time'     => 'pay_time',
            'pay.create_time'  => 'create_time',
            'server_id'        => 'server_id',
            'server_name'      => 'server_name',
            'role_id'          => 'role_id',
            'role_name'        => 'role_name',
        ];
        $_model = new OrderExtModel();
        $_order = $this->orderFilter($order);
        $_count = $_model->with('pay')->where($_map)->count();
        if (empty($_count)) {
            return $_rdata;
        }
        $_datas = $_model->with('pay')
                         ->field($_field)
                         ->where($_map)
                         ->order($_order)
                         ->page($page)
                         ->select();
        $_list = [];
        if (!$_datas->isEmpty()) {
            $_fame_cache = GameCache::ins();
            $_list = $_datas->toArray();
            foreach ($_list as $key => $item) {
                $_game = $_fame_cache->getInfoByAppId($item['app_id']);
                $item['payway'] = PaywayConst::getMsg($item['payway']);
                $item['gamename'] = $_game['name'];
                $item['icon'] = $_game['icon'];
                $item['pay_time'] = !empty($item['pay_time']) ? $item['pay_time'] : $item['create_time'];
                unset($item['game']);
                $_list[$key] = $item;
            }
        }

        return [
            'count' => $_count,
            'list'  => $_list
        ];
    }
}