<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use App\Model\OrderModel;
use App\Model\PayLogModel;
use App\Model\ErpPayLogModel;
use App\Model\RemovalModel;
use App\Model\UserMainModel;
use App\Model\UserAmountModel;
use App\Model\RedisModel;
use App\Model\OrderRefundModel;
use App\Model\OrderReturnModel;
use MonitorDing;

class CronController extends Controller
{
    // 统计 2019-8-5 到 2019-10-31 期间的用户总额  定时任务下午6点 (0 18 * * * /usr/bin/curl http://order.ichunt.net/act/useramoumt)
    public function userAmount()
    {
        $time = Config('params.lx_activity_time');

        $start_time = strtotime($time['start_time']);
        $end_time   = strtotime($time['end_time']);

        $PayLogModel      = new PayLogModel();
        $ErpPayLogModel   = new ErpPayLogModel();
        $RemovalModel     = new RemovalModel();
        $UserMainModel    = new UserMainModel();
        $UserAmountModel  = new UserAmountModel();
        $RedisModel       = new RedisModel();
        $OrderRefundModel = new OrderRefundModel();
        $OrderReturnModel = new OrderReturnModel();

        // 查询联营、自营线上支付记录
        $pay_log_list   = $PayLogModel->getPayLog($start_time, $end_time);
        $pay_log = $this->filterJointAccounts($pay_log_list); // 过滤掉联营账期 (账期金额根据erp_pay_log表统计)
        $pay_log_amount = $this->countByCurrency($pay_log); // 统计金额

        // 联营线下支付记录
        $joint_offline_list   = $ErpPayLogModel->getErpPayLog($start_time, $end_time);
        $joint_offline        = $this->filterData($joint_offline_list); // 过滤数据
        $joint_offline_amount = $this->countByCurrency($joint_offline, 'receipt_amount'); // 统计金额

        // 自营账期支付记录
        $self_accounts_list   = $RemovalModel->getSelfAccounts($start_time, $end_time);
        $self_accounts_amount = $this->countByCurrency($self_accounts_list, 'checkout_paid_amount'); // 统计金额

        $resp = [];

        // 合并用户 
        $resp = $this->mergeUser($pay_log_amount, $joint_offline_amount);     
        $resp = $this->mergeUser($resp, $self_accounts_amount);

        // 保存用户金额数据
        if (!empty($resp)) {
            $cur_rate = $this->getRate();

            foreach ($resp as $k=>$v) {
                $data = [];

                $user = $UserMainModel->getUserAccount($k); // 获取用户账号

                if ($user) {
                    $data['account'] = $user['mobile'] ? $user['mobile'] : $user['email'];
                }

                $data['rmb_amount'] = isset($v['rmb']) ? $v['rmb'] : 0;
                $data['usd_amount'] = isset($v['usd']) ? $v['usd'] : 0;

                $joint_return_amount = $OrderRefundModel->getJointReturnAmount($k, $start_time, $end_time); // 联营用户退款金额

                if ($joint_return_amount) {
                    foreach ($joint_return_amount as $joint) {
                        if ($joint['currency'] == 1) {
                            $data['rmb_amount'] = $data['rmb_amount'] - ($joint['pay_amount'] - $joint['price_fall']);
                        } else {
                            $data['usd_amount'] = $data['usd_amount'] - ($joint['pay_amount'] - $joint['price_fall']);
                        }
                    }
                }

                $self_return_amount = $OrderReturnModel->getSelfReturnAmount($k, $start_time, $end_time); // 自营用户退款金额

                if ($self_return_amount) {
                    foreach ($self_return_amount as $self) {
                        if ($self['currency'] == 1) {
                            $data['rmb_amount'] = $data['rmb_amount'] - $self['return_amount'];
                        } else {
                            $data['usd_amount'] = $data['usd_amount'] - $self['return_amount'];
                        }
                    }
                }              
                
                $data['cur_rate'] = $cur_rate;
                $data['amount']   = $data['rmb_amount'] + $data['usd_amount'] * $data['cur_rate'];

                $res = $UserAmountModel->updateOrCreate(['user_id' => $k], $data);

                if ($res === false) {
                    MonitorDing::sendText('活动用户汇总表---新增或更新失败,用户ID:'.$k);
                    echo '新增或更新失败,用户ID:'.$k; die;
                }
            }
        }

        // 获取排名前十的用户,存入缓存
        $rank = $UserAmountModel->getUserAmount(); 
        $RedisModel->set('api_lx_activity_user_rank', json_encode($rank));

        MonitorDing::sendText(date('Y-m-d').'活动用户排行榜:'.json_encode($rank));
        return $RedisModel->get('api_lx_activity_user_rank');
    }

