<?php
/**
 * homepage & article detail
 *
 * @package EMLOG
 * @link https://www.emlog.net
 */

class Pay_Controller {

    /**
     * 发起支付
     */
    function index() {

        doAction('before_payment');
        $options_cache = Option::getAll();
        extract($options_cache);
        $out_trade_no = Input::postStrVar('out_trade_no');

        $payment = Input::postStrVar('payment');
        $pay_plugin = Input::postStrVar('pay_plugin');
        $pay_name = Input::postStrVar('pay_name');

        if(empty($payment)){
            emMsg('该链接已失效，请重新发起支付！');
        }

        $db = Database::getInstance();
        $db_prefix = DB_PREFIX;
        $stockModel = new Stock_Model();


        $client_ip = getClientIP();

        $plugin_data = [
            'client_ip' => $client_ip
        ];

        doAction('start_pay_before', $plugin_data);

        if($out_trade_no){
            $orderModel = new Order_Model();
            $order_info = $orderModel->getOrderInfo($out_trade_no);
            $params = $orderModel->getOrderList($order_info['id']);
            $order_info['amount'] *= 100;
//            d($order_info); die;


        }else{
            $params = Input::postStrArray('product');
            foreach($params as $val){
                if(!empty($val['attach_user'])){
                    foreach($val['attach_user'] as $k => $v){
                        if(empty(trim($v))){
                            emMsg('请输入' . $k);
                        }
                    }
                }
            }
            $order_required = Input::postStrArray('order_required', []);
            foreach($order_required as $key => $val){
                if(empty(trim($val))){
                    $temp = explode('_', $key);
                    emMsg('请输入' . $temp[0]);
                }

            }

        }
        foreach($params as $val){

            if($val['quantity'] < 1){
                emMsg('非法请求');
            }
            $sku = empty($val['sku']) ? '0' : $val['sku'];
            $stock = $stockModel->getSkuStock($val['goods_id'], $sku);
            $quantity = ceil($val['quantity']);
            if($stock < $quantity){
                emMsg('该商品剩余库存量不足，请联系客服补货');
            }

        }

        $orderModel = new Order_Model();

        if($out_trade_no){
            $order = $orderModel->getOrderInfo($out_trade_no);
            $order_list = $orderModel->getOrderList($order['id']);
        }else{
            $timestamp = time();
            $out_trade_no = date('YmdHis', $timestamp) . mt_rand(1000, 9999);


            $order_info = [
                'out_trade_no' => $out_trade_no,
                'payment' => $payment,
                'pay_plugin' => $pay_plugin,
                'create_time' => $timestamp,
                'amount' => 0,
                'expire_time' => $timestamp + 600,
                'pay_name' => $pay_name,
                'client_ip' => getClientIP(),
                'user_id' => UID,
            ];
//        d($order_info); die;
            $order_id = $orderModel->addOrder($order_info);


            $order_required_insert = [];
            foreach($order_required as $key => $val){
                $temp = explode('_type_', $key);
                $sql = "INSERT INTO `{$db_prefix}order_required` (`order_id`, `name`, `type`, `content`) VALUES ({$order_id}, '{$temp[0]}', '{$temp[1]}', '{$val}')";
                $db->query($sql);
            }

            $order_list = [];
//d($params);die;
            foreach($params as $val){
                if(empty($val['sku'])){
                    $attr_spec = '';
                    $sku = $orderModel->getSku($val['goods_id'], 0);
                }else{
                    $specification_value_data = $orderModel->getSpecificationValue($val['sku']);
                    $specification_value = array_column($specification_value_data, 'name');

                    $specification_ids = array_column($specification_value_data, 'attr_id');
                    $specification_data = $orderModel->getSpecification($specification_ids);
                    $specification = array_column($specification_data, 'title');
                    $sku = $orderModel->getSku($val['goods_id'], $val['sku']);
                    $attr_spec = '';
                    foreach($specification as $k => $v){
                        $attr_spec .= $v . '：' . $specification_value[$k] . '；';
                    }
                }

                $sql = "SELECT * FROM `{$db_prefix}discount` WHERE `goods_id` = {$val['goods_id']}";
                $discount = $db->fetch_all($sql);
                $discount_key = -1;
                if($discount){
                    foreach($discount as $k => $v){
                        if($v['quantity'] <= $quantity){
                            $discount_key = $k;
                        }
                    }
                }

                if($discount_key > -1){
                    $price = (($sku['price'] - $discount[$discount_key]['amount'] / 100) * 100 ) * $quantity;
                }else{
                    $price = $sku['price'] * 100 * $quantity;
                }

//                var_dump($price);die;


                $order_list_insert = [
                    'order_id' => $order_id,
                    'goods_id' => $val['goods_id'],
                    'sku' => $val['sku'],
                    'quantity' => $quantity,
                    'unit_price' => $sku['price'] * 100,
                    'cost_price' => $sku['cost_price'] * $quantity,
                    'price' => $price,
                    'attr_spec' => $attr_spec,
                    'attach_user' => empty($val['attach_user']) ? null : json_encode($val['attach_user'], JSON_UNESCAPED_UNICODE),
                ];
                $order_info['amount'] += $price;
                $orderModel->addOrderList($order_list_insert);

                $order_list[] = $order_list_insert;

            }

            $update = [
                'amount' => $order_info['amount']
            ];

            $orderModel->updateOrderInfo($out_trade_no, $update);
        }

        doAction('before_submitting_the_payment', $order_list);

        $pay_func = "pay_{$pay_plugin}";

        if($pay_plugin == 'balance' || $order_info['amount'] == 0){
            // 余额支付
            if(ISLOGIN){
                $sql = "SELECT * FROM " . DB_PREFIX . "user WHERE uid = " . UID;

                $user = $db->once_fetch_array($sql);
                $order_money = $order_info['amount'] / 100;
                if($user['money'] < $order_money){
                    emMsg('您的余额不足，请联系客服充值');
                }
                $sql = "update " . DB_PREFIX . "user set money = money - {$order_money} where uid=" . UID;
                $db->query($sql);

                // 修改订单的支付状态
                $order_info = $orderModel->getOrderInfo($out_trade_no);
                $order_update = [
                    'pay_status' => 1,
                ];
                $orderModel->updateOrderPayStatus($order_info['id'], $order_update); // 修改订单的支付状态
                // 更新订单的支付时间
                $order_info['payment'] = $order_money == 0 ? '免费商品' : $order_info['payment'];
                $orderModel->updateOrderInfo($out_trade_no, ['pay_time' => time(), 'payment' => $order_info['payment']]);
                // 去发货
                $orderModel->deliver($order_info['id']);
                // 发货完成，订单流程结束。跳转到用户订单页面
                $url = Option::get('blogurl') . 'user/order.php';
                header("location: {$url}");
                die;

            }else{
                if($order_info['amount'] == 0){
                    emMsg('未登录用户无法购买免费商品，请先登录~');
                }else{
                    emMsg('未登录用户无法使用余额支付');
                }

            }
        }else{
            // 发起支付
            $pay_func($order_info, $order_list);
        }






    }


