<?php
/**
 * File UserController.php
 *
 * @author Tuan Duong <bacduong@gmail.com>
 * @package Laravue
 * @version 1.0
 */

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\Permission;
use App\Laravue\Models\Role;
use App\Laravue\Models\User;
use App\Laravue\Models\Users;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Env;
use Illuminate\Support\Facades\Hash;
use Validator;

/**
 * Class UserController
 *
 * @package App\Http\Controllers
 */
class UserController extends Controller
{
    const ITEM_PER_PAGE = 15;

    /**
     * Display a listing of the user resource.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response|ResourceCollection
     */
    public function index(Request $request)
    {
        $searchParams = $request->all();
        $userQuery = User::query();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $role = Arr::get($searchParams, 'role', '');
        $keyword = Arr::get($searchParams, 'keyword', '');

        if (!empty($role)) {
            $userQuery->whereHas('roles', function ($q) use ($role) {
                $q->where('name', $role);
            });
        }

        if (!empty($keyword)) {
            $userQuery->where('name', 'LIKE', '%' . $keyword . '%');
            $userQuery->where('email', 'LIKE', '%' . $keyword . '%');
        }

        return UserResource::collection($userQuery->paginate($limit));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            array_merge(
                $this->getValidationRules(),
                [
                    'password' => ['required', 'min:6'],
                    'confirmPassword' => 'same:password',
                ]
            )
        );

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 403);
        } else {
            $params = $request->all();
            $user = User::create([
                'name' => $params['name'],
                'email' => $params['email'],
                'password' => Hash::make($params['password']),
                'username' => $params['username'],
                'title' => $params['title'],
                'company' => $params['company'],
                'mapcenter' => $params['mapcenter'],
                'provinceid' => $params['province'],
                'areaid' => $params['area'],
                'cityid' => $params['city'],
                'isadmin' => 2,
            ]);
            $this->timeline('新增了用户!');
            $role = Role::findByName($params['role']);
            $user->syncRoles($role);

            return new UserResource($user);
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  User $user
     * @return UserResource|\Illuminate\Http\JsonResponse
     */
    public function show(User $user)
    {
        return new UserResource($user);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param User $user
     * @return UserResource|\Illuminate\Http\JsonResponse
     */
    public function update(Request $request, User $user)
    {
        if ($user === null) {
            return response()->json(['error' => 'User not found'], 404);
        }
        if ($user->isAdmin()) {
            return response()->json(['error' => 'Admin can not be modified'], 403);
        }

        $validator = Validator::make($request->all(), $this->getValidationRules(false));
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 403);
        } else {
            $email = $request->get('email');
            $found = User::where('email', $email)->first();
            if ($found && $found->id !== $user->id) {
                return response()->json(['error' => 'Email has been taken'], 403);
            }

            $user->name = $request->get('name');
            $user->email = $email;
            $user->save();
            return new UserResource($user);
        }
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param User $user
     * @return UserResource|\Illuminate\Http\JsonResponse
     */
    public function updatePermissions(Request $request, User $user)
    {
        if ($user === null) {
            return response()->json(['error' => 'User not found'], 404);
        }

        if ($user->isAdmin()) {
            return response()->json(['error' => 'Admin can not be modified'], 403);
        }

        $permissionIds = $request->get('permissions', []);
        $rolePermissionIds = array_map(
            function ($permission) {
                return $permission['id'];
            },

            $user->getPermissionsViaRoles()->toArray()
        );

        $newPermissionIds = array_diff($permissionIds, $rolePermissionIds);
        $permissions = Permission::allowed()->whereIn('id', $newPermissionIds)->get();
        $user->syncPermissions($permissions);
        return new UserResource($user);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  User $user
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        if ($user->isAdmin()) {
            response()->json(['error' => 'Ehhh! Can not delete admin user'], 403);
        }

        try {
            $user->delete();
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    /**
     * Get permissions from role
     *
     * @param User $user
     * @return array|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public function permissions(User $user)
    {
        try {
            return new JsonResponse([
                'user' => PermissionResource::collection($user->getDirectPermissions()),
                'role' => PermissionResource::collection($user->getPermissionsViaRoles()),
            ]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }
    }

    /**
     * @param bool $isNew
     * @return array
     */
    private function getValidationRules($isNew = true)
    {
        return [
            'name' => 'required',
            'email' => $isNew ? 'required|email|unique:users' : 'required|email',
            'roles' => [
                'required',
                'array'
            ],
        ];
    }

    /**
     * @param bool $isNew
     * @return array
     */
    private function getValidationRulescontacts($isNew = true)
    {
        return [
            'contacts_name' => 'required|max:3',
            'contacts_phone' => 'required|regex:/^1[3465789]\d{9}$/|max:11|unique:contactsuser,contacts_phone'
        ];
    }

    /**
     * @param bool $isNew
     * @return array
     * 用户提交表单验证
     */
    private function getValidationRulesuser($isNew = true)
    {
        return [
            'email' => $isNew ? 'required|email|unique:users' : 'required|email',
            'username' => 'required|between:2,25|regex:/^[A-Za-z0-9\-\_]+$/|unique:users,username',
            'password' => 'sometimes|required|string|min:6',
            'nickname' => 'required|between:2,25|regex:/^[A-Za-z0-9\-\_]+$/|unique:users,name'
        ];
    }

//    后台管理用户列表
    public function HUserList(Request $request)
    {
        $limit = $request->input('limit');
        $pagenNum = $limit * ($request->input('page') - 1);//页数
        if (is_null($pagenNum)) {
            return $this->jsonErrorData(105, 'page不能为空');
        }
        if (is_null($limit)) {
            return $this->jsonErrorData(105, 'limit不能为空');
        }
        $users = DB::table('users as b')
            ->leftjoin('areachina as p', 'b.provinceid', '=', 'p.areaid')
            ->leftjoin('areachina as c', 'b.cityid', '=', 'c.areaid')
            ->leftjoin('areachina as a', 'b.areaid', '=', 'a.areaid')
            ->leftJoin('user_roles AS ur', 'b.user_role_id', '=', 'ur.id')
            ->orderBy('b.id', 'desc')
            ->select(
                'b.username',
                'b.id',
                'b.created_at',
                'b.name',
                'b.email',
                'b.state',
                'b.phone_number',
                'ur.name AS role_name',
                'a.area_name as area',
                'c.area_name as city',
                'p.area_name as province'
            )
            ->offset($pagenNum)
            ->limit($limit)
            ->get();
        $count = DB::table('users')
            ->count();
        $davicenum = DB::table('users')
            ->select('id')
            ->get()->toArray();
        $data = [];
        foreach (array_column($davicenum, 'id') as $k => $value) {
            $countdevice_type = DB::table('device')
                ->where('uid', '=', $value)
                ->count();
            $usernum['count'] = $countdevice_type;
            $usernum['id'] = $value;
            array_push($data, $usernum);
        }
        $data = ['users' => $users, 'count' => $count, 'davicenum' => $data];
        if ($users) {
            return $this->jsonSuccessData($data);
        } else {
            return $this->jsonErrorData(105, '获取失败');
        }
    }

    //用户搜索
    public function userSeek(Request $request)
    {
        $keys = $request->all();
        $handle = DB::table('users as b');
        foreach ($keys as $key => $val) {
            if ($key == 'page') {
                unset($keys[$key]);
            } elseif ($key == 'limit') {
                unset($keys[$key]);
            }
        }
        foreach ($keys as $k => $v) {
            if ($v == '正常') {
                $v = 2;
            } else if ($v == '禁用') {
                $v = 3;
            } else if ($v == '已删除') {
                $v = 1;
            }
            $keys[$key] && $handle->where('b.' . $k, 'like', '%' . $v . '%');
        }
        $datas = $handle
            ->leftjoin('areachina as p', 'b.provinceid', '=', 'p.areaid')
            ->leftjoin('areachina as c', 'b.cityid', '=', 'c.areaid')
            ->leftjoin('areachina as a', 'b.areaid', '=', 'a.areaid')
            ->orderBy('b.id', 'desc')
            ->select('b.username', 'b.id', 'b.created_at', 'b.name', 'b.email', 'b.state', 'a.area_name as area', 'c.area_name as city', 'p.area_name as province')
            ->get();
        $davicenum = DB::table('users')
            ->select('id')
            ->get()->toArray();
        $data = [];
        foreach (array_column($davicenum, 'id') as $k => $value) {
            $countdevice_type = DB::table('device')
                ->where('uid', '=', $value)
                ->count();
            $usernum['count'] = $countdevice_type;
            $usernum['id'] = $value;
            array_push($data, $usernum);
        }
        $cont = $handle->count();
        $data = ['users' => $datas, 'count' => $cont, 'davicenum' => $data];
        return $this->jsonSuccessData($data);
    }

    //新增用户
    public function addUser(Request $request)
    {
        $userdata = $request->all();
        //获取用户列表
        $validator = Validator::make($request->all(), $this->getValidationRulesuser(false));
        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 403);
        } else {
            $type = new Users();
            $this->timeline('新增了用户!');
            $arr = $type->getTypeAlldeleteuserToArray($userdata);
            return $this->jsonSuccessData($arr);
        }
    }

    /*
     * 删除用户
     * type
     * 1 == 逻辑删除用户
     * 2  == 物理删除用户
     * duserid 删除用户的id
     * */
    public function deleteuser(Request $request)
    {
        $type = (int)$request->input('type');
        $duserid = (int)$request->input('duserid');
        if ($type == '') {
            return $this->jsonErrorData(105, 'type参数不能为空');
        }
        if ($duserid == '') {
            return $this->jsonErrorData(105, 'duserid参数不能为空');
        }
        if ($type == 1) { // 逻辑删除
            $this->timeline('将用户放到废纸篓[id' . $duserid . ']');
            $users = Users::where('id', '=', $duserid)
                ->update(['state' => 3]);
            if ($users) {
                return $this->jsonSuccessData($users);
            } else {
                return $this->jsonErrorData(105, '用户操作数据失败');
            }
        } else if ($type == 2) {
            $this->timeline('删除了设备');
            $users = Users::where('id', '=', $duserid)
                ->delete();
            if ($users) {
                return $this->jsonSuccessData($users);
            } else {
                return $this->jsonErrorData(105, '获取用户数据失败');
            }
        }
    }

    //更新用户
    public function Upuser(Request $request)
    {
        if ($request->isMethod('post')) {
            $userdata = $request->all();
            $uid = $userdata['userid'];
            if (!isset($userdata['userid']) || $userdata['userid'] == '') {
                return $this->jsonErrorData(105, '用户id不能为空');
            }
            foreach ($userdata as $k => $v) {
                if ($k == 'userid') {
                    unset($userdata[$k]);
                }
            }
            $re = Users::where('id', '=', (int)$uid)->update($userdata);
            if ($re !== false) {
                return $this->jsonSuccessData($re);
            } else {
                return $this->jsonErrorData(105, '更新失败');
            }
        } else {
//            获取用户数据
            $userid = (int)$request->input('userid');
            if ($userid == '') {
                return $this->jsonErrorData(105, '用户id不能为空');
            }
            $userdata = Users::where('id', '=', $userid)
                ->select('username', 'name', 'email', 'title', 'company', 'mapcenter', 'phone_number', 'user_role_id')
                ->first();
            if ($userdata) {
                return $this->jsonSuccessData($userdata);
            } else {
                return $this->jsonErrorData(105, '获取数据失败');
            }
        }
    }

    //返回地址列表
    public function areachina(Request $request)
    {
        if ($request->isMethod('post')) {
            $areaid = $request->input('areaid');
            if ($areaid == '') {
                return $this->jsonErrorData('105', '地区id不能为空');
            }
            $area =  Db::table('areachina')->where('pid', '=', $areaid)
                ->where('status', '=', '1')
                ->select('area_name', 'areaid')
                ->get();
        } else {
            $area =  Db::table('areachina')->where('pid', '=', '0')
                ->where('status', '=', '1')
                ->select('area_name', 'areaid')
                ->get();
        }
        if ($area) {
            return $this->jsonSuccessData($area);
        } else {
            return $this->jsonErrorData(105, '获取失败');
        }
    }

    //添加联系人
    public function addcontactsuser(Request $request)
    {
        $data = $request->all();
        if (!is_null($this->isadmin())) {//当前登入管理员
            $validator = Validator::make($request->all(), $this->getValidationRulescontacts(false));
            if ($validator->fails()) {
                return response()->json(['errors' => $validator->errors()], 403);
            } else {
                $data['isadmin'] = 1;
            }
        } else {
            $data['isadmin'] = 2;
        }
//        $data['contactsid'] = Auth::id();
        $this->timeline($data['isadmin'] == 1 ? '管理员添加了设备联系人' : '用户添加了设备联系人');
        $isadmin = DB::table('contactsuser')->insert($data);
        return $this->jsonSuccessData($isadmin);
    }

    //查看所有逻辑删除用户 和禁用用户
    public function UpPaperBasket($id)
    {
        return $this->jsonSuccessData(DB::table('users')->where('id', '=', $id)->update(['state' => '2']));
    }

    //禁用用户
    public function UpuserForbidden($id)
    {
        return $this->jsonSuccessData(DB::table('users')->where('id', '=', $id)->update(['state' => '1']));
    }

    /*
     * 返回当前登入的联系人列表
     * */
    public function contactslist()
    {
        return $this->jsonSuccessData(DB::table('contactsuser')->where([['contactsid', '=', Auth::id()], ['isadmin', '=', is_null($this->isadmin()) ? '2' : '1'], ['isstatus', '=', '1']])->get());
    }

    /*
   * 返回废纸篓数量
   * */
    public function paperBasket()
    {
        return $this->jsonSuccessData(DB::table('users')->where('state', '=', '3')->count());
    }

    //返回用户的经纬度
    public function userLocation()
    {
        if (!is_null($this->isadmin())) {
            $davicenum = DB::table('users as b')
                ->leftjoin('device as d', 'b.id', '=', 'd.uid')
                ->leftjoin('device_type as t', 'd.dtype', '=', 't.tid')
                ->selectRaw('b.name,b.id,b.mapcenter,d.devicenum,COUNT(d.id) AS UserDaviceNum,COUNT(IF(d.devicepolice <> 1, true, null)) AS police')
                ->groupBy('b.id')
                ->get()->toArray();
        } else {
            $davicenum = DB::table('users as b')
                ->where('uid','=',Auth::id())
                ->leftjoin('device as d', 'b.id', '=', 'd.uid')
                ->leftjoin('device_type as t', 'd.dtype', '=', 't.tid')
                ->selectRaw('b.name,b.id,b.mapcenter,d.devicenum,COUNT(d.id) AS UserDaviceNum,COUNT(IF(d.devicepolice <> 1, true, null)) AS police')
                ->groupBy('b.id')
                ->get()->toArray();
        }
        return $this->jsonSuccessData($davicenum);
    }

    /*
   * 返回废纸篓 和状态
   * */
    public function paperBasketList()
    {
        $paper = DB::table('users')->where('state', '=', '3')->get()->toArray();
        $stutus = DB::table('users')->where('state', '=', '1')->get()->toArray();
        return $this->jsonSuccessData(['paper' => $paper, 'stutus' => $stutus]);
    }

    public function textcountuser()
    {
        print_r(Auth::id());
    }
}