    // 过滤掉联营账期 (账期从ERP支付记录中获取)
    public function filterJointAccounts($data)
    {
        if (!$data) return false;

        $OrderModel = new OrderModel();

        foreach ($data as $k=>$v) {
            $map = [];
            $map['order_id']         = $v['order_id'];
            $map['order_goods_type'] = 1;
            $map['order_pay_type']   = 3;

            $order = $OrderModel->where($map)->select('order_id')->first();

            if ($order) { 
                unset($data[$k]);
                continue;
            }
        }

        return $data;
    }

    // 过滤联营线下支付数据
    public function filterData($data)
    {
        if (!$data) return false;

        $OrderModel  = new OrderModel();
        $PayLogModel = new PayLogModel();

        foreach ($data as $k=>$v) {
            $order = $OrderModel->where('order_id',  $v['order_id'])->where('order_goods_type', 1)->where('order_pay_type', '<>', 3)->first();

            if (!$order) 
                continue;

            $pay_log = $PayLogModel->where('order_id', $v['order_id'])->select('pay_log_id')->first();

            // 若非账期且pay_log表里已存在订单支付记录,则说明该订单已收款完成,需要清除
            if ($pay_log) { 
                unset($data[$k]);
                continue;
            }
        }

        return $data;
    }

    // 根据币种统计用户金额
    public function countByCurrency($data, $field='pay_amount')
    {
        if (!$data) return false;

        $amount = [];

        // 获取用户对应的金额
        foreach ($data as $k=>$v) {
            if ($v['currency'] == 1) { // RMB
                $amount[$v['user_id']]['rmb'][$k] = $v[$field];
            } else { // USD
                $amount[$v['user_id']]['usd'][$k] = $v[$field];
            }
        }

        if (!empty($amount)) {
            // 统计用户金额
            foreach ($amount as &$val)
            {
                if (isset($val['rmb'])) {
                    $val['rmb'] = array_sum($val['rmb']);
                }

                if (isset($val['usd'])) {
                    $val['usd'] = array_sum($val['usd']);
                }
            }
        }

        return $amount;
    }

    // 合并用户
    public function mergeUser($amount_1, $amount_2)
    {
        if (empty($amount_1)) return $amount_2;
        if (empty($amount_2)) return $amount_1;

        $keys = array_keys($amount_2); // 获取keys

        foreach ($amount_1 as $k1=>&$v1) {
            if (in_array($k1, $keys)) {
                if (isset($v1['rmb']) && isset($amount_2[$k1]['rmb'])) $v1['rmb'] = $v1['rmb'] + $amount_2[$k1]['rmb'];
                if (isset($v1['usd']) && isset($amount_2[$k1]['usd'])) $v1['usd'] = $v1['usd'] + $amount_2[$k1]['usd'];

                unset($amount_2[$k1]); // 删除amount_2中已合并金额的用户
            }
        }

        if (!empty($amount_2)) {
            foreach ($amount_2 as $k2=>$v2) {
                $amount_1[$k2] = $v2;
            }
        }

        return $amount_1;
    }

    // 获取汇率
    public function getRate()
    {
        $url = Config('website.api_domain').'order/getrate';

        $check['k1']  = time();
        $check['k2']  = md5(md5($check['k1']).'fh6y5t4rr351d2c3bryi');

        $temp = json_decode(curlApi($url, $check, "POST"), true);

        return isset($temp['data']) && $temp['data'] ? $temp['data'] : 6.9;
    }

