<?php

namespace Sartoric\ModularCms\Controllers\Layouts;

use App\Providers\AuthServiceProvider;
use Sartoric\ModularCms\Models\User;
use Sartoric\ModularCms\Models\Role;
use Illuminate\Validation\Rule;
use Illuminate\Auth\Access\Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Sartoric\ModularCms\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Mockery\Exception;
use Validator;
use DB;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = User::appusers();
        return view('sartoric/modularcms::layouts.users.index', compact('users'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        if (!auth()->user()->can('create', User::class)) {
            abort(401);
        }

        $user = new User;
        $roles = Role::approles();
        $userroles=collect([]);
        return view('sartoric/modularcms::layouts.users.create', compact(['user', 'roles', 'userroles']));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // save request data in $user
        if (!auth()->user()->can('create', User::class )) {
            abort(401);
        }

        $this->validator($request->all())
            ->sometimes('password','required|alpha_dash|min:6|max:100', function(){return true;})
            ->validate();

        $active = request('active')=='on'?true:false;

        $user = null;
        try {
            DB::transaction(function () use (&$user, $request, $active) {

                $user = User::create([
                    'fullname'      => request('fullname'),
                    'email'         => request('email'),
                    'username'      => request('username'),
                    'active'        => $active,
                    'password'      => request('password'),
                ]);

                if (!auth()->user()->isSuperAdmin()) {
                    // Remove any admin or superadmin role from the role list to protect against admin creation hack
                    $rolelist = Arr::where(request('rolelist'), function ($value, $key) {
                        $role = Role::find($value);
                        return ($role->name !== 'Superadmin' && $role->name !== 'Admin');
                    });
                } else {
                    $rolelist = request('rolelist');
                }

                $user->roles()->sync($rolelist);

                $user->save();

            });

        } catch (\Exception $err) {
            return back()->with('notify', $this->notifArray('DB', 'error', $err->getMessage(), true));
        }

        return redirect()->route('users.edit', $user)
            ->with('notify', $this->notifArray('DB', 'success', __('Utente creato con successo')));


    }

    /**
     * Display the specified resource.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function edit(User $user)
    {
        if (!auth()->user()->can('update', $user)) {
            abort(401);
        }

        $roles = Role::approles();
        $userroles=$user->roles->pluck('id');
        return view('sartoric/modularcms::layouts.users.edit', compact(['user', 'roles', 'userroles']));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, User $user)
    {
        if (!auth()->user()->can('update', $user)) {
            abort(401);
        }

        $this->validator($request->all(), $user->id)
            ->sometimes('password', 'nullable|alpha_dash|min:6|max:100', function () {
                return true;
            })
            ->validate();

        $active = request('active')=='on'?true:false;

        $user->fill([
            'fullname'      => request('fullname'),
            'email'         => request('email'),
//            'username'      => request('username'),
//            'avatar'        => request('avatar'),
            'active'        => $active,
            'password'      => request('password'),
        ]);

        try {
            DB::transaction(function () use ($user, $request) {

                if (!auth()->user()->isSuperAdmin()) {
                    // Remove any admin or superadmin role from the role list to protect against admin creation hack
                    $rolelist = Arr::where(request('rolelist'), function ($value, $key) {
                        $role = Role::find($value);
                        return ($role->name !== 'Superadmin' && $role->name !== 'Admin');
                    });
                } else {
                    $rolelist = request('rolelist');
                }

                $user->roles()->sync($rolelist);

                $user->save();
            });

        } catch (\Exception $err) {
            return back()->with('notify', $this->notifArray('DB', 'error', $err->getMessage(), true));
        }
        return redirect()->route('users.edit', $user)
            ->with('notify', $this->notifArray('DB', 'success', __('Utente aggiornato con successo')));
    }

    public function toggleActive(User $user)
    {
        if (!auth()->user()->can('update', $user)) {
            abort(401);
        }
        try {
            $user->fill([
                'active' => !$user->active
            ]);

            $user->save();
        } catch (\Exception $err) {
            return back()->with('notify', $this->notifArray('DB', 'error', $err->getMessage(), true));
        }

        return back();
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        if (!auth()->user()->can('delete', $user)) {
            abort(401);
        }
// TODO : Gestire detach
        try {
            $user->delete();
        } catch (\Exception $err) {
            return back()->with('notify', $this->notifArray('DB', 'error', $err->getMessage(), true));
        }
        return redirect()->route('users.index', $user)
            ->with('notify', $this->notifArray('DB', 'success', __('Utente eliminato con successo')));
    }


    /**
     * @param User $user
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function showChangePassword(User $user)
    {
        if (!auth()->user()->can('selfUpdatePassword', $user)) {
            abort(401);
        }

        return view('sartoric/modularcms::layouts.changepassword', compact('user'));
    }

    /**
     * @param Request $request
     * @param User $user
     * @return \Illuminate\Http\RedirectResponse
     */
    public function updateChangePassword(Request $request, User $user)
    {
        if (!auth()->user()->can('selfUpdatePassword', $user)) {
            abort(401);
        }

        $attributeNames = array(
            'old_password' => __('Vecchia password'),
            'new_password' => __('Nuova password')
        );

        Validator::make($request->all(), [
            'old_password'   => 'required|alpha_dash|min:6|max:100',
            'new_password'   => 'required|alpha_dash|min:6|max:100|confirmed|different:old_password',
            'new_password_confirmation'   => 'required',
        ])->setAttributeNames($attributeNames)->validate();

        if (auth()->attempt(['username'=>auth()->user()->username, 'password'=>request('old_password')])) {
            try {
                $user->fill([
                    'password' => request('new_password'),
                    'updated_by' => auth()->user()->id,
                ]);

                $user->save();

            } catch (\Exception $err) {
                return back()->with('notify', $this->notifArray('DB', 'error', $err->getMessage(), true));
            }

            return redirect()->route('change-password', $user)
                ->with('notify', $this->notifArray('DB', 'success', __('Password modificata con successo')));

        } else {
            return redirect()->route('change-password', $user)
                ->with('notify', $this->notifArray('DB', 'error', __('Vecchia password errata, riprovare')));

        }
    }

    /**
     * @param array $data
     * @param int $id
     * @return \Illuminate\Validation\Validator
     */
    protected function validator(array $data, $id = 0)
    {

        $attributeNames = array(
            'rolelist' => __('Ruoli'),
            'fullname' => __('Nome completo'),
        );

        return Validator::make($data, [
            'fullname'   => 'required|string|max:255',
            // Non serve controllo unique come x email perchè non viene passato in update (disabled)
            'username'   => 'sometimes|unique:users|alpha_dash|max:255',
//          'password'   => 'sometimes|alpha_dash',
            'rolelist'   => 'required',
            'email' => ['required','email','max:255',
                Rule::unique('users', 'email')
                    ->ignore($id)
                    ->where(function ($query) {
                        $query->where('deleted_at', null);
                    })
            ],
        ])->setAttributeNames($attributeNames);
    }

}
