<?php
/**
 * Created by PhpStorm.
 * User: qiuzijian
 * Date: 2021-04-28
 * Time: 20:59
 */

namespace Modules\Camera\Http\Controllers\Api;

use App\Http\Controllers\Api\BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use Modules\Camera\Enum\CameraEnum;
use Modules\Mine\Entities\MineList;
use Modules\Mine\Services\MineServices;


class HaiKangController extends BaseController
{
    protected $pre_url;  // 海康接口地址
    protected $app_key;  // 海康app_key
    protected $app_secret;  // 海康app_secret
    protected $sign;//  签名
    protected $time;//  时间戳
    protected $artemis;//  OpenAPI接口的上下文

    public function __construct()
    {
//        if ($request->has('mine')) {
//            $this->pre_url    = config('haikang.' . $request->input('mine') . '.pre_url');  // https://120.253.79.51:4433
//            $this->app_key    = config('haikang.' . $request->input('mine') . '.app_key');  // 25720460
//            $this->app_secret = config('haikang.' . $request->input('mine') . '.app_secret');  // qqP7NLcIDwO9MgtYmp8L
//            $this->artemis    = config('haikang.' . $request->input('mine') . '.artemis');  // /artemis
//        } else {
//            $this->pre_url    = env('HAI_KANG_URL');  // https://120.253.79.51:4433
//            $this->app_key    = env('HAI_KANG_APP_KEY');  // 25720460
//            $this->app_secret = env('HAI_KANG_APP_SECRET');  // qqP7NLcIDwO9MgtYmp8L
//            $this->artemis    = env('HAI_KANG_ARTEMIS_PATH');  // /artemis
//        }
//        $this->pre_url    = 'https://10.71.252.64:4433';  // https://120.253.79.51:4433
//        $this->app_key    = '25720460';  // 25720460
//        $this->app_secret = 'qqP7NLcIDwO9MgtYmp8L';  // qqP7NLcIDwO9MgtYmp8L
//        $this->artemis    = '/artemis';  // /artemis
        $this->pre_url    = Input::get('url');  // https://120.253.79.51:4433
        $this->app_key    = Input::get('key');  // 25720460
        $this->app_secret = Input::get('secret');  // qqP7NLcIDwO9MgtYmp8L
        $this->artemis    = '/artemis';  // /artemis

        list($msec, $sec) = explode(' ', microtime());
        $this->time = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

    /**
     * 获取区域列表
     * @return bool|mixed|string
     */
    public function getRegionsList()
    {
        $url = $this->artemis . '/api/resource/v1/regions';
        //请求参数
        $params = [];
//        $params['pageNo']   = $request->has('pageNo') ? intval($request->input('pageNo')) : 1;
//        $params['pageSize'] = $request->has('pageSize') ? intval($request->input('pageSize')) : 1000;
        $params['pageNo']   = 1;
        $params['pageSize'] = 1000;
        $this->sign         = $this->get_sign($url);

        $type    = Input::get('type');
        $mine_id = Input::get('mine_id');

        $result = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result = json_decode($result, true);

        $area_list = [];
        if (isset($result['code']) && $result['code'] == 0) {
            $list = $result['data']['list'];
            foreach ($list as $key => $item) {
                $area_list[] = $item['indexCode'];
                if ($item['parentIndexCode'] == '-1') {
                    unset($list[$key]);
                }
            }
            $result['data']['list'] = array_values($list);
        }

        if ($type == CameraEnum::REQUEST_TYPE_API) {
            $result['data']['list'] = $this->regionsTree($result['data']['list']);
        } else {
            //先删除不存在的区域
            if ($area_list) {
                MineList::where('degree', 'like', $mine_id . '|%')->whereNotIn('index_code', $area_list)->delete();
            }

            //更新区域
            $result['data']['list'] = $this->saveTree($result['data']['list'], $mine_id);
        }

        return $result;
    }

    protected function regionsTree($regions, $pid = 'root000000')
    {
        $arr = [];
        if (empty($regions)) {
            return [];
        }

        foreach ($regions as $key => $value) {
            if (isset($value['parentIndexCode']) && $value['parentIndexCode'] == $pid) {
                $arr[$key]['indexCode']       = $value['indexCode'];
                $arr[$key]['mine_id']         = $value['indexCode'];
                $arr[$key]['name']            = $value['name'];
                $arr[$key]['parentIndexCode'] = $value['parentIndexCode'];
                $arr[$key]['treeCode']        = $value['treeCode'];
                $arr[$key]['children']        = array_values(self::regionsTree($regions, $value['indexCode']));
                unset($arr[$key]['indexCode']);
                unset($arr[$key]['parentIndexCode']);
                unset($arr[$key]['treeCode']);
                if (count($arr[$key]['children']) == 0) {
                    unset($arr[$key]['children']);
                }
            }
        }

        return array_values($arr);
    }

    protected function saveTree($regions, $parent_id, $pid = 'root000000')
    {

        $arr = [];
        if (empty($regions)) {
            return [];
        }

        $mineService = new MineServices();
        $mineService->initMineList();

        $arr_count = count($regions);
        foreach ($regions as $key => $value) {
            if (isset($value['parentIndexCode']) && $value['parentIndexCode'] == $pid) {
                $arr[$key]['indexCode']       = $value['indexCode'];
                $arr[$key]['mine_id']         = $value['indexCode'];
                $arr[$key]['name']            = str_replace('#', '号', $value['name']);
                $arr[$key]['parentIndexCode'] = $value['parentIndexCode'];
                $arr[$key]['treeCode']        = $value['treeCode'];

                $id      = MineList::where('index_code', $value['indexCode'])->value('id');
                $params  = [
                    'id'         => $id,
                    'parent_id'  => $parent_id,
                    'title'      => $value['name'],
                    'sort'       => $arr_count - $key,
                    'index_code' => $value['indexCode'],
                ];
                $result  = $mineService->add($params);
                $mine_id = $result->id;

                $arr[$key]['children'] = array_values(self::saveTree($regions, $mine_id, $value['indexCode']));
                if (count($arr[$key]['children']) == 0) {
                    unset($arr[$key]['children']);
                }
            }
        }

        return array_values($arr);
    }

    /**
     * 获取区域监控列表
     * @return bool|mixed|string
     */
    public function getCamerasList()
    {
        if (!Input::has('indexCode')) {
            return $this->error(1, '缺少必要参数');
        }
        $url = $this->artemis . '/api/resource/v1/regions/regionIndexCode/cameras';
        //请求参数
        $params                    = [];
        $params['regionIndexCode'] = Input::get('indexCode');
//        $params['pageNo']          = $request->has('pageNo') ? intval($request->input('pageNo')) : 1;
//        $params['pageSize']        = $request->has('pageSize') ? intval($request->input('pageSize')) : 1000;
        $params['pageNo']   = 1;
        $params['pageSize'] = 1000;
        $this->sign         = $this->get_sign($url);

        $result = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result = json_decode($result, true);
        return $result;
    }

    /**
     * 获取摄像头码流url
     * @return array|mixed
     */
    public function getCamerasUrl()
    {
        if (!Input::has('cameraIndexCode')) {
            return $this->error(1, '缺少必要参数');
        }
        $protocol   = Input::get('protocol', 'hls');
        $streamType = Input::get('streamType', 1);
        $url        = $this->artemis . '/api/video/v1/cameras/previewURLs';
//        $cameras_info = json_decode($this->getCamerasInfo(Input::all()), true);
        //请求参数
        $params = [];
//        $params['regionIndexCode'] = $request->input('regionIndexCode');
        $params['cameraIndexCode'] = Input::get('cameraIndexCode');
        $params['streamType']      = $streamType;  //0主码流 1子码流 2第三码流
        $params['protocol']        = $protocol;
        $params['transmode']       = 1;  //0:UDP 1:TCP
        $params['expand'] = 'transcode=1&systemformat=ps&videotype=h264';

        $this->sign = $this->get_sign($url);

        $result = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result = json_decode($result, true);
        if (isset($result['code']) && $result['code'] == 0) {  // 将内网地址替换为外网地址
            $video_url = $result['data']['url'];
            preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $video_url, $res);  // 提取内网ip
            preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i', $this->pre_url, $res_n);  // 提取外网ip
            $result['data']['url'] = str_replace($res, $res_n, $video_url);
        }
        return $result;
    }