    /**
     * 同步通知
     */
    public function _return(){


        $orderModel = new Order_Model();

        $url = $_SERVER['REQUEST_URI'];
        // 移除查询参数，只保留路径部分
        $path = parse_url($url, PHP_URL_PATH); // 返回：/action/notify/epay_ali
        // 按斜杠分割路径
        $parts = explode('/', trim($path, '/'));
        // 获取第三个部分（索引为2）
        $plugin = $parts[2] ?? '';
        $out_trade_no = empty($parts[3]) ? '' : $parts[3];

        $checkFunc = $plugin . "CheckSign";
        $checkSign = $checkFunc('return');

        if($checkSign){ // 验签通过 - 支付成功
            $order_update = [
                'pay_status' => 1,
            ];
            $order = $orderModel->getOrderInfo($checkSign['out_trade_no']);
            if($order['pay_status'] == 1){
                $db = Database::getInstance();
                $sql = "SELECT * FROM `" . DB_PREFIX . "order_list` WHERE `order_id` = {$order['id']} LIMIT 1";
                $order_list = $db->once_fetch_array($sql);
                $sql = "SELECT * FROM `" . DB_PREFIX . "goods` WHERE `id` = {$order_list['goods_id']} LIMIT 1";
                $goods = $db->once_fetch_array($sql);

                $pay_redirect = Option::get('pay_redirect') ? Option::get('pay_redirect') : 'list';
                if($pay_redirect == 'kami'){
                    if($goods['type'] == 'duli' || $goods['type'] == 'guding'){
                        $url = Option::get('blogurl') . 'user/order.php?action=sdk&id=' . $order_list['id'] . '&out_trade_no=' . $order['out_trade_no'];
                    }else{
                        if(ISLOGIN){
                            $url = Option::get('blogurl') . 'user/order.php';
                        }else{
                            $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order['out_trade_no'];
                        }
                    }
                }else{
                    if(ISLOGIN){
                        $url = Option::get('blogurl') . 'user/order.php';
                    }else{
                        $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order['out_trade_no'];
                    }
                }
                header("location: {$url}");
                die;
            }else{
                $res = $orderModel->updateOrderPayStatus($order['id'], $order_update); // 修改订单的支付状态
                if($res == false){
                    $db = Database::getInstance();
                    $sql = "SELECT * FROM `" . DB_PREFIX . "order_list` WHERE `order_id` = {$order['id']} LIMIT 1";
                    $order_list = $db->once_fetch_array($sql);
                    $sql = "SELECT * FROM `" . DB_PREFIX . "goods` WHERE `id` = {$order_list['goods_id']} LIMIT 1";
                    $goods = $db->once_fetch_array($sql);

                    $pay_redirect = Option::get('pay_redirect') ? Option::get('pay_redirect') : 'list';
                    if($pay_redirect == 'kami'){
                        if($goods['type'] == 'duli' || $goods['type'] == 'guding'){
                            $url = Option::get('blogurl') . 'user/order.php?action=sdk&id=' . $order_list['id'] . '&out_trade_no=' . $order['out_trade_no'];
                        }else{
                            if(ISLOGIN){
                                $url = Option::get('blogurl') . 'user/order.php';
                            }else{
                                $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order['out_trade_no'];
                            }
                        }
                    }else{
                        if(ISLOGIN){
                            $url = Option::get('blogurl') . 'user/order.php';
                        }else{
                            $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order['out_trade_no'];
                        }
                    }
                    header("location: {$url}");
                    die;
                }
            }

            Log::info("同步回调！订单号：{$checkSign['out_trade_no']}");

            // 更新订单的支付时间
			$orderModel->updateOrderInfo($checkSign['out_trade_no'], [
                'pay_time' => $checkSign['timestamp'],
                'up_no' => $checkSign['up_no']
            ]);
            // 去发货
            $orderModel->deliver($order['id']);

            header("location: " . EM_URL . 'user/order.php' . (ISLOGIN ? '' : '?action=search'));
            die;



        }else{ // 验签失败
            echo '验签失败';
        }
    }



