<?php

namespace App\Http\Controllers\Resources;

use App\Models\User;
use App\Exports\UsersExport;
use App\Imports\UsersImport;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Excel;
use App\Http\Filters\QueryBuilder;
use App\Http\Controllers\Controller;
use App\Http\Requests\ExportRequest;
use App\Http\Requests\ImportRequest;
use App\Http\Resources\User\UserResource;
use App\Http\Requests\User\UserStoreRequest;
use Illuminate\Database\Eloquent\Collection;
use App\Http\Requests\User\UserUpdateRequest;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $this->authorize('viewAny', User::class);

        $queryBuilder = new QueryBuilder(new User(), $request);

        return response()->json($queryBuilder->build()->withTrashed()->paginate(10), 200);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  App\Http\Requests\User\UserStoreRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(UserStoreRequest $request)
    {
        $user = User::create($request->validated());
        $user->password = bcrypt($request->password);
        $user->save();
        $user->assignRole($request->role);

        // return response()->json($user, 201);
        return new UserResource($user);
    }

    /**
     * Display the specified resource.
     *
     * @param  User  $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        $this->authorize('view', User::class);
        return new UserResource($user);
        return response()->json(['status' => 'ok','data' => $user], 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  App\Http\Requests\User\UserUpdateRequest  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(UserUpdateRequest $request, $id)
    {
        $user = User::withTrashed()->find($id);

        $user->syncRoles($request->role);

        if (!$user) {
            return response()->json(['errors' => array(['code' => 404,'message' => __('users.not_find')])], 404);
        }

        if (isset($request->password)) {
            return tap($user)->update([
              'name' => $request->name,
              'email' => $request->email,
              'password' =>  bcrypt($request->password),
            ]);
        } else {
            return tap($user)->update([
              'name' => $request->name,
              'email' => $request->email,
            ]);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $user = User::withTrashed()->findOrFail($id);

        $this->authorize('delete', $user);

        $user->forceDelete();

        return response()->json(['code' => 204,'message' => __('strings.deleted_successfully')], 204);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  array  $id
     * @return \Illuminate\Http\Response
     */
    public function destroyMany(Request $request)
    {
        foreach ($request->input('ids') as $id) {
            $user = User::withTrashed()->findOrFail($id);

            $this->authorize('delete', $user);
        }

        foreach ($request->input('ids') as $id) {
            $user = User::find($id);

            $user->forceDelete();
        }

        return response()->json(['code' => 204,'message' => __('strings.deleted_successfully')], 204);
    }

    /**
     * Remove the notifiations of specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function readAll(Request $request, $id)
    {
        $user = User::withTrashed()->findOrFail($id);

        $user->notifications()->delete();

        return response()->json(['code' => 200,'message' => __('strings.deleted_successfully')], 204);
    }

    /**
     * Remove the notifiations of specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function read(Request $request, $id, $idNotification)
    {
        $user = User::withTrashed()->findOrFail($id);

        $notification = $user->notifications()->where('id', $idNotification)->first();
        if($notification) {
            $notification->delete();
        }

        return response()->json(['code' => 200,'message' => __('strings.deleted_successfully')], 204);
    }


    /**
     * Display report from a listing of the resource.
     *
     * @param  App\Http\Requests\ExportRequest $request
     * @return PDF CSV or XLS
     */
    public function export(ExportRequest $request, Excel $excel)
    {
        $file = 'users.' . $request->input('format');
        $queryBuilder = new QueryBuilder(new User(), $request);
        return $excel->download(new UsersExport($queryBuilder->build()->withTrashed()->get()), $file);
    }

    /**
     * Import data from a listing of the file.
     *
     * @param  App\Http\Requests\ImportRequest $request
     * @return PDF CSV or XLS
     */
    public function import(ImportRequest $request, Excel $excel)
    {
        $excel->import(new UsersImport(auth()->user()), $request->file('importFile'));

        return response()->json(['code' => 201,'message' => __('strings.imported_successfully')], 201);
    }

    /**
     * Dowload template.
     *
     * @return File CSV
     */
    public function template(Excel $excel)
    {
        return $excel->download(new UsersExport(new Collection([])), 'users.csv');
    }

    public function inactived($id)
    {
        $user = User::withTrashed()->findOrFail($id);

        return $this->user()->can('inactived', $user);

        $user->delete();

        return response()->json($user, 200);
    }

    public function actived($id)
    {
        $user = User::withTrashed()->findOrFail($id);

        if (!$user->deleted_at) {
            return response()->json(['errors' => array(['code' => 400,'message' => __('users.actived_error')])], 400);
        }

        $user->restore();

        return response()->json($user, 200);
    }
}