    /**
     * 获取摄像头详情
     * @param array $data
     * @return array|bool|string
     */
    public function getCamerasInfo($data)
    {
        $url = $this->artemis . '/api/resource/v1/cameras/indexCode';
        //请求参数
        $params                    = [];
        $params['cameraIndexCode'] = $data['cameraIndexCode'];

        $this->sign = $this->get_sign($url);
        $result     = $this->curlPost($this->pre_url . $url, json_encode($params));
        return $result;
    }

    //获取编码设备信息
    public function getTranscodeInfo()
    {
        $url = $this->artemis . '/api/resource/v1/encodeDevice/get';
        //请求参数
        $params             = [];
        $params['pageNo']   = 1;
        $params['pageSize'] = 1;

        $this->sign = $this->get_sign($url);
        $result     = $this->curlPost($this->pre_url . $url, json_encode($params));
        return $result;
    }

    //根据区域获取下级编码设备列表
    public function getTest()
    {
        $url = $this->artemis . '/api/resource/v1/encodeDevice/subResources';
        //请求参数
        $params             = [];
        $params['pageNo']   = 1;
        $params['pageSize'] = 1000;
        $params['regionIndexCode'] = Input::get('indexCode');

        $this->sign = $this->get_sign($url);
        $result     = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result = json_decode($result, true);
        return $result;
    }