    // 清除用户表数据和缓存数据
    public function clearData()
    {
        $UserAmountModel = new UserAmountModel();
        $RedisModel      = new RedisModel();

        // $UserAmountModel->truncate(); // 清空数据
        $RedisModel->set('api_lx_activity_user_rank', null);
    }

    /**
     * 推送新用户活动短信
     * 
     * 条件:前15天注册,未下单的用户或下单未支付一笔订单的用户
     *
     * 推送时间:每天上午10点  (0 10 * * * /usr/bin/curl http://order.ichunt.net/act/sendactmsg)
     */
    public function sendActMsg()
    {
        $start_time = strtotime(date('Y-m-d', strtotime('-15 day'))); // 前15天0点
        $last_time  = strtotime(date('Y-m-d')) - 1; // 前一天23:59:59
       
        $UserMainModel = new UserMainModel;
        $OrderModel    = new OrderModel;

        // 获取前15天注册用户
        $user = $UserMainModel->where('is_type', 0)
                ->where('is_test', 0)
                ->whereBetween('create_time', [$start_time, $last_time])
                ->select('user_id', 'is_new', 'create_time')
                ->get()
                ->toArray();

        if (empty($user)) return '未获取到新用户'; 

        $user_send_msg = []; // 需要发送短信的用户ID集合
        $crm_params = []; // 推送到crm用户集合

        foreach ($user as $k=>$v) {
            if ($v['is_new'] == 0) { // 未下单用户
                $user_send_msg[$k]['user_id']     = $v['user_id'];
                $user_send_msg[$k]['create_time'] = $v['create_time'];

                $crm_params[$k]['user_id']         = $v['user_id'];
                $crm_params[$k]['is_create_order'] = 0;
                continue; 
            }

            // 已下单用户,判断订单是否有支付
            $count = $OrderModel->where('user_id', $v['user_id'])->where('status', '>', 2)->count();

            if (!$count) { // 不存在,则表示没有已付款的订单
                $user_send_msg[$k]['user_id']     = $v['user_id'];
                $user_send_msg[$k]['create_time'] = $v['create_time'];
            }

            $crm_params[$k]['user_id']         = $v['user_id'];
            $crm_params[$k]['is_create_order'] = 1; // 标记已下单
        }

        if (empty($user_send_msg)) return '没有需要推送活动短信的用户';

        //调用消息接口
        $url = Config('website.api_domain').'msg/sendmessagebyauto';
        

        $data['k1']  = time();
        $data['k2']  = md5(md5($data['k1']).'fh6y5t4rr351d2c3bryi');

        foreach ($user_send_msg as $msg) {
            // 判断用户注册时间
            $time    = time() - $msg['create_time'];
            $reg_day = intval(ceil($time / 86400));

            switch ($reg_day) {
                case 1: $keyword = 'new_user_activity_msg_1'; break;
                case 3: $keyword = 'new_user_activity_msg_3'; break;
                case 7: $keyword = 'new_user_activity_msg_7'; break;
                case 15: $keyword = 'new_user_activity_msg_15'; break;
                default : $keyword = ''; break;
            }

            if (!$keyword) continue;

            $userData = [
                "keyword"  => $keyword, 
                "pf"       => 1, 
                "k1"       => $data['k1'], 
                "k2"       => $data['k2'],
                'touser'   => json_encode($msg['user_id']),
            ];

            $temp = json_decode(curlApi($url, $userData, "POST"), true);

            if (empty($temp) || $temp['err_code'] != 0) errorLog(10001, '消息推送失败记录,用户ID:'.$uid);             
            
            continue;     
        }

        // 推送到crm
        $crm_url = Config('website.crm_domain').'/api/notifyNewUser';
        $crm_header = array('api-key: crm a1b2c3d4e5f6g7h8i9jk');

        $res = json_decode(curlApi($crm_url, $crm_params, "POST", false, $crm_header), true);

        if (!$res || $res['err_code'] != 0) errorLog(10002, '新用户推送到crm失败 '.$res['err_msg']);
    }

}