<?php

namespace App\Handlers;

use App\Models\EcommerceBillW;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class EcommerceBillHandler extends Command
{
    //获取二级商户资金账单
    public function getecommercebill($bill_date,$account_type,$algorithm){
        $url='https://api.mch.weixin.qq.com/v3/ecommerce/bill/fundflowbill?bill_date='.$bill_date.'&account_type='.$account_type.'&algorithm='.$algorithm;
        $merchant_id=config('wechat.payment.default.mch_id');//商户号
        $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号
        $handle=new SignHandler();
        $mch_private_key=$handle->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文
        $timestamp=time();//时间戳
        $nonce=$handle->nonce_str();//随机字符串
        $body="";
        $sign=$handle->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
        $header=[
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
            'Accept:application/json',
            'User-Agent:' . $merchant_id,
            'Content-Type:application/json',
            'Wechatpay-Serial:' . $handle->getzhengshu()//获取平台证书序列号
        ];
        $result=$handle->curl($url,'',$header,'GET');
        $res=json_decode($result,true);
        Log::info($bill_date.'下载资金账单，页数为'.count($res['download_bill_list']));
        foreach($res['download_bill_list'] as $key=>$val){
            $ciphertext= $this->down($val['download_url']);
            $key=$this->getDecrypt($val['encrypt_key'],'',$val['nonce']);
            $result_str=$this->decryptToString('',$val['nonce'],base64_encode($ciphertext),$key);
            $res_arr=$this->deal_ecommerce_bill($result_str);
            $bill_day = $res_arr['bill'][0]['bill_date'];
            $trade_info = EcommerceBillW::where('bill_date',$bill_day)->first();
            if(!$trade_info){
                if(count($res_arr['bill']) > 1000){
                    $arr = array_chunk($res_arr['bill'],1000);
                    foreach($arr as $k=>$v){
                        EcommerceBillW::insert($v);
                    }
                }else{
                    EcommerceBillW::insert($res_arr['bill']);
                }
            }
        }
        return $res;
    }

    public function down($url){
        $merchant_id=config('wechat.payment.default.mch_id');//商户号
        $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号
        $handle=new SignHandler();
        $mch_private_key=$handle->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文
        $timestamp=time();//时间戳
        $nonce=$handle->nonce_str();//随机字符串
        $body="";
        $sign=$handle->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
        $header=[
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
            'Accept:application/json',
            'User-Agent:' . $merchant_id,
            'Content-Type:application/json',
            'Wechatpay-Serial:' . $handle->getzhengshu()//获取平台证书序列号
        ];
        $result=$handle->curl($url,'',$header,'GET');
        return $result;
    }

    //解密数据
    public function getDecrypt($ciphertext, $associatedData, $nonceStr){
        $mch_private_key= file_get_contents(config('wechat.payment.default.key_path'));
//        Log::info($mch_private_key);
        $str = base64_decode($ciphertext);
        openssl_private_decrypt($str,$encrypted,$mch_private_key,OPENSSL_PKCS1_OAEP_PADDING);
        return $encrypted;
    }

    //解密返回的信息
    public function decryptToString($associatedData,$nonceStr,$ciphertext,$aesKey){
        if (strlen($aesKey) != 32) {
            throw new InvalidArgumentException('无效的ApiV3Key，长度应为32个字节');
        }
        $ciphertext=\base64_decode($ciphertext);
        if (strlen($ciphertext) <= 16) {
            return false;
        }
        if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&
            \sodium_crypto_aead_aes256gcm_is_available()) {
            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
        }
        // ext-libsodium (need install libsodium-php 1.x via pecl)
        if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&
            \Sodium\crypto_aead_aes256gcm_is_available()) {
            return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
        }
//        if(function_exists('\sodium_crypto_aead_aes256gcm_is_available')&& \sodium_crypto_aead_aes256gcm_is_available()){
//            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext,$associatedData,$nonceStr,$aesKey);
//        }
        if(PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())){
            $ctext=substr($ciphertext,0,-16);
            $authTag=substr($ciphertext,-16);
            return \openssl_decrypt(
                $ctext,
                'aes-256-gcm',
                $aesKey,
                \OPENSSL_RAW_DATA,
                $nonceStr,
                $authTag,
                $associatedData
            );
        }
        throw new \RuntimeException('php7.1');
    }

    public function deal_ecommerce_bill($response){
        $result  = array();
        $response = str_replace(","," ",$response);
        $response = explode(PHP_EOL, $response);
        foreach ($response as $key=>$val){
            if(strpos($val, '`') !== false){
                $data = explode('`', $val);
                array_shift($data); // 删除第一个元素并下标从0开始
                if(count($data) == 13){ // 处理账单数据
                    $result['bill'][] = array(
                        'bill_time'       => $data[0], // 记账时间
                        'wx_order_no'        => $data[1], // 微信支付业务单号
                        'fee_order_no'        => $data[2], // 资金流水单号
                        'bill_name'        => $data[3], // 业务名称
                        'bill_type'         => $data[4], // 业务类型
                        'fee_type'     => $data[5], // 收支类型
                        'amount'     => $data[6], // 收支金额(元)
                        'account_fee'       => $data[7], // 账户结余(元)
                        'apply_name'       => $data[8], // 资金变更提交申请人
                        'remark'      => $data[9], // 备注
                        'bill_cre_no'         => $data[10], // 业务凭证号
                        'sub_mch_id'      => $data[11], // 电商二级商户号
                        'account_type'     => $data[12], // 账户类型
                        'bill_date'        => date("Y-m-d", strtotime($data[0]))
                    );
                }
                if(count($data) == 1){ // 统计数据
                    $result['summary'] = array(
                        'order_num'    => $data[0],  // 资金流水总笔数
                    );
                }
            }
        }
        return $result;
    }
}
