<?php

namespace App\Http\Controllers;

use App\Client;
use App\Operator;
use App\RightsGroup;
use Illuminate\Support\Facades\Auth;
use View;
use Illuminate\Support\Facades\Log;
use JsValidator;
use Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;

use App\User;

use App\Events\UserCreated;

class ClientAdminController extends Controller {

    # Userliste des Mandanten laden
    public function showUserList() {
        $loggedUser = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("seeClientUserList", $loggedUser))
            return redirect()->route('index');

        # User auslesen, die zu diesem Mandanten gehören
        $userList = $loggedUser->client->user;

        return View::make('clientAdmin.list')->with(["activeNavItem" => "userList", "userList" => $userList]);
    }

    # View aufrufen für das Bearbeiten eines Users aus der Mandantennutzerliste heraus
    public function showUserEdit() {

        $loggedUser = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("editProfiles", $loggedUser))
            return response()->json(['response' => 'error', 'message' => 'Keine Berechtigung.']);

        $userID = request()->input('userID');

        # Userdaten laden
        $userToEdit = User::find($userID);
        if ($userToEdit == null)
            return response()->json(['response' => 'error', 'message' => 'Nutzer nicht gefunden.']);

        # Validatorobjekt erstellen
        $controller = new UserController();
        $rules = array_merge($controller->getUpdateValidationRules(), $controller->getEMailUpdateValidationRules());

        $frontValidator = JsValidator::make($rules, [], [], "#userEdit");

        # View rendern
        $editorHTML = View::make('clientAdmin.editUser', ["userToEdit" => $userToEdit, "validator" => $frontValidator])->render();

        return response()->json(['response' => 'success', 'editorHTML' => $editorHTML]);
    }

    # View für Benutzerberechtigungen verwalten in Variable rendern und zurückgeben
    public function showUserRightsEdit() {
        $loggedUser = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("editUserRights", $loggedUser))
            return response()->json(['response' => 'error', 'message' => 'Keine Berechtigung.']);

        $userID = request()->input('userID');

        # User darf nicht seine eigenen Rechte bearbeiten
        if ($loggedUser->id == $userID)
            return response()->json(['response' => 'error', 'message' => 'Keine Berechtigung.']);

        # Userdaten laden
        $userToEdit = User::find($userID);
        if ($userToEdit == null)
            return response()->json(['response' => 'error', 'message' => 'Nutzer nicht gefunden.']);

        # Rechtegruppen auslesen
        $groups = RightsGroup::all();
        $rightsGroups = array();

        # Rechtegruppen für Ausgabe sortieren
        foreach ($groups as $group) {
            # Globale Rechte darf nur der globale Administrator sehen
            if ($group["id"] == 1 && !UserController::isSuperAdmin($loggedUser)) {
                continue;
            }
            # Administrationsrechte auf Mandantenbasis darf nur der Mandantenadministrator (oder globaler
            # Administrator) sehen
            if ($group["id"] == 2 && !UserController::isClientAdmin($loggedUser)) {
                continue;
            }

            $rightsGroups[$group["id"]]["name"] = $group["name"];
            $rightsGroups[$group["id"]]["description"] = $group["description"];

            # Zugehörige Rechte zur Gruppe auslesen und sortieren
            $groupRights = array();
            $rights = $group->rights;

            $hasAllRights = "checked";

            foreach ($rights as $right) {
                $hasRight = "";

                $groupRights[$right["id"]]["name"] = $right["name"];
                $groupRights[$right["id"]]["label"] = $right["label"];
                $groupRights[$right["id"]]["description"] = $right["description"];

                # Prüfen, ob der User dieses Recht besitzt oder Admin ist
                if (UserController::checkRight($right["name"], $userToEdit)) {
                    $hasRight = "checked";
                }
                else {
                    $hasRight = "";
                    $hasAllRights = "";
                }

                $groupRights[$right["id"]]["hasRight"] = $hasRight;
            }

            $rightsGroups[$group["id"]]["rights"] = $groupRights;
            $rightsGroups[$group["id"]]["hasAllRights"] = $hasAllRights;

            unset($groupRights);
        }

        $args["userToEdit"] = $userToEdit;
        $args["rightsGroups"] = $rightsGroups;

        $editorHTML = View::make('clientAdmin.editUserRights', $args)->render();

        return response()->json(['response' => 'success', 'editorHTML' => $editorHTML]);
    }

    # View für Registrierung eines neuen Nutzers durch Administrator
    public function showUserRegister($operatorId = 0) {
        $loggedUser = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("createUser", $loggedUser))
            return redirect()->route('index');

        # Formulardaten validieren Frontend
        $userController = new UserController();
        $frontValidator = JsValidator::make($userController->getRegisterByAdminValidationRules(), [], [], "#registerNewUser");

        $operator = new Operator();

        # Ggf. E-Mail-Adresse vorblenden, wenn für Bearbeiter User angelegt werden soll
        if ($operatorId <> 0) {
            # Bearbeiterdaten holen
            $operator = Operator::find($operatorId);

            if ($operator == null)
                $operator = new Operator();
        }

        return View::make('clientAdmin.newUser')->with(["activeNavItem" => "userList", "validator" => $frontValidator, "operator" => $operator]);
    }

    # Neuen Benutzer durch Administrator registrieren
    public function registerNewUser() {
        $user = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("createUser", $user))
            return redirect()->route('index');

        # Validator erstellen und Inputdaten validieren
        $userController = new UserController();
        $validationRules = $userController->getRegisterByAdminValidationRules();
        $backValidator = Validator::make(request()->all(), $validationRules);

        if ($backValidator->fails()) {
            return redirect()->back()->withErrors($backValidator->errors());
        }

        # 2019-01-24 / DS / Prüfung, ob E-Mail-Adresse bereits vergeben, nur auf aktive User
        $eMail = request()->input('email');
        if(!UserController::checkEmailAvailable($eMail)) {
            return redirect()->back()->withErrors(["Diese E-Mail-Adresse ist bereits in Verwendung."]);
        }

        # Neuen Benutzer speichern
        $newUser = new User();
        $newUser->name = request()->input('name');
        $newUser->firstname = request()->input('firstname');
        $newUser->email = request()->input('email');
        $newUser->client_id = $user->client->id;
        $newUser->active = false;
        $newUser->password = Hash::make("123");

        $operatorId = request()->input('operator_id');

        try {
            $newUser->save();
        } catch (\Exception $e) {
            Log::error("Fehler bei Registrierung eines neuen Nutzers " . $newUser->email);
            Log::error($e->getMessage());
            return redirect()->back()->withErrors(["Die Registrierung ist fehlgeschlagen."]);
        }

        # Bezug zu Bearbeiter herstellen
        if ($operatorId <> "") {
            $operator = Operator::find($operatorId);

            if ($operator <> NULL) {
                $operator->user_id = $newUser->id;
            }
        }
        # Neuen Bearbeiter erstellen
        else {
            $operator = new Operator();
            $operator->client_id = $user->client->id;
            $operator->name = request()->input('name');
            $operator->firstname = request()->input('firstname');
            $operator->email = request()->input('email');
            $operator->image = NULL;
            $operator->user_id = $newUser->id;
        }

        # Bearbeiter speichern
        try {
            $operator->save();
        } catch (\Exception $e) {
            Log::error("Fehler bei Registrierung eines neuen Nutzers " . $newUser->email);
            Log::error("Bearbeiter konnte nicht erstellt werden");
            Log::error($e->getMessage());

            # Versuchen, neu angelegten Nutzer wieder zu löschen
            try {
                $newUser->delete();
            } catch (\Exception $e) {
            }

            return redirect()->back()->withErrors(["Die Registrierung ist fehlgeschlagen. Bearbeiter konnte nicht erstellt werden."]);
        }

        event(new userCreated($newUser));

        # E-Mail für das Setzen des Passworts versenden
        # Userdaten laden
        if (!$newUser) return redirect()->back()->withErrors(["Nutzer nicht gefunden."]);

        # Link versenden
        $userController = new UserController();
        $sendLink = $userController->sendPasswordResetLink($newUser, true);

        # Erfolgs- bzw. Fehlermeldung zurückgeben
        if (!$sendLink) {
            return redirect()->back()->withErrors(["Es ist ein Fehler aufgetreten."]);
        }

        return redirect()->back()->with("message", "Der Benutzer wurde angelegt.");
    }

    # Änderungen an den Berechtigungen eines Nutzers speichern
    public function changeUserRights() {
        $user = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("editUserRights", $user))
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        $userID = request()->input('userToEdit');

        # User darf nicht seine eigenen Rechte bearbeiten
        if ($user->id == $userID)
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        # Userdaten laden
        $userToEdit = User::find($userID);
        if ($userToEdit == null)
            return redirect()->back()->withErrors(["Nutzer nicht gefunden."]);

        $rightsController = new RightsController($userToEdit);

        # War User Mandantenadministrator?
        $wasClientAdmin = UserController::isClientAdmin($userToEdit);

        # War User Superadministrator?
        $wasSuperAdmin = UserController::isSuperAdmin($userToEdit);

        $rightsToAttach = array();

        # Prüfen, welche Rechte belegt wurden
        foreach ($_POST as $key => $item) {
            if (substr($key, 0, 9) != "checkbox_") continue;
            if ($item != "on") continue;

            # Rechte sammeln
            $rightsToAttach[] = substr($key, 9, strlen($key));
        }

        # Wenn User Mandantenadministrator (kein Superadmin!) war und das nun nicht mehr ist, nur Standard-Nutzerrechte vergeben
        # Darf nur ausgeführt werden, wenn eingeloggter User ebenfalls mindestens Mandantenadministrator ist
        if ($wasClientAdmin && !$wasSuperAdmin && UserController::isClientAdmin($user)) {
            # User soll kein Mandantenadministrator mehr sein
            if (array_search(2, $rightsToAttach) === false) {
                $rightsController->removeAllRights();

                # ggf. neue Rechte hinzufügen
                $rightsController->addRights($rightsToAttach);

                # Standardrechte vergeben
                RightsController::setStandardRights($userToEdit);

                return redirect()->back()->with("message", "Die Daten wurden gespeichert.");
            }
        }
        # Wenn User Superadministrator war und das nun nicht mehr ist, bleibt Mandantenadministratorrecht erhalten
        # Darf nur ausgeführt werden, wenn eingeloggter User ebenfalls mindestens Superadministrator ist
        elseif ($wasSuperAdmin && UserController::isSuperAdmin($user)) {
            # User soll kein Superadministrator mehr sein
            if (array_search(1, $rightsToAttach) === false) {
                $rightsController->removeAllRights();

                # ggf. neue Rechte hinzufügen
                $rightsController->addRights($rightsToAttach);

                # Standardrechte vergeben
                RightsController::setStandardRights($userToEdit);

                return redirect()->back()->with("message", "Die Daten wurden gespeichert.");
            }
        }

        # Alle Rechte des Nutzers entfernen, die nicht administrativ sind
        $rightsController->removeAllSingleRights();

        $someAdmin = false;

        # Ansonsten Rechte wie gehabt zuweisen, außer User soll Mandanten- oder Superadministrator werden/bleiben
        if (array_search(1, $rightsToAttach) !== false) {
            $someAdmin = true;
            $addRights = $rightsController->makeSuperAdmin();
        }
        elseif (array_search(2, $rightsToAttach) !== false) {
            $someAdmin = true;
            $addRights = $rightsController->makeClientAdmin();
        }

        # Weitere Rechte
        if (!$someAdmin) {
            $addRights = $rightsController->addRights($rightsToAttach);
        }

        # Erfolgs/Fehlermeldung
        if ($addRights)
            return redirect()->back()->with("message", "Die Daten wurden gespeichert.");
        else return redirect()->back()->withErrors(["Es ist ein Fehler aufgetreten."]);

    }

    # View für Benutzer löschen in Variable rendern und zurückgeben
    public function showUserDelete() {
        $user = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("deleteUser", $user))
            return response()->json(['response' => 'error', 'message' => "Keine Berechtigung."]);

        $userID = request()->input('userID');
        $userToEdit = User::find($userID);

        if ($userToEdit == null)
            return response()->json(['response' => 'error', 'message' => "Nutzer nicht gefunden."]);

        # View rendern
        $editorHTML = View::make('clientAdmin.deleteUser', ["userToEdit" => $userToEdit])->render();

        return response()->json(['response' => 'success', 'editorHTML' => $editorHTML]);
    }

    # Benutzer löschen
    public function deleteUser() {
        $user = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("deleteUser", $user))
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        $userID = request()->input('userToEdit');
        $userToDelete = User::find($userID);

        if ($userToDelete == null)
            return redirect()->back()->withErrors(["Nutzer nicht gefunden."]);

        $confirmDelete = request()->input('confirmDelete');

        # User darf sich nicht selbst löschen
        if ($user->id == $userID)
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        # Super-Administratoren dürfen nicht gelöscht werden
        if (UserController::checkRight("isSuperAdmin", $userToDelete))
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        # Prüfen, ob Checkbox bestätigt ist
        if (!is_null($confirmDelete)) {

            try {
                # Gelöscht von setzen (hier passiert bisher nur ein soft delete!)
                $userToDelete->deleted_by = $user->id;
                $userToDelete->update();

                $userToDelete->delete();
            } catch (\Exception $e) {
                Log::error("Fehler beim Löschen von Nutzer " . $userToDelete->id);
                Log::error($e->getMessage());
                return redirect()->back()->withErrors(["Es ist ein Fehler aufgetreten."]);
            }

            # Erfolgsmeldung
            Log::info("Der Benutzer mit der ID " . $userToDelete->id . " wurde durch den Benutzer " . $user->id . " gelöscht (soft delete).");
            return redirect()->back()->with("message", "Der Benutzer wurde gelöscht.");
        }
        else
            return redirect()->back()->with("message", "Der Benutzer wurde nicht gelöscht, da das Löschen bestätigt werden muss!");

    }


    public function resetUserPassword($userID) {
        $user = User::find(Auth::user()->id);

        # Berechtigung prüfen
        if (!UserController::checkRight("resetPassword", $user))
            return redirect()->back()->withErrors(["Keine Berechtigung."]);

        # Userdaten laden
        $userToEdit = User::find($userID);
        if (!$userToEdit) return redirect()->back()->withErrors(["Nutzer nicht gefunden."]);

        $username = $userToEdit->firstname . " " . $userToEdit->name;

        # Link versenden
        $userController = new UserController();
        $sendLink = $userController->sendPasswordResetLink($userToEdit);

        # Erfolgs- bzw. Fehlermeldung zurückgeben
        if (!$sendLink) {
            return redirect()->back()->withErrors(["Es ist ein Fehler aufgetreten."]);
        }

        return redirect()->back()->with("message", "Der Link zum Zurücksetzen des Passworts für Benutzer " . $username . " wurde versendet.");
    }

}
