<?php

declare (strict_types=1);

namespace app\controller;


use app\controller\Bus\PlugCharge;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use DateInterval;
use DateTime;
use Overtrue\Pinyin\Pinyin;
use think\facade\Cache;
use think\facade\Db;
use think\Request;


class TeldTest
{

    public $OperatorID = 'MACFHBM3X'; //运营商标识
    public $OperatorSecret = '1234567890abcdef';//运营商密钥
    public $DataSecret = '1234567890abcdef';//消息秘钥
    public $DataSecretIV = '1234567890abcdef';//消息密钥初始化向量
    public $SigSecret = '1234567890abcdef';//签名密钥
    public $Seq = '001';
    public $url = 'http://hlht.teld9.xyz/evcs/v20191230/';//测试地址
    public $connectorID = '3702121094205';//桩子号
    public $EquipAuthSeq = '3702121094205';//桩子认证号

    public $iv = '1234567890abcdef';//iv的长度要根据加密方式和模式来定,aes-128-cbc偏移量的是16位

    public $key = '1234567890abcdef';
    //获取token
    //查询充电站信息
    //设备接口状态查询
    //设备状态变化推送
    //查询业务策略信息
    //请求设备认证
    //请求启动充电
    //推送启动充电结果
    //查询充电状态
    //推送充电状态
    //请求停止充电
    //推送停止充电结果
    //推送充电订单信息
    //自助备案车牌号
    //获取商户企业账户余额
    //订单文件下载

    //token
    public function getToken()
    {
        $OperatorID = $this->OperatorID;
        $OperatorSecret = $this->OperatorSecret;
        $time = date('YmdHis');
        $Seq = $this->Seq;
        $mess = array('OperatorID' => $OperatorID, 'OperatorSecret' => $OperatorSecret);
        $data = json_encode($mess);


        $en_data = $this->encrypt($data);

        $de_Sig = $OperatorID . $en_data . $time . $Seq;

        $Sig = $this->HMAC($de_Sig, $this->DataSecret);
        $kk['OperatorID'] = $OperatorID;
        $kk['Data'] = $en_data;
        $kk['TimeStamp'] = $time;
        $kk['Seq'] = $Seq;
        $kk['Sig'] = $Sig;


        $datas = $this->CurlSend_Token($this->url . '/query_token', $kk);

        $array_data = (array)$datas;
        if ($array_data['Ret'] == 0) {
            $token = $array_data['Data'];
            $de_data = $this->decrypt($token);
            $arr_token = json_decode($de_data);
            $array_token = (array)$arr_token;
            $token = $array_token['AccessToken'];
            Cache::set('token', $token, 7200);
            return $token;
        } else {
            return 1;
        }
    }


    //设备认证
    public function queryEquipAuth()
    {
        Cache::delete('token');
        $token = Cache::get('token');
        if (!$token) {
            $token = $this->getToken();
        }
        $datetime = date('YmdHis');
        $kk['EquipAuthSeq'] = $this->EquipAuthSeq;
        $kk['ConnectorID'] = $this->connectorID;
        $en = $this->encrypt(json_encode($kk));
        $sig = $this->OperatorID . $en . $datetime . $this->Seq;
        $s = $this->HMAC($sig, $this->DataSecret);
        $rr['OperatorID'] = $this->OperatorID;
        $rr['Data'] = $en;
        $rr['TimeStamp'] = $datetime;
        $rr['Seq'] = $this->Seq;
        $rr['Sig'] = $s;
        $data = $rr;
        $message = $this->CurlSend_Token($this->url . '/query_equip_auth', $data, $token);

        $en_mess = $message['Data'];
        $de_data = $this->decrypt($en_mess);

        $arr = json_decode($de_data, true);

//  Array
// (
//     [FailReason] => 0
//     [SuccStat] => 0
//     [EquipAuthSeq] => 3702121094205
//     [ConnectorID] => 3702121094105
// )
        return $arr;
    }