    /**
     * 异步通知
     */
    public function notify(){

        $orderModel = new Order_Model();

        $url = $_SERVER['REQUEST_URI'];
        // 移除查询参数，只保留路径部分
        $path = parse_url($url, PHP_URL_PATH); // 返回：/action/notify/epay_ali
        // 按斜杠分割路径
        $parts = explode('/', trim($path, '/'));
        // 获取支付插件名称
        $plugin = $parts[2] ?? '';
        $checkFunc = $plugin . "CheckSign";
        $checkSign = $checkFunc('notify');

        if($checkSign){ // 验签通过 - 支付成功
        

            $order_info = $orderModel->getOrderInfo($checkSign['out_trade_no']);

            $order_update = [
                'pay_status' => 1,
            ];
            
            $order = $orderModel->getOrderInfo($checkSign['out_trade_no']);
            if($order['pay_status'] == 1){
                echo 'success'; die; // 重复通知
            }else{
                $res = $orderModel->updateOrderPayStatus($order_info['id'], $order_update); // 修改订单的支付状态
                if($res == false){
                    echo 'success'; die; // 重复通知
                }
            }

            Log::info("异步回调！订单号：{$checkSign['out_trade_no']}");
			
            // 更新订单的支付时间
            $orderModel->updateOrderInfo($checkSign['out_trade_no'], [
                'pay_time' => $checkSign['timestamp'],
                'up_no' => $checkSign['up_no']
            ]);
            // 去发货
            $orderModel->deliver($order_info['id']);
            echo 'success'; die;

        }else{ // 验签失败
            echo '验签失败';
        }

    }

    /**
     * 补单
     */
    public function repay($out_trade_no){
        $orderModel = new Order_Model();
        $order_info = $orderModel->getOrderInfo($out_trade_no);

        $order_update = [
            'pay_status' => 1,
        ];
        $res = $orderModel->updateOrderPayStatus($order_info['id'], $order_update); // 修改订单的支付状态
        if(!$res){ // 重复通知
            emMsg('请勿重复补单，该订单状态为已支付！');
        }
        // 更新订单的支付时间
        $orderModel->updateOrderInfo($out_trade_no, ['pay_time' => time(), 'payment' => $order_info['payment'] . '(补单)']);
        // 去发货
        $orderModel->deliver($order_info['id']);


    }

    /**
     * 验证订单支付状态
     */
    public function isPay(){
        $out_trade_no = Input::postStrVar('out_trade_no');
        $orderModel = new Order_Model();
        $order_info = $orderModel->getOrderInfo($out_trade_no);
        if($order_info['pay_time']){

            $db = Database::getInstance();
            $sql = "SELECT * FROM `" . DB_PREFIX . "order_list` WHERE `order_id` = {$order_info['id']} LIMIT 1";
            $order_list = $db->once_fetch_array($sql);
            $sql = "SELECT * FROM `" . DB_PREFIX . "goods` WHERE `id` = {$order_list['goods_id']} LIMIT 1";
            $goods = $db->once_fetch_array($sql);
            $pay_redirect = Option::get('pay_redirect') ? Option::get('pay_redirect') : 'list';

            if($pay_redirect == 'kami'){
                if($goods['type'] == 'duli' || $goods['type'] == 'guding'){
                    $url = Option::get('blogurl') . 'user/order.php?action=sdk&id=' . $order_list['id'] . '&out_trade_no=' . $order_info['out_trade_no'];
                }else{
                    if(ISLOGIN){
                        $url = Option::get('blogurl') . 'user/order.php';
                    }else{
                        $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order_info['out_trade_no'];
                    }
                }
            }else{
                if(ISLOGIN){
                    $url = Option::get('blogurl') . 'user/order.php';
                }else{
                    $url = Option::get('blogurl') . 'user/order.php?action=search&type=out_trade_no&pwd=' . $order_info['out_trade_no'];
                }
            }





            die(json_encode([
                'code' => 200, 'msg' => 'Paid', 'data' => [
                    'is_pay' => true,
                    'url' => $url
                ]
            ]));
        }else{
            die(json_encode([
                'code' => 200, 'msg' => 'Unpaid', 'data' => [
                    'is_pay' => false
                ]
            ]));
        }
    }



}
