<?php

namespace App\Model;

use App\Exceptions\DatabaseException;
use App\Tool\Constant;
use Carbon\Carbon;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\DB;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
use MongoDB\BSON\UTCDateTime;


class MediaModel extends Eloquent
{
    protected $collection = "media";

    protected $connection = 'mongodb';  //使用mongodb

    protected $primaryKey = '_id';

    protected $fillable = [];

    public $timestamps = false;



    public function media_category()
    {
        return $this->belongsTo('MediaCategoryModel');
    }

    /**
     * 媒资列表
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function mediaList($request){

        try{
            $medias = MediaModel::query()->raw(function ($collection) use($request){


                $limit = (isset($request->page_size) ? (int)($request->page_size) : Constant::PAGE_NUMBER) ;

                if ($limit >500){
                    $limit = 500;
                }

                $page = $request->page??1;
                $aggregate = [];
                /**
                 * 默认降序
                 */
                $sort = -1;
                if ($request->sort == 'asc'){
                    $sort = 1;
                }

                if (isset($request->media_id) && !empty($request->media_id)){
                    $aggregate[]['$match']['_id'] = $request->media_id;
                }

                if (isset($request->category_id) && !empty($request->category_id)){
                    $aggregate[]['$match']['media_type_id'] = $request->category_id;
                }

                // status：代表未转码
                $aggregate[]['$match']['status'] = ["\$ne" => '0'];
                $aggregate[]['$match']['media_url'] = ["\$ne" => 'null'];

//                $aggregate[]['$match']['_id'] = 'mda-864371b9a82d1e21';

                if (isset($request->media_name) && !empty($request->media_name)){
                    $aggregate[]['$match']['media_name'] = ['$regex' => addslashes($request->media_name) ];
                }

                if (isset($request->username) && !empty($request->username)){
                    $aggregate[]['$match']['username'] = ['$regex' => addslashes($request->username) ];
                }

                if (isset($request->description) && !empty($request->description)){
                    $aggregate[]['$match']['description'] = ['$regex' => $request->description ];
                }

                if (isset($request->start_time)&& !empty($request->start_time)){
                    $start_time =  new UTCDateTime(strtotime($request->start_time) * 1000);
                    $aggregate[]['$match']['start_time'] = ['$gt' => $start_time ];
                }

                if (isset($request->end_time)&& !empty($request->end_time)){
                    $end_time =  new UTCDateTime(strtotime($request->end_time) * 1000);;
                    $aggregate[]['$match']['end_time'] = ['$lt' => $end_time ];
                }

                $aggregate1 = $aggregate;

                $aggregate[]['$sort'] = ['start_time'  => $sort];

                $aggregate1[]['$group'] = [
                    '_id' => array(),//更具性别进行分组
                    'count'=>array('$sum'=>1)
                ];

                $count = $collection->aggregate($aggregate1)->toArray();

                if (isset($count[0])){
                    $count = $count[0]['count'];
                }else{
                    $count = 0;
                }

                $skip = ((empty($request->page)   ? 1 : $request->page)-1) * $limit;

                $aggregate[]['$skip'] = $skip;
                $aggregate[]['$limit'] = $limit;

                $tmp_arr = $collection->aggregate($aggregate)->toArray();

                $tmp_arr = collect($tmp_arr);

                /**
                 * 将mongoDate 转化为普通时间
                 */
                foreach ($tmp_arr as $media){

                    $tz = new \DateTimeZone("Asia/Shanghai");
                    if (is_object($media['start_time'])){

                        $start_time = $media['start_time']->toDateTime();
                        $start_time->setTimezone($tz);
                        $start_time = $start_time->format("Y-m-d H:i:s");

                        $media['start_time'] = $start_time;
                    }

                    if (is_object($media['end_time'])){
                        $end_time = $media['end_time']->toDateTime();
                        $end_time->setTimezone($tz);
                        $media['end_time'] = $end_time->format('Y-m-d H:i:s');
                    }
                    if (is_object($media['create_time'])){
                        $create_time = $media['create_time']->toDateTime();
                        $create_time->setTimezone($tz);
                        $media['create_time'] = $create_time->format('Y-m-d H:i:s');
                    }
                }

