<?php

namespace App\Http\Controllers;

use App\Http\Resources\PermissionResource;
use App\Http\Requests\UsersRequest;
use App\Http\Resources\UserResource;
use App\Laravue\JsonResponse;
use App\Laravue\Models\Device;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Validator;

class DevicesController extends Controller
{
    //设备列表
    /*
     * 设备类型
     * type 不传默认是第一个
     * @type 设备类型id
     * */
    public function devicelist(Request $request)
    {
        $type = $request->input('type');//设备类型id
        $pagenNum = $request->input('page') - 1;//页数
        $limit = $request->input('limit');
        if ($pagenNum === '' || $limit == '') {
            return $this->jsonErrorData(105, '页数或limit不能为空');
        }
        return $this->jsonSuccessData($this->whertype($type == '' ? '1' : $type, $pagenNum, $limit));
    }

    //用户设备列表
    /*
     * 设备类型
     * type 不传默认是第一个
     * @type 设备类型id
     * */
    public function userdevicelist(Request $request)
    {
        $type = $request->input('type');//设备类型id
        $pagenNum = $request->input('page') - 1;//页数
        $limit = $request->input('limit');
        if ($pagenNum === '' || $limit == '') {
            return $this->jsonErrorData(105, '页数或limit不能为空');
        }
        return $this->jsonSuccessData($this->userdevice($type == '' ? '1' : $type, $pagenNum, $limit));
    }

    /*
     * 删除设备
     * type 1==逻辑删除
     * type 2== 物理删除
     * */
    public function deletedecice(Request $request)
    {
        $type = (int)$request->input('type');
        $deviceid = (int)$request->input('deviceid');//设备id
        if ($type == '' || $deviceid == '') {
            return $this->jsonErrorData(105, '参数不能为空');
        }
        if ($type == 1) {//逻辑删除
            $dete = Device::where('id', '=', $deviceid)
                ->value('delete');
            if ($dete != 1) {
                $this->timeline('设备放到废纸篓[设备id' . $deviceid . ']');
                $update = Device::where('id', '=', $deviceid)
                    ->update(['delete' => 1]);
                return $this->jsonSuccessData($update);
            } else {
                return $this->jsonErrorData(105, '数据异常');
            }

        } else if ($type == 2) {//物理删除
            $dete = Device::where('id', '=', $deviceid)
                ->value('delete');
            if ($dete != 2) {
                $this->timeline('删除了设备');
                $delete = Device::where('id', '=', $deviceid)
                    ->delete();
                return $this->jsonSuccessData($delete);
            } else {
                return $this->jsonErrorData(105, '数据异常');
            }
        }
    }

    //返回逻辑删除的设备和修复设备
    public function physicsdelete(Request $request)
    {
        $deviceid = $request->input('deviceid');
        $databadevice = DB::table('device');
        if ($_POST) {
            $up = $databadevice
                ->where('id', '=', $deviceid)
                ->update(['delete' => 2]);
            return $this->jsonSuccessData($up);
        } else {
            //返回物理删除设备列表
            $type = (int)$request->input('type');//设备类型
            $pagenNum = $request->input('page') - 1;//页数
            $limit = $request->input('limit');//条数
            if ($pagenNum === '' || $limit == '') {
                return $this->jsonErrorData(105, '页数或limit不能为空');
            }
            $devicelist = $databadevice
                ->where('dtype', '=', $type == '' ? '1' : $type)
                ->where('delete', '=', '1')//设备逻辑删除状态
                ->join('device_type as dy', "device.dtype", '=', 'dy.tid')
                ->join('gas as g', "device.status", '=', 'g.id')
                ->select('dy.tname', 'g.gas', 'device.*')
                ->orderBy('device.id', 'desc')
                ->offset($pagenNum)
                ->limit($limit)
                ->get()->toArray();
            return $this->jsonSuccessData($devicelist);
        }

    }