    //开始充电
    public function queryStartCharge()
    {
        $token = Cache::get('token');
        if (!$token) {
            $token = $this->getToken();
        }
        $datetime = date('YmdHis');
        $kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
        $kk['ConnectorID'] = $this->connectorID;
        $kk['QRCode'] = 'QRCode';
        $kk['PhoneNum'] = ''; //13698689669 个人支付必传，格式确保正确
        $kk['PlateNum'] = '';// 车牌号
        $en = $this->encrypt(json_encode($kk));


        $sig = $this->OperatorID . $en . $datetime . $this->Seq;
        $s = $this->HMAC($sig, $this->DataSecret);
        $rr['OperatorID'] = $this->OperatorID;
        $rr['Data'] = $en;
        $rr['TimeStamp'] = $datetime;
        $rr['Seq'] = $this->Seq;
        $rr['Sig'] = $s;


        $message = $this->CurlSend_Token($this->url . '/query_start_charge', $rr, $token);

        $en_mess = $message['Data'];
        $de_data = $this->decrypt($en_mess);
        $arr = json_decode($de_data);
        $array = (array)$arr;

        return $array;

        // Array (
        // [StartChargeSeq] => MACFHBM3X175705873925064035
        // [SuccStat] => 1
        // [FailReason] => 18
        // [StartChargeSeqStat] => 5
        // [ConnectorID] => 3702121094105
        // )
    }

//充电状态
    public function queryEquipChargeStatus()
    {
        $token = Cache::get('token');
        if (!$token) {
            $token = $this->getToken();
        }
        $datetime = date('YmdHis');
        $kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
        
        $en = $this->encrypt(json_encode($kk));
        $sig = $this->OperatorID . $en . $datetime . $this->Seq;
       
        $s = $this->HMAC($sig, $this->DataSecret);
        
        $rr['OperatorID'] = $this->OperatorID;
        $rr['Data'] = $en;
        $rr['TimeStamp'] = $datetime;
        $rr['Seq'] = $this->Seq;
        $rr['Sig'] = $s;
        $data = $rr;
        $message = $this->CurlSend_Token($this->url . '/query_equip_charge_status ', $data, $token);
       
        $en_mess = $message['Data'];
        $de_data = $this->decrypt($en_mess);
        $arr = json_decode($de_data);
        $array = (array)$arr;
        halt($array);
        if (isset($array['TotalMoney'])) {
            $area = \app\model\ChargeOrder::where('StartChargeSeq', $StartChargeSeq)->value('area');
            $pinyin = new Pinyin();
            $s = $pinyin->sentence($area);
            $s = strtr($s, array(' ' => ''));
            $table = 'charge_order_' . $s;
            $table_user = 'user_' . $s;
            $ll = array_diff_key($array, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', "StartChargeSeq" => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
            $station_id = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('charge_station_id');
            $station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
            $openid = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('openid');
            $detail_message = '';
            if ((int)$station_type == 0) {
                $ii = 1;
                $total = 0;
                $ElectMoney = 0;
                $SeviceMoney = 0;
                foreach ($array['ChargeDetails'] as $Details) {
                    $Details = (array)$Details;
                    $per_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Elect'];
                    $S_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Serve'];
                    $period_price = round($Details['DetailPower'] * $per_price, 2);
                    $service_price = round($Details['DetailPower'] * $S_price, 2);
                    $total_money = $period_price + $service_price;
                    $detail_message .= '时段' . $ii .
                        ':开始时间:' . $Details['DetailStartTime'] . ',' .
                        '结束时间:' . $Details['DetailEndTime'] . ',' .
                        '所用度数:' . $Details['DetailPower'] . ',' .
                        '时段电费单价:' . $per_price . ',' .
                        '时段电费金额:' . $period_price . ',' .
                        '时段服务费单价:' . $S_price . ',' .
                        '时段服务费金额:' . $service_price . ',' .
                        '时段总价:' . $total_money . ';';
                    $ii += 1;
                    $total += $total_money;
                    $ElectMoney += $period_price;
                    $SeviceMoney += $service_price;
                }
            } else {
                $price = $this->GetPrice($station_id, $openid, $table_user);
                $total = $ll['TotalPower'] * $price['EPrice'] + ($ll['TotalPower'] * $price['SPrice']);
                $ElectMoney = $array['TotalPower'] * $price['EPrice'];
                $SeviceMoney = $array['TotalPower'] * $price['SPrice'];
            }
            $ll['TotalMoney'] = round($total, 2);
            $ll['ElecMoney'] = round($ElectMoney, 2);
            $ll['SeviceMoney'] = round($SeviceMoney, 2);
            $WithholdingMoney = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('WithholdingMoney');
            $order_num = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('order_number');
            if ((float)$WithholdingMoney - (float)$ll['TotalMoney'] <= 3) {
                $order = new ChargeOrder();
                $order->EndOrder($openid, $order_num);
            }
            $ll['status'] = $ll['StartChargeSeqStat'];
            $end_time = Db::table($table)->where('order_number', $order_num)->value('end_time');
            $status = Db::table($table)->where('order_number', $order_num)->value('status');
            if (empty($end_time) && $status != 4) {
                Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->save($ll);
            }
            return ['code' => 200];
        } else {
            return ['code' => 1];
        }
    }


//停止充电
    public function queryStopCharge()
    {
       
        $token = Cache::get('token');
        if (!$token) {
            $token = $this->getToken();
        }
        $datetime = date('YmdHis');
        $kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
        $kk['ConnectorID'] = $this->connectorID;


        $en = $this->encrypt(json_encode($kk));
        $sig = $this->connectorID . $en . $datetime . $this->Seq;


        $s = $this->HMAC($sig, $this->DataSecret);

        $rr['OperatorID'] = $this->connectorID;
        $rr['Data'] = $en;
        $rr['TimeStamp'] = $datetime;
        $rr['Seq'] = $this->Seq;
        $rr['Sig'] = $s;

        $data = $rr;
        $message = $this->CurlSend_Token($this->url . '/query_stop_charge', $data, $token);

        halt($message);
        $en_mess = $message['Data'];
        $de_data = $this->decrypt($en_mess);
        $arr = json_decode($de_data);
        $array = (array)$arr;
        return $array;
    }


    public function index()
    {

        return print_r($this->queryStopCharge());

    }


    function CurlSend_Token($url, $data = '', $token = '')
    {
        $data = json_encode($data);
        $ch = curl_init();
        $headers = array();
        if ($token) {
            $headers[] = 'Authorization: Bearer ' . $token;
        }
        $headers[] = 'Content-Type: application/json;charset=utf-8';
        $headers[] = 'Content-Length: ' . strlen($data);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $curl_return = curl_exec($ch);
        curl_close($ch);
        return json_decode(trim($curl_return), true);
    }

    public function HMAC($data, $key)
    {
        $key = $this->strToUtf8($key);
        $data = $this->strToUtf8($data);

        $b = 64; // byte length for md5
        if (strlen($key) > $b) {
            $key = pack("H32", md5($key));
        }
        $key = str_pad($key, $b, chr(0x00));
        $ipad = str_pad('', $b, chr(0x36));
        $opad = str_pad('', $b, chr(0x5c));
        $k_ipad = $key ^ $ipad;
        $k_opad = $key ^ $opad;

        return strtoupper(md5($k_opad . pack("H32", md5($k_ipad . $data))));
    }

    function strToUtf8($str)
    {
        $encode = mb_detect_encoding($str, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
        if ($encode == 'UTF-8') {
            return $str;
        } else {
            return mb_convert_encoding($str, 'UTF-8', $encode);
        }
    }

    public function encrypt($input)
    {
        return base64_encode(openssl_encrypt($input, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv));
    }

    public function decrypt($input)
    {
        return openssl_decrypt(base64_decode($input), 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv);
    }
}