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

namespace Modules\Camera\Services;

use App\Enum\ApiEnum;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use Modules\Admin\Enum\AdminEnum;
use Modules\Camera\Entities\CameraFieldList;
use Modules\Camera\Entities\CameraList;
use Modules\Camera\Enum\CameraEnum;
use Modules\Camera\Http\Controllers\Api\HaiKangController;
use Modules\Mine\Entities\MineList;
use Modules\Mine\Entities\MineListExt;
use Modules\Mine\Enum\MineEnum;

class CameraServices
{
    //添加摄像头链接
    public static function addCameraList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        //通过ip+端口+通道号作为唯一标识判断数据是否存在
        $query = CameraList::where(
            [
                'ip'         => $params['ip'],
                'port'       => $params['port'],
                'com_number' => $params['com_number'],
            ]
        )->first();

        if ($query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_ALREADY_EXIST;
            return $result;
        }

        $camera_url = self::makeCameraUrl($params);

        //入库动作
        $res = CameraList::insert(
            [
                'mine_id'     => $params['mine_id'],
                'ip'          => $params['ip'],
                'port'        => $params['port'],
                'user_name'   => $params['user_name'],
                'password'    => $params['password'],
                'com_number'  => $params['com_number'],
                'camera_name' => $params['camera_name'],
                'revert_id'   => CameraEnum::CAMERA_DEFAULT_REVERT_ID,
//                'status'     => $params['status'],
                'camera_url'  => $camera_url,
                'sort'        => $params['sort'],
                'created_at'  => date('Y-m-d H:i:s'),
                'updated_at'  => date('Y-m-d H:i:s'),
            ]
        );

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }

    //生成摄像头请求链接
    public static function makeCameraUrl($params)
    {
        $url  = 'rtsp://' . $params['user_name'] . ':' . $params['password'] . '@';
        $url .= $params['ip'] . ':' . $params['port'] . '/' . 'h264' . '/' . 'ch' . $params['com_number'] . '/';
        $url .= 'sub/av_stream';     //sub 子码流
//        $url .= 'main/av_stream';  //main 主码流
        return $url;
    }

    //编辑摄像头链接
    public static function editCameraList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        $camera_url = self::makeCameraUrl($params);

        //判断记录是否存在
        $query = CameraList::find($params['id']);

        if (!$query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_NOT_EXIST;
            return $result;
        }

        //通过ip+端口+通道号作为唯一标识判断数据是否存在
        $query = CameraList::where(
            [
                'ip'         => $params['ip'],
                'port'       => $params['port'],
                'com_number' => $params['com_number'],
            ]
        )->where('id', '!=', $params['id'])->first();

        if ($query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_ALREADY_EXIST;
            return $result;
        }

        //更新动作
        $res = CameraList::where('id', $params['id'])->update(
            [
                'mine_id'     => $params['mine_id'],
                'ip'          => $params['ip'],
                'port'        => $params['port'],
                'user_name'   => $params['user_name'],
                'password'    => $params['password'],
                'com_number'  => $params['com_number'],
                'camera_name' => $params['camera_name'],
//                'status'     => $params['status'],
                'camera_url'  => $camera_url,
                'sort'        => $params['sort'],
                'updated_at'  => date('Y-m-d H:i:s'),
            ]
        );

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }

    //删除摄像头列表记录
    public static function delCameraList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        //判断字段是否存在
        $query = CameraList::find($params['id']);

        if (!$query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_NOT_EXIST;
            return $result;
        }

        $res = CameraList::where('id', $params['id'])->delete();

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }


    //添加摄像头链接生成字段
    public static function addCameraFieldList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        //判断字段是否已存在
        $query = CameraFieldList::where('field_name', $params['field_name'])->first();

        if ($query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_ALREADY_EXIST;
            return $result;
        }

        //入库动作
        $res = CameraFieldList::insert(
            [
                'field_name' => $params['field_name'],
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]
        );

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }

    //编辑摄像头链接生成字段
    public static function editCameraFieldList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        //判断字段是否存在
        $query = CameraFieldList::find($params['id']);

        if (!$query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_NOT_EXIST;
            return $result;
        }

        $res = CameraFieldList::where('id', $params['id'])->update(
            [
                'field_name' => $params['field_name'],
                'updated_at' => date('Y-m-d H:i:s'),
            ]
        );

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }

    //删除摄像头链接生成字段
    public static function delCameraFieldList($params)
    {
        $result['status'] = true;
        $result['msg']    = AdminEnum::RETURN_SUCCESS;

        //判断字段是否存在
        $query = CameraFieldList::find($params['id']);

        if (!$query) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::RECORD_NOT_EXIST;
            return $result;
        }

        $res = CameraFieldList::where('id', $params['id'])->delete();

        if (!$res) {
            $result['status'] = false;
            $result['msg']    = AdminEnum::DATABASE_ERROR;
        }

        return $result;
    }

    //根据矿区id获取摄像头列表
    public static function getCameraListByMineId($mine_id)
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;

        $query = CameraList::where('mine_id', $mine_id)->orderBy('sort', 'desc')->select(
            [
                'id as camera_id',
                'mine_id',
                'camera_name'
            ]
        )->get()->toArray();

        $result['data'] = $query;

        return $result;
    }

    //根据摄像头id获取摄像头播放链接
    public static function getCameraUrlByCameraId($camera_id)
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;

        $query = CameraList::where('id', $camera_id)->first();

        if (!$query) {
            $result['status'] = false;
            $result['msg'] = ApiEnum::NO_CAMERA_URL;
            return $result;
        }

        $degree = MineList::where('id', $query->mine_id)->value('degree');

        $mine_list = MineList::whereIn('id', explode('|', $degree))->select(['title'])->get()->toArray();

        $path = '';
        foreach ($mine_list as $key => $val) {
            $path .= '/' . $val['title'];
        }
        $path .= '/' . $query->camera_name . $camera_id;

        //已有拉流id，直接返回拉流链接
        if ($query->revert_id != CameraEnum::CAMERA_DEFAULT_REVERT_ID) {
            $result['data'] = [
                'camera_id' => $camera_id,
                'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME,
            ];

            return $result;
        }

        $data = [
            'url'        => $query->camera_url,
            'customPath' => $path,
        ];

        Log::info('请求流媒体服务器参数------------');
        Log::info($data);

        $curl = env('EASY_DARWIN_URL') . CameraEnum::API_STREAM_START . '?' . http_build_query($data);

        //请求流媒体服务器拉流
        $curl_res = curl_request($curl);

        Log::info('请求流媒体服务器result------------');
        Log::info($curl_res);

        if (strpos($curl_res,' ')) {
            $result['status'] = false;
            $result['msg'] = ApiEnum::EASY_DAWIN_REQUEST_FAIL;
            return $result;
        }

        //更新拉流id
        CameraList::where('id', $camera_id)->update(
            [
                'revert_id'  => trim($curl_res, '"'),
                'updated_at' => date('Y-m-d H:i:s'),
            ]
        );

        $result['data'] = [
            'camera_id' => $camera_id,
            'url' => env('VIDEO_SYSTEM_URL') . CameraEnum::M3U8_FILE_PATH . $path . '/' . date('Ymd', time()) . '/' . CameraEnum::M3U8_FILE_NAME,
        ];

        return $result;
    }

    //停止流媒体推流
    public static function stopCameraStream($camera_id = '')
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;

        $query = CameraList::where('revert_id', '!=', CameraEnum::CAMERA_DEFAULT_REVERT_ID);

        if ($camera_id) {
            $query = $query->where('id', $camera_id);
        }

        $query = $query->get()->toArray();

        if (!$query) {
            $result['status'] = false;
            $result['msg'] = ApiEnum::NO_CAMERA_URL;
            return $result;
        }

        $res_data = [];

        foreach ($query as $key => $val) {
            $data = [
                'id' => $val['revert_id']
            ];

            Log::info('请求流媒体服务器参数------------');
            Log::info($data);

            $curl = env('EASY_DARWIN_URL') . CameraEnum::API_STREAM_STOP . '?' . http_build_query($data);

            //请求流媒体服务器拉流
            $curl_res = curl_request($curl);

            Log::info('请求流媒体服务器result------------');
            Log::info($curl_res);

            if (trim($curl_res, '"') != 'OK') {
                $res_data['error'][] = [
                    'id'        => $val['id'],
                    'revert_id' => $val['revert_id'],
                    'result'    => $curl_res,
                ];
            } else {
                $res_data['success'][] = [
                    'id'        => $val['id'],
                    'revert_id' => $val['revert_id'],
                ];
            }

            //更新拉流id为默认id
            CameraList::where('id', $val['id'])->update(
                [
                    'revert_id'  => CameraEnum::CAMERA_DEFAULT_REVERT_ID,
                    'updated_at' => date('Y-m-d H:i:s'),
                ]
            );
        }

        //递归删除目录
        $dir = public_path() . '/files/video/m3u8/';
        if (is_dir($dir)) {
            deldir($dir);
        }

        $result['data'] = $res_data;

        return $result;
    }

    //查询海康矿井摄像头列表
    public static function getHaiKangCamera($parent_id, $mine_id)
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;
        $result['data']   = [];

        $query = MineListExt::where('mine_id', $parent_id)->first();

        $list = [];

        Input::replace(
            [
                'url'       => trim($query->ip, '/') . ':' . $query->port,
                'key'       => $query->key,
                'secret'    => $query->secret,
                'indexCode' => $mine_id,
            ]
        );
        $haikang   = new HaiKangController();
        $result_hk = $haikang->getCamerasList();
        if ($result_hk['data']['list']) {
            foreach ($result_hk['data']['list'] as $key => $val) {
                $list[$key]['mine_id']     = $mine_id;
                $list[$key]['camera_id']   = $val['cameraIndexCode'];
                $list[$key]['camera_name'] = $val['cameraName'];
            }
        }

        $result['data'] = $list;

        return $result;
    }

    //查询海康矿井摄像头播放链接
    public static function getHaiKangCameraUrl($parent_id, $camera_id)
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;
        $result['data']   = [];

        $query = MineListExt::where('mine_id', $parent_id)->first();

        $slug  = MineList::where('id', $parent_id)->value('slug');
        $count = strpos($slug, 'MeiKuang');
        if ($count) {
            $slug = substr_replace($slug, '', $count, 8);
        }
        $slug = strtolower($slug);

        Input::replace(
            [
                'url'             => trim($query->ip, '/') . ':' . $query->port,
                'key'             => $query->key,
                'secret'          => $query->secret,
                'cameraIndexCode' => $camera_id,
            ]
        );
        $haikang   = new HaiKangController();
        $result_hk = $haikang->getCamerasUrl();
        if ($result_hk['data']['url']) {
            $url = CameraEnum::VIDEO_AGENCY_URL . $slug . '/video/' . strstr($result_hk['data']['url'], 'openUrl');
            $result['data']['camera_id'] = $camera_id;
            $result['data']['url']       = $url;
        }

        return $result;
    }

    //查询海康矿井摄像头列表
    public static function getHaiKangTransCode($parent_id)
    {
        $result['status'] = true;
        $result['msg']    = ApiEnum::RETURN_SUCCESS;
        $result['data']   = [];

        $query = MineListExt::where('mine_id', $parent_id)->first();

        Input::replace(
            [
                'url'       => trim($query->ip, '/') . ':' . $query->port,
                'key'       => $query->key,
                'secret'    => $query->secret,
            ]
        );
        $haikang   = new HaiKangController();
        $result_hk = $haikang->getTranscodeInfo();
        if ($result_hk) {
            $result['data'] = json_decode($result_hk, true);
        }

        return $result;
    }
}