    //添加设备
    public function adddevice(Request $request)
    {
        //验证用户提交表单
        $addDeviceData = $request->all();
        $validator = Validator::make($addDeviceData, $this->getValidationRulesdevice(false));
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 403);
        }
        foreach ($addDeviceData as $k => $v) {
            if ($k == 'isadmin') {
                unset($addDeviceData[$k]);
            }
        }
        $type = new Device();
        $this->timeline($this->isadmin() == 1 ? '管理员添加设备[设备号' . $request->input('devicenum') . ']' : '用户添加设备[设备编号' . $request->input('devicenum') . ']');
        return $this->jsonSuccessData($type->adddevice($addDeviceData, $this->isadmin() == 1 ? 1 : 2));

    }


    //编辑设备
    public function updatedevice(Request $request)
    {
        $deid = $request->input('deid');
        $data = $request->all();
        if (is_null($deid)) {
            return $this->jsonErrorData(105, '设备ID不能为空');
        }
        if ($request->isMethod('post')) {
            $data['dtype'] = $request->input('tid');
            foreach ($data as $k => $v) {
                if ($k == 'deid') {
                    unset($data[$k]);
                }
                if ($k == 'tid') {
                    unset($data[$k]);
                }
                if ($k == 'name') {
                    unset($data[$k]);
                }
                if ($k == 'devicenum') {
                    unset($data[$k]);
                }
            }

            $this->timeline('编辑了设备[设备id' . $deid . ']');
            return $this->jsonSuccessData(Device::where('id', '=', $deid)->update($data));
        } else {
            $devi = DB::table('device as de')
                ->where('de.id', '=', $deid)
                ->leftjoin('device_type as dt', 'de.dtype', '=', 'dt.tid')
                ->leftjoin('gas', 'de.status', '=', 'gas.id')
                ->leftjoin('danwei as da', 'de.devicemonad', '=', 'da.id')
                ->leftjoin('users as ud', 'de.uid', '=', 'ud.id')
                ->select('dt.tid','ud.name', 'de.username','de.deviceremark','de.devicelinkman','de.devicephone','de.deviceinfo','de.devicecoord','de.uid','de.devicenum')
                ->first();
            return $this->jsonSuccessData($devi);
        }
    }

    //返回设备类型和单位和介质
    public function devicetype()
    {
        $gas = DB::table('gas')->get();
        $danwei = DB::table('danwei')->get();
        $devicetypecount = DB::table('device_type as t')
            ->leftjoin('device as d', 'd.dtype', '=', 't.tid')
            ->selectRaw('t.*,count(d.id) as counnum')
            ->groupBy('t.tid')
            ->get();
        return $this->jsonSuccessData(['devicetype' => $devicetypecount, 'gas' => $gas, 'danwei' => $danwei]);
    }

    //返回设备列表
    private function whertype($type, $pagenNum, $limit): array
    {
        $databadevice = DB::table('device');
        $devicelist = $databadevice
            ->where('dtype', '=', $type)
            ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
            ->leftjoin('gas as g', "device.status", '=', 'g.id')
            ->leftjoin('users as u', "device.uid", '=', 'u.id')
            ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
            ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name', 'u.name as usernickname')
            ->orderBy('device.id', 'desc')
            ->offset($pagenNum)
            ->limit($limit)
            ->get()->toArray();
        $count = $databadevice
            ->where('dtype', '=', $type)
            ->count();
        return ['devicelist' => $devicelist, 'count' => $count];
    }

    //返回用户设备列表
    private function userdevice($type, $pagenNum, $limit): array
    {
        $databadevice = DB::table('device');
        $devicelist = $databadevice
            ->where('dtype', '=', $type)
            ->where('uid', '=', Auth::id())
            ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
            ->leftjoin('gas as g', "device.status", '=', 'g.id')
            ->leftjoin('users as u', "device.uid", '=', 'u.id')
            ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
            ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name', 'u.name as usernickname')
            ->orderBy('device.id', 'desc')
            ->offset($pagenNum)
            ->limit($limit)
            ->get()->toArray();
        $count = $databadevice
            ->where('dtype', '=', $type)
            ->where('uid', '=', Auth::id())
            ->count();
        return ['devicelist' => $devicelist, 'count' => $count];
    }

    private function deviceDataSearchData($devicenum, $pagenNum, $limit, $isuser): array
    {
        $databadevice = DB::table('device');
        if ($isuser != '') {
            $devicelist = $databadevice
                ->where('devicenum', '=', $devicenum)
                ->where('uid', '=', Auth::id())
                ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
                ->leftjoin('gas as g', "device.status", '=', 'g.id')
                ->leftjoin('users as u', "device.uid", '=', 'u.id')
                ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
                ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name', 'u.name as usernickname')
                ->orderBy('device.id', 'desc')
                ->offset($pagenNum)
                ->limit($limit)
                ->get()->toArray();
            $count = $databadevice
                ->where('dtype', '=', $devicenum)
                ->where('uid', '=', Auth::id())
                ->count();
            return ['devicelist' => $devicelist, 'count' => $count];
        } else {
            $devicelist = $databadevice
                ->where('devicenum', '=', $devicenum)
                ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
                ->leftjoin('gas as g', "device.status", '=', 'g.id')
                ->leftjoin('users as u', "device.uid", '=', 'u.id')
                ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
                ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name', 'u.name as usernickname')
                ->orderBy('device.id', 'desc')
                ->offset($pagenNum)
                ->limit($limit)
                ->get()->toArray();
            $count = $databadevice
                ->where('dtype', '=', $devicenum)
                ->count();
            return ['devicelist' => $devicelist, 'count' => $count];
        }
    }

    //批量上传设备
    public function batchdevice()
    {
    }

    //获取设备详情信息
    public function deviceDataInfo($id)
    {
        $devicedata = Device::where('device.id', '=', $id)
            ->leftjoin('contactsuser as c', 'c.contactsid', '=', 'device.id')
            ->select('c.*', 'device.deviceuuid', 'device.devicelinkman', 'device.devicephone', 'device.devicecoord')
            ->get();
        $devicedatainfo = Device::where('id', '=', $id)
            ->select('deviceuuid', 'devicelinkman', 'devicephone', 'devicecoord')
            ->get();
        return $this->jsonSuccessData(['devicedata' => $devicedata, 'devicedatainfo' => $devicedatainfo]);
    }