                return new LengthAwarePaginator($tmp_arr, $count, $limit, $page,[
                    'path' => Paginator::resolveCurrentPath(),
                    'pageName' => 'page',
                ]);


            });

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }


        return $medias;
    }

    /**
     * 存储媒资数据
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function hookRestoreMedia($request,$category = "media"){

        try{

            /**
             * 判断媒资ID是否存在
             */
            $media_id = $request->media_id;
            $media_type = $request->media_type;

            $mediaCatg = MediaCategoryModel::where('_id',$media_type)->first();
            if (empty($mediaCatg)){
                throw new \Exception("媒资类别不存在");
            }


            if ($request->replace){
                $recycleId = RecycleModel::addRecycle($media_id);
                $call_back = $mediaCatg['call_back'];


                $url = getRbac($request,$call_back,$mediaCatg['media_category_id'] ,$type='clear_cache');

                http_request_code($url,null,'POST',['mediaId'=>$media_id]);

                self::updatehookMedia($request,$media_id);


                if (!$recycleId){
                    throw new \Exception('回收站保存失败');
                }
                return $media_id;
            }else{

                $media = MediaModel::where("_id",$media_id)->first();

                if (!empty($media)){
                    throw new \Exception("媒资编号已被使用");
                }
            }

            //hb15011&河北公务员考试试题
            /**
             * 媒资名称是由课程编号与课程名称组成
             */
            $media_info = explode("&",$request->media_name);

            $media_url = $request->media_url;

            $media_url = str_replace("http:","https:",$media_url);


            /**
             * 构造开始时间，结束时间
             */
            $start_time =  new UTCDateTime(strtotime($request->start_time) * 1000);
            $end_time =  new UTCDateTime(strtotime($request->end_time) * 1000);
            $create_time = new UTCDateTime(time() * 1000);;

//            $start_time = $request->start_time;
//            $end_time = $request->end_time;
//            $create_time = date('Y-m-d H:i:s',time());