    //获取编码设备列表
    public function getTranscodeList()
    {
        $url = $this->artemis . '/api/resource/v1/encodeDevice/subResources';
        //请求参数
        $params['regionIndexCode'] = 'root000000';
        $params['pageNo']          = 1;
        $params['pageSize']        = 100;

        $this->sign = $this->get_sign($url);
        $result     = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result     = json_decode($result, true);
        return $result;
    }

    public function getRegionsInfo()
    {
        $url = $this->artemis . '/api/resource/v1/region/regionCatalog/regionInfo';
        //请求参数
        $params = [];

        $indexCodes = Input::get('indexCodes');
        $params['indexCodes'] = $indexCodes;

        $this->sign = $this->get_sign($url);

        $result = $this->curlPost($this->pre_url . $url, json_encode($params));
        $result = json_decode($result, true);
//        if (isset($result['code']) && $result['code'] == 0) {
//        }

        return $result;
    }

    /**
     * 以appSecret为密钥，使用HmacSHA256算法对签名字符串生成消息摘要，对消息摘要使用BASE64算法生成签名（签名过程中的编码方式全为UTF-8）
     */
    protected function get_sign($url)
    {
        $sign_str = $this->get_sign_str($url); //签名字符串
        $priKey   = $this->app_secret;
        $sign     = hash_hmac('sha256', $sign_str, $priKey, true); //生成消息摘要
        $result   = base64_encode($sign);
        return $result;
    }

    /**
     * 生成签名
     * @param $url
     * @return string
     */
    protected function get_sign_str($url)
    {
        // $next = "\n";
        $next = "\n";
        $str  = "POST" . $next . '*/*' . $next . 'application/json' . $next;
        $str  .= "x-ca-key:" . $this->app_key . $next;
        $str  .= "x-ca-timestamp:" . $this->time . $next;
        $str  .= $url;
        return $str;
    }

    /**
     * 发送请求
     * @param string $url
     * @param string $postData
     * @param array  $options
     * @return bool|string
     */
    public function curlPost($url = '', $postData = '', $options = array())
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数

        curl_setopt_array($ch, array(
            CURLOPT_HTTPHEADER => array(
                "Accept:" . '*/*',
                "Content-Type:" . 'application/json',
                "x-Ca-Key:" . $this->app_key,
                "X-Ca-Signature:" . $this->sign,
                "X-Ca-Timestamp:" . $this->time,
                "X-Ca-Signature-Headers:" . "x-ca-key,x-ca-timestamp",
            )
        ));

        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
}