//    返回设备地图详情信息
    public function device_info($id)
    {
        $devicedata = Device::where('device.id', '=', $id)
            ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
            ->leftjoin('gas as g', "device.status", '=', 'g.id')
            ->leftjoin('users as u', "device.uid", '=', 'u.id')
            ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
            ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name', 'u.name as usernickname')
            ->first();
        return $this->jsonSuccessData($devicedata);
    }

    //搜索设备账号
    public function deviceDataSearch(Request $request)
    {
        $data = $request->input('deviceName');
        $pagenNum = $request->input('page') - 1;//页数
        $limit = $request->input('limit');
        $isuser = $request->input('isuser');
        if ($pagenNum === '' || $limit == '' || $data == '') {
            return $this->jsonErrorData(105, '请求参数不能为空');
        }
        return $this->jsonSuccessData($this->deviceDataSearchData($data, $pagenNum, $limit, $isuser == '' ? '' : $isuser));
    }

    //推送获取数据监测数据
    public function equipment()
    {
        /*
         * 将写入文件改为时序数据库!
         * */
        $dalen = Redis::llen('Devicesdata');//返回队列长度
        $data = [];
        if ($dalen > 0) {
            for ($i = 0; $i < $dalen; $i++) {
                array_push($data, unserialize(Redis::lpop('Devicesdata')));
            }
        }
        if ($data != []) {
            $this->devicemkdir($data); //写入文件
        }
        $devicelistopen = $this->devicelistopen();
        if ($devicelistopen != 105) {
            return $this->jsonSuccessData($devicelistopen);
        } else {
            return $this->jsonErrorData(105, '暂无数据');
        }

    }

    //历史数据查询
    public function detedevice(Request $request)
    {
        $dete = $request->input('dete');
        $devicetime = $this->devicetime($dete);
        if ($devicetime != 105) {
            return $this->jsonSuccessData($devicetime);
        } else {
            return $this->jsonErrorData(105, '暂无数据');
        }
    }


    //返回设备当前报警
    public function police()
    {
        $data = DB::table('reportpolice as r')
            ->join('status as s', 'r.policestatus', '=', 's.id')
            ->select('r.*', 's.status_name')
            ->get();
        return $this->jsonSuccessData($data);

    }

    //返回设备废纸篓数量
    public function deviceBasket()
    {
        if (!is_null($this->isadmin())) {
            return $this->jsonSuccessData(DB::table('device')->where('delete', '=', '1')->count());
        } else {
            return $this->jsonSuccessData(DB::table('device')->where('delete', '=', '1')->where('uid', '=', Auth::id())->count());
        }
    }

    public function addUserDevice()
    {
        return $this->jsonSuccessData(DB::table('users')->where('state', '=', '2')->select('name', 'id')->get());
    }

    //返回设备废纸篓和禁用设备
    public function deviceBasketList()
    {
        if (!is_null($this->isadmin())) {
            $paper = DB::table('device')->where('delete', '=', '1')->get()->toArray();
            return $this->jsonSuccessData($paper);
        } else {
            $paper = DB::table('device')->where('delete', '=', '1')->where('uid', '=', Auth::id())->get()->toArray();
            return $this->jsonSuccessData($paper);
        }

    }

    public function deviceDelete(Request $request)
    {
        $id = $request->input('id');
        $type = $request->input('type');
        if ($type == 1) {//丢弃废纸篓
            $this->timeline('设备放到废纸篓[设备id' . $id . ']');
                return $this->jsonSuccessData(DB::table('device')->where('id', '=', $id)->update(['delete' => 1, 'devicestatus' => 6, 'devicedeleteinfo' => $this->isadmin() == 1 ? '管理员将设备放置废纸篓' : '用户将设备放置废纸篓']));
        } else {
            $this->timeline('删除了设备');
            return $this->jsonSuccessData(DB::table('device')->where('id', '=', $id)->delete());
        }
    }

    public function UpPaperBasket($id)
    {
        return $this->jsonSuccessData(DB::table('device')->where('id', '=', $id)->update(['delete' => 2, 'devicestatus' => 1, 'devicedeleteinfo' => '']));

    }

    public function addClassify($data)
    {
        //添加分类
        $this->timeline('添加了分类[分类名称' . $data . ']');
        return $this->jsonSuccessData(DB::table('device_type')->insertGetId(['tname' => $data]));
    }
    public function delteClassify($id)
    {
        //删除分类
        $this->timeline('删除了分类!');
        return $this->jsonSuccessData(DB::table('device_type')->where('tid', '=', $id)->delete());
    }

    public function deviceLocation(Request $request)
    {
        if ($this->isadmin() == 1) {
            $where = [];
            if ($request->has('uid')) {
                $user_id = $request->get('uid');
                $where['uid'] = $user_id;
            }
            $data = DB::table('device')
                ->select('id', 'uid', 'nd', 'deviceinfo', 'devicenum', 'devicecoord', 'devicepolice', 'deviceremark', 'devicelinkman')
                ->where($where)
                ->get();
        } else {
            $data = DB::table('device')
                ->select('id', 'uid', 'nd', 'deviceinfo', 'devicenum', 'devicecoord', 'devicepolice', 'deviceremark', 'devicelinkman')
                ->where('uid','=',Auth::id())
                ->get();
        }

        //返回用户安装位置
        return $this->jsonSuccessData($data);
    }

    //返回消防监测
    public function control(Request $request)
    {
        $pagenNum = $request->input('page') - 1;//页数
        $limit = $request->input('limit');
        $type = $request->input('type');
        if ($pagenNum === '' || $limit == '' || $type === '') {
            return $this->jsonErrorData(105, '页数或limit不能为空');
        }
        if ($type == 1) {//返回消防监测
            $wherein = [2, 4, 6, 7, 8, 9, 11];
        } else {
            //返回危化
            $wherein = [1, 5, 10];
        }
        $databadevice = DB::table('device');
        $devicelist = $databadevice
            ->whereIn('dtype', $wherein)
            ->leftjoin('device_type as dy', "device.dtype", '=', 'dy.tid')
            ->leftjoin('gas as g', "device.status", '=', 'g.id')
            ->leftjoin('status as p', "device.devicepolice", '=', 'p.id')
            ->select('dy.tname', 'g.gas', 'device.*', 'p.status_name')
            ->orderBy('device.id', 'desc')
            ->offset($pagenNum)
            ->limit($limit)
            ->get()->toArray();
        $count = $databadevice
            ->whereIn('dtype', $wherein)
            ->count();
        return $this->jsonSuccessData(['devicelist' => $devicelist, 'count' => $count]);
    }
    public function devicepolice(Request $request)
    {
        $devicenum = $request->input('devicenum');
        if ($devicenum) {
           $police = DB::table('reportpolice')->where('devicenumber','=',$devicenum)->update(['police'=>2]);
           $this->jsonSuccessData($police);
        }else{
            return $this->jsonErrorData(105,'设备编号不能为空');
        }
    }
    public function devicepoliceinfo(Request $request){
        $devicenum = $request->input('devicenum');
        if ($devicenum) {
            $data = DB::table('device as d')
                ->join('device_type as t','d.dtype','=','t.tid')
                ->join('gas as g','d.status','=','g.id')
                ->join('status as s','d.devicepolice','=','s.id')
                ->join('danwei as w','d.devicemonad','=','w.id')
                ->join('users as u','d.uid','=','u.id')
                ->join('reportpolice as r','d.devicenum','=','r.devicenumber')
                ->where('d.devicenum','=',$devicenum)
                ->select('d.devicenum','d.username','d.nd','d.deviceremark','d.devicecoord','d.deviceaddtime','d.devicestatus','t.tname','g.gas','s.status_name','w.danwei','u.name','u.email','r.location','r.concentration','r.starttime')
                ->first();
            return $this->jsonSuccessData($data);
        }else{
            return $this->jsonErrorData(105,'设备编号不能为空');
        }
    }
    /**
     * @param bool $isNew
     * @return array
     * 用户添加设备表单验证
     */
    private function getValidationRulesdevice($isNew = true)
    {
        return [
            'devicenum' => 'required|between:2,25|unique:device,devicenum',//设备编号
            'username' => 'required|unique:device,username|max:40',//设备名称
            'devicephone' => 'sometimes|required|regex:/^1[3465789]\d{9}$/|max:11',//联系人手机号
            'devicelinkman' => 'sometimes|required|max:15',
            'dtype' => 'required',
            'status' => 'required',
            'devicemonad' => 'required',
            'deviceremark' => 'sometimes|required|max:15',
            'devicecoord' => 'sometimes|required',
            'contactsid' => 'sometimes|required',//绑定联系人id
            'deviceinfo' => 'sometimes|required',
            'devicenumber' => 'sometimes|required|unique:device,devicenumber|max:40'
        ];
    }

    //更新设备列表
    private function getValidationRulesupdevice($isNew = true)
    {
        return [
            'username' => 'sometimes|required|unique:device,username|max:40',//设备名称
            'devicephone' => 'sometimes|required|regex:/^1[3465789]\d{9}$/|max:11',//联系人手机号
            'devicelinkman' => 'sometimes|required|max:15',
            'dtype' => 'sometimes|required',
            'status' => 'sometimes|required',
            'devicemonad' => 'sometimes|required',
            'deviceremark' => 'sometimes|required|max:15',//备注
            'devicecoord' => 'sometimes|required',
            'contactsid' => 'sometimes|required',//绑定联系人id
            'deviceinfo' => 'sometimes|required',
            'devicenumber' => 'sometimes|required|unique:device,devicenumber|max:40'
        ];
    }

    private function devicemkdir($data)
    {
        $path = public_path() . '/device/' . date('Y-m-d' . '/');
        if (!is_dir($path)) {
            mkdir($path);
        }
        file_put_contents($path . "devicelistdata.text", json_encode($data) . PHP_EOL, FILE_APPEND);

        $this->devicelistopen($path);
    }

    private function devicelistopen(): array
    {
        $path = public_path() . '/device/' . date('Y-m-d' . '/');
        if (is_file($path . 'devicelistdata.text')) {
            $myfile = file_get_contents($path . 'devicelistdata.text');
            $exp = explode("\n", $myfile);
            $datadevice = [];
            foreach (array_filter($exp) as $key => $vel) {
                $newstring = str_replace('[', '', $vel);
                $newstring1 = str_replace(']', '', $newstring);
                array_push($datadevice, json_decode($newstring1, true));
            }
            return $datadevice;
        } else {
            return 105;
        }
    }

    private function devicetime($dete)
    {
        $path = public_path() . '/device/' . $dete . '/';
        if (is_file($path . 'devicelistdata.text')) {
            $myfile = file_get_contents($path . 'devicelistdata.text');
            $exp = explode("\n", $myfile);
            $datadevice = [];
            foreach (array_filter($exp) as $key => $vel) {
                $newstring = str_replace('[', '', $vel);
                $newstring1 = str_replace(']', '', $newstring);
                array_push($datadevice, json_decode($newstring1, true));
            }
            return $datadevice;
        } else {
            return 105;
        }
    }
}