//            if ($request->shop_id=='100'){
//                $mediaCatg = MediaCategoryModel::where('_id','5f3d073a033f5a336b2b4346')->first();
//            }


            /**
             * 处理文件名称，确认是否包含"&"符合
             */
            if (count($media_info)>=2){

                $data = [
                    '_id'           => $media_id,
                    'media_name'    => $request->media_name,
                    'media_type_id' => $mediaCatg['_id'],
                    'media_type'    => $mediaCatg['name'],
                    'book_num'      => $media_info[0],
                    'book_name'     => $media_info[1],
                    'media_url'     => $media_url,
                    'access_key'    => $request->access_key,
                    'secret_key'    => $request->secret_key,
                    'create_time'   => $create_time,
                    'description'   => $request->description,
                    'username'      => $request->token_username,//员工工号
                    'user_id'       => $request->token_user_id,
                    'start_time'    => $start_time,
                    'end_time'      => $end_time,
                    'duration'      => $request->duration??"0"
                ];

            }else{

                $data = [
                    '_id'           => $media_id,
                    'media_name'    => $request->media_name,
                    'media_type_id' => $mediaCatg['_id'],
                    'media_type'    => $mediaCatg['name'],
                    'book_num'      => '',
                    'book_name'     => $request->media_name,
                    'media_url'     => $media_url,
                    'access_key'    => $request->access_key,
                    'secret_key'    => $request->secret_key,
                    'create_time'   => $create_time,
                    'description'   => $request->description,
                    'username'      => $request->token_username,//员工工号
                    'user_id'       => $request->token_user_id,
                    'start_time'    => $start_time,
                    'end_time'      => $end_time,
                    'duration'      => $request->duration??"0"
                ];
            }


            $id = MediaModel::insertGetId($data);

            LogModel::addlog(["添加媒资信息"=> $data,['媒资ID为：=> '.$id]]);
        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $id;
    }

    /**
     * 更新媒资信息
     * @param $request
     * @param $id
     * @return mixed
     * @throws DatabaseException
     */
    public static function updatehookMedia($request,$id){

        try{

            $media = MediaModel::find($id);
            if (empty($media)){
                throw new \Exception("媒资不存在");
            }

            //hb15011&河北公务员考试试题
            /**
             * 媒资名称是由课程编号与课程名称组成
             */
            $media_info = explode("&",$request->media_name);

            $mediaCatg = MediaCategoryModel::where('_id',$request->media_type)->first();
            if (empty($mediaCatg)){
                throw new \Exception("媒资类别不存在");
            }

            $start_time =  new UTCDateTime(strtotime($request->start_time) * 1000);
            $end_time =  new UTCDateTime(strtotime($request->end_time) * 1000);


            /**
             * 处理文件名称，确认是否包含"&"符合
             */
            if (count($media_info)>=2){

                $data = [
//                    '_id'           => $id,
                    'media_name'    => $request->media_name,
                    'media_type'    => $mediaCatg['name'],
                    'media_type_id' => $mediaCatg['_id'],
                    'book_num'      => $media_info[0],
                    'book_name'     => $media_info[1],
                    'media_url'     => $request->media_url?$request->media_url:$media['media_url'],
//                    'access_key'    => $request->access_key,
                    'secret_key'    => $request->secret_key?$request->secret_key:$media['secret_key'],
//                    'create_time'   => $media['create_time'],
                    'description'   => $request->description,
                    'start_time'    => $request->start_time?$start_time:$media['start_time'],
                    'end_time'      => $request->end_time?$end_time:$media['start_time'],
                    'duration'      => $request->duration??"0",
                ];

            }else{
                $data = [
//                    '_id'           => $id,
                    'media_name'    => $request->media_name,
                    'media_type'    => $mediaCatg['name'],
                    'media_type_id' => $mediaCatg['_id'],
                    'book_num'      => '',
                    'book_name'     => $request->media_name,
                    'media_url'     => $request->media_url?$request->media_url:$media['media_url'],
//                    'access_key'    => $request->access_key,
                    'secret_key'    => $request->secret_key?$request->secret_key:$media['secret_key'],
//                    'create_time'   => date('Y-m-d H:i:s',time()),
                    'description'   => $request->description,
                    'start_time'    => $request->start_time?$start_time:$media['start_time'],
                    'end_time'      => $request->end_time?$end_time:$media['start_time'],
                    'duration'      => $request->duration??"0",
                ];
            }

            $flag = MediaModel::where("_id",$id)->update($data);
            if (!$flag){
                throw new \Exception("更新失败");
            }

            LogModel::addlog(["更新媒资信息=>".$id,$data]);

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $flag;
    }


    /**
     * 获取媒资详情
     * @param $id
     * @return mixed
     * @throws DatabaseException
     */
    public static function getMediaDetail($id){

        try{
            $media = MediaModel::find($id);

            if (empty($media)){
                throw new \Exception('媒资不存在');
            }

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }

        return $media;

    }

    /**
     * 根据课件编号获取媒资编号与视频地址
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function getMediaList($request){

        try{
            /**
             *[{"bookNum":["hb15011","2"],"mediaCatg":"一题一码"}]
             */
            $params = json_decode($request->params,true);

            if (empty($params)){
                throw new \Exception("参数格式有误");
            }
            $tmp = [];
            foreach ($params as $param){

                if (!isset($param['mediaCatg']) || !isset($param['bookNum'])){
                    throw new \Exception("格式有误");
                }

                $media_name= $param['mediaCatg'];
                $media_ids = $param['bookNum'];

                $media_catg = MediaCategoryModel::where('name',trim($media_name))->first();

                if (empty($media_catg)){
                    throw new \Exception("媒资类别不存在");
                }

                $tmp[] = MediaModel::select("_id","book_num","book_name","secret_key","media_url")->where("media_type_id",$media_catg['_id'])->whereIn('book_num',$media_ids)->get();
            }

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }

        $res = [];

        foreach ($tmp as $item){
            $res = $item->groupBy("book_num");
        }

        return $res;
    }

    /**
     * 删除媒资数据
     * @param $id
     * @return int
     * @throws \Exception
     */
    public static function deleteMediaById($request,$id){

        try{
            $media = MediaModel::where('_id',$id)->first();
            if (empty($media)){
                throw new \Exception('媒资不存在！');
            }

//            if (getAdmin()->name != 'offcn'){
//                throw new \Exception("您无权限操作");
//            }


            $session = DB::connection('mongodb')->getMongoClient()->startSession();
            $session->startTransaction();

            $recycleId = RecycleModel::addRecycle($id);

            if (!$recycleId){
                $session->abortTransaction();
                throw new \Exception('回收站保存失败');
            }

            $flag = MediaModel::destroy($id);
            if (!$flag){
                LogModel::addlog(["删除媒资失败"=> $id]);
                $session->abortTransaction();
                throw new \Exception('删除失败');
            }
            $session->commitTransaction();

        }catch (\Exception $exception){

            throw new \Exception($exception->getMessage());

        }
        return $flag;
    }

    /**
     * 获取媒资播放地址
     * @param $media_id
     * @return mixed
     * @throws DatabaseException
     */
    public static function playUrl($media_id){

        try{

            $media = MediaModel::select('media_url','secret_key','duration','media_name','status')->find($media_id);

            if (empty($media)){
                throw new \Exception("媒资不存在");
            }

            if (!isset($media['duration'])){
                $media['duration'] = "0";
            }

            if (!isset($media['status'])){
                $media['status'] = "1";
            }


        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());

        }
        return $media;
    }

    /**
     * 处理异常视频链接
     * @param $request
     * @return \Illuminate\Database\Query\Expression
     * @throws DatabaseException
     */
    public static function handleMediaUrl($request){

        try{
            $medias = MediaModel::query()->raw(function ($collection) use($request){

                $limit = (isset($request->page_size) ? (int)($request->page_size) : Constant::PAGE_NUMBER) ;

                $page = $request->page??1;

                /**
                 * 默认降序
                 */
                $sort = -1;
                if ($request->sort == 'asc'){
                    $sort = 1;
                }

                if (isset($request->media_id) && !empty($request->media_id)){
                    $aggregate[]['$match']['_id'] = $request->media_id;
                }

                $aggregate[]['$match']['media_url'] = ['$regex' => 'qcoenfz67.bkt.clouddn.com' ];

                if (isset($request->username) && !empty($request->username)){
                    $aggregate[]['$match']['username'] = $request->username;
                }

                $aggregate[]['$sort'] = ['start_time'  => $sort];

                $aggregate1=$aggregate;

                $aggregate1[]['$group'] = [
                    '_id' => array(),//更具性别进行分组
                    'count'=>array('$sum'=>1)
                ];

                $count = $collection->aggregate($aggregate1)->toArray();

                if (isset($count[0])){
                    $count = $count[0]['count'];
                }else{
                    $count = 0;
                }
//
                //$count = sizeof($collection->aggregate($aggregate)->toArray());


                $skip = ((empty($request->page)   ? 1 : $request->page)-1) * $limit;

                $aggregate[]['$skip'] = $skip;
                $aggregate[]['$limit'] = $limit;


                return new LengthAwarePaginator($collection->aggregate($aggregate)->toArray(), $count, $limit, $page,[
                    'path' => Paginator::resolveCurrentPath(),
                    'pageName' => 'page',
                ]);


            });



            if (!empty($medias)){


                foreach ($medias as $media){
                    $data = [
                        'media_url'     => "https://vod-mam.eoffcn.com/".$media->_id.'/index.m3u8',
                    ];

                    $flag = MediaModel::where("_id",$media->_id)->update($data);
                    if ($flag==0){
                        throw new \Exception("更新失败");
                    }
                }

            }



        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $medias;

    }

    /**
     * 第三方百度更新status状态
     * @param $request
     * @param $media_id
     * @return mixed
     * @throws DatabaseException
     */
    public static function updateMediaStatus($request,$media_id){
        try{

            $media = MediaModel::where('_id',$media_id)->first();
            if (empty($media)){

                $mediaCatg = MediaCategoryModel::where('_id',$request->media_type)->first();
                if (empty($mediaCatg)){
                    throw new \Exception("媒资类别不存在");
                }

                $create_time = new UTCDateTime(time() * 1000);;

                $data = [
                    '_id'           => $media_id,
                    'media_name'    => $request->media_name??"",
                    'media_type'    => $mediaCatg['name'],
                    'media_type_id' => $mediaCatg['_id'],
                    'media_url'     => $request->media_url??"",
                    'access_key'    => $request->access_key??"",
                    'secret_key'    => $request->secret_key??"",
                    'create_time'   => $create_time,
                    'description'   => $request->description??"",
                    'start_time'    => $create_time,
                    'end_time'      => $create_time,
                    'duration'      => $request->duration??"0",
                    "username"      => "offcn",
                    "mis_uid"       => "admin"
                ];

                $id = MediaModel::insertGetId($data);
                LogModel::addlog(["添加媒资信息"=> $data,['媒资ID为：=> '.$id]]);

                return $id;
            }


            if ($request->status){

                $data = [
                    'media_url'     => $request->media_url??"",
                    'media_name'    => $request->media_name??"",
                    'duration'      => $request->duration??"0",
                    'access_key'    => $request->access_key??"",
                    'secret_key'    => $request->secret_key??"",
                    'status'        => $request->status??''
                ];

                LogModel::addlog(["原media信息为"=>json_encode($media),"更新为"=>json_encode($data)]);
            }else{
                $data['status'] = "0";
            }


//            if ($request->status == 1){
//                LogModel::addlog(["media重新转码"=>json_encode($media)]);
//
//                if ($request->media_secret != $media['secret_key']){
//                    $data['secret_key'] = $request->secret_key;
//                    $data['media_url']  = $request->media_url;
//                }
//            }

            $flag = MediaModel::where("_id",$media_id)->update($data);
            if (!$flag){
                LogModel::addlog("Status更新失败");
                //throw new \Exception("Status更新失败");
            }

            LogModel::addlog(["更新媒资信息Status=>".$media_id,$data]);

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $media_id;

    }

    /**
     * 更新媒资时间
     * @param $request
     * @return \Illuminate\Database\Query\Expression
     * @throws DatabaseException
     */
    public static function updateDatetime($request){

        try{
            $medias = MediaModel::query()->raw(function ($collection) use($request){

                $limit = (isset($request->page_size) ? (int)($request->page_size) : Constant::PAGE_NUMBER) ;

                $page = $request->page??1;

                /**
                 * 默认降序
                 */
                $sort = -1;
                if ($request->sort == 'asc'){
                    $sort = 1;
                }

                if (isset($request->media_id) && !empty($request->media_id)){
                    $aggregate[]['$match']['_id'] = $request->media_id;
                }

                //$aggregate[]['$match']['media_url'] = ['$regex' => 'qcoenfz67.bkt.clouddn.com' ];

//                if (isset($request->username) && !empty($request->username)){
//                    $aggregate[]['$match']['username'] = $request->username;
//                }

//                $aggregate[]['$match']['media_name'] = "test3.mp3";

                $aggregate[]['$sort'] = ['start_time'  => $sort];

                $aggregate1=$aggregate;

                $aggregate1[]['$group'] = [
                    '_id' => array(),//更具性别进行分组
                    'count'=>array('$sum'=>1)
                ];

                $count = $collection->aggregate($aggregate1)->toArray();

                if (isset($count[0])){
                    $count = $count[0]['count'];
                }else{
                    $count = 0;
                }

                //$count = sizeof($collection->aggregate($aggregate)->toArray());

                $skip = ((empty($request->page)   ? 1 : $request->page)-1) * $limit;

                $aggregate[]['$skip'] = $skip;
                $aggregate[]['$limit'] = $limit;


                return new LengthAwarePaginator($collection->aggregate($aggregate)->toArray(), $count, $limit, $page,[
                    'path' => Paginator::resolveCurrentPath(),
                    'pageName' => 'page',
                ]);

            });


            if (!empty($medias)){


                foreach ($medias as $media){

                    /**
                     * 构造开始时间，结束时间
                     */
                    $tmp_medias = MediaModel::where("media_name",$media['media_name'])->count();

                    if ($tmp_medias>1){

                        MediaModel::deleteMediaById($request,$media['_id']);

                        var_dump($tmp_medias);
                    }

                }

            }


        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $medias;

    }

    /**
     * @return string
     * @throws DatabaseException
     */
    public static function getMediaId(){

        try{
            $i = 0;
            do {
                $media_id = "mda-".generateRandomNum(16);
                $media = MediaModel::find($media_id);
                $i ++;
            } while ($i < 3 && !empty($media) );

            if ($i == 3){
                throw new \Exception('获取媒资编号失败');
            }
        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $media_id;
    }

    /**
     * 设置随机码
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function setMediaNum($request){
        try{
            $media_id = $request->media_id;
            $data = [
                'media_num'     => md5(md5($media_id)),
            ];
            $flag = MediaModel::where("_id",$media_id)->update($data);
        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $flag;
    }

    /**
     * 根据媒资编号获取媒资随机码
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function getMediaInfoByNum($request){
        try{
            $media = MediaModel::select('_id','secret_key','duration','media_name','status')->where("media_num",$request->media_num)->first();
            if (empty($media)){
                throw new \Exception("媒资信息不存在");
            }
        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $media;
    }

    /**
     * @param $request
     * @return mixed
     * @throws DatabaseException
     */
    public static function clearCdnCache($request,$media_id){

        try{
            /**
             * 判断媒资ID是否存在
             */
            $media = MediaModel::where("media_num",$request->media_num)->first();
            if (empty($media)){
                throw new \Exception("媒资信息不存在");
            }

            $media_type = $media['media_type_id'];
            $mediaCatg = MediaCategoryModel::where('_id',$media_type)->first();
            if (empty($mediaCatg)){
                throw new \Exception("媒资类别不存在");
            }

            $call_back = $mediaCatg['call_back'];
            $url = getRbac($request,$call_back,$mediaCatg['media_category_id'] ,$type='clear_cache');
            http_request_code($url,null,'POST',['mediaId'=>$media_id]);

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }
        return $media;

    }

    /**
     * 获取永久m3u8地址
     * @param $request
     * @param $media_id
     * @return mixed
     * @throws DatabaseException
     */
    public static function getMediaForeverM3u8($request){

        try{
            $media_id = $request->media_id;
            /**
             * 判断媒资ID是否存在
             */
            $media = MediaModel::where("_id",$media_id)->first();
            if (empty($media)){
                throw new \Exception("媒资信息不存在");
            }

            $media_type = $media['media_type_id'];
            $mediaCatg = MediaCategoryModel::where('_id',$media_type)->first();
            if (empty($mediaCatg)){
                throw new \Exception("媒资类别不存在");
            }

            $url = getRbac($request,'video/info',$media_id ,$type='play_m3u8');

            echo $url;
            $res = http_request_code($url,null,'GET');

            $result = json_decode($res,true);


            if ($result['code'] != 0){
                LogModel::addlog($result);
                throw new \Exception("获取数据失败");
            }

        }catch (\Exception $exception){
            throw new DatabaseException($exception->getMessage());
        }

        return $result['data'];
    }

}
