<?php

namespace App\Http\Controllers;

use App\User;
use App\Client;
use App\Operator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Request as RequestFacade;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use JsValidator;


class OperatorController extends Controller {
    const REL_FILE_PATH = "/images/operatorImages/";

    private $operatorValidationRules = [
        'name' => 'required|string|max:255',
        'firstname' => 'required|string|max:255',
        'company' => 'nullable|string|max:255',
        'email' => 'nullable|email|max:255',
        'phone' => 'nullable|string|max:255',
        'position' => 'nullable|string|max:255',
    ];


    /**
     * Display a listing of the resource.
     */
    public function index() {
        $loggedUser = User::find(Auth::user()->id);

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

        # Bearbeiter auslesen, die zu diesem Mandanten gehören
        $operatorList = $loggedUser->client->operator;

        return View::make('operator.list')->with(["operatorList" => $operatorList]);
    }


    /**
     * Show the form for creating a new resource.
     * Show the form for editing the specified resource.
     *
     */
    public function edit($operatorId) {
        $loggedUser = User::find(Auth::user()->id);

        # Neuen Bearbeiter erstellen
        if ($operatorId == 0) {
            # Berechtigung prüfen
            if (!UserController::checkRight("createOperators", $loggedUser))
                return response()->json(['response' => 'error', 'message' => 'Keine Berechtigung.']);

            $operator = new Operator();
        }
        # Bearbeiter bearbeiten
        else {
            # Berechtigung prüfen
            if (!UserController::checkRight("editOperators", $loggedUser))
                return response()->json(['response' => 'error', 'message' => 'Keine Berechtigung.']);

            # Bearbeiter finden
            $operator = Operator::find($operatorId);
            if ($operator == null) {
                return response()->json(['response' => 'error', 'message' => 'Bearbeiter nicht gefunden.']);
            }
        }

        # Validierung
        $frontValidator = JsValidator::make($this->operatorValidationRules, [], [], "#editOperator");

        $arguments = ["operator" => $operator,
            "validator" => $frontValidator];

        # View rendern
        $editorHTML = View::make('operator.edit')->with($arguments)->render();

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


    /**
     * Store a newly created resource
     *
     */
    public function store(Request $request) {
        $loggedUser = User::find(Auth::user()->id);

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

        # Speichern
        $trySave = $this->save($request, $loggedUser->client);
        if ($trySave instanceof Operator) {
            return response()->json(['response' => 'success', 'message' => "Bearbeiter "
                . $request->get('name')
                . " " . $request->get('firstname')
                . " wurde erfolgreich angelegt."]);
        }
        # Wenn Speichern nicht erfolgreich, enthält $trySave eventuell Fehlermeldungen, die dem Nutzer angezeigt werden
        else {
            return response()->json(['response' => 'error', 'message' => $trySave]);
        }
    }

    /**
     * Update the specified resource
     *
     */
    public function update(Request $request) {
        $loggedUser = User::find(Auth::user()->id);

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

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

        # Bestehenden Bearbeiter lesen
        $operator = Operator::find($operatorId);
        if ($operator == null)
            return redirect()->back()->withErrors("Bearbeiter nicht gefunden.");

        # Speichern
        $trySave = $this->save($request, $loggedUser->client, $operator);
        if ($trySave instanceof Operator) {
            return response()->json(['response' => 'success', 'message' => "Bearbeiter " . $operator->name
                . " " . $operator->firstname
                . " wurde erfolgreich gespeichert."]);
        }
        # Wenn Speichern nicht erfolgreich, enthält $trySave eventuell Fehlermeldungen, die dem Nutzer angezeigt werden
        else {
            return response()->json(['response' => 'error', 'message' => $trySave]);
        }
    }

    # View für Bestätigung der Registrierung eines neuen Nutzers durch Administrator
    public function showUserRegisterConfirm($operatorId) {
        $user = User::find(Auth::user()->id);

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

        $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();
        }

        $arguments = ["activeNavItem" => "userList",
                      "operator"      => $operator];

        # View rendern
        $editorHTML = View::make('operator.newUserConfirm')->with($arguments)->render();

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


    private function setImageToObject($operator) {
        # Bildrelevante Parameter
        $newImage = RequestFacade::input('newFile');

        # Pfad für Bearbeiter-Bilder
        $filePath = OperatorController::REL_FILE_PATH;

        # Bild löschen, wenn gewünscht
        if (RequestFacade::input('deleteFile')) {
            $this->deleteImage($operator);
        }

        # Prüfen, ob neues Bild via Dropzone hochgeladen wurde
        if ($newImage != "") {
            # Altes Bild löschen
            $this->deleteImage($operator);

            # Neues Bild setzen
            # Pfad hinzufügen
            $newImage = DropzoneController::DROPZONE_TMP_PATH . $newImage;
            $this->setNewImage($operator, $newImage, $filePath);
        }

        return $operator;
    }

    private function deleteImage($operator) {
        # Prüfen, ob ein Bild für den Nutzer existiert
        if ($operator->image != null) {
            $userImage = $operator->image;
            if (!empty($userImage)) {
                Storage::disk('uploads')->delete($userImage);
            }
        }
        $operator->image = NULL;

        return $operator;
    }

    # Speichern eines neuen Bildes für den User
    private function setNewImage($operator, $newImage, $filePath) {

        # Neue Dateiendung auslesen
        $info = pathinfo(Storage::disk('uploads')->url($newImage));

        if (is_array($info)) {
            $newExtension = $info["extension"];
        }
        else return $operator;

        # Pfad zum temporären Bild setzen
        $newImage = Storage::disk("uploads")->getAdapter()->getPathPrefix() . $newImage;

        # Neuen Dateinamen zusammensetzen
        $filename = "operatorImage_" . $operator->id . uniqid() . "." . $newExtension;

        # Neues Bild hochladen
        if (UploadController::uploadFile($newImage, $filename, $filePath)) {
            $operator->image = $filePath . $filename;
        }

        return $operator;
    }

    /**
     * Save the specified resource in storage.
     *
     */
    public function save(Request $request, Client $client, Operator $operator = null) {
        if (is_null($operator)) $operator = new Operator();

        # Input validieren
        $backValidator = Validator::make($request->all(), $this->operatorValidationRules);

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

        # Neue Daten setzen
        $operator->client_id = $client->id;
        $operator->company = $request->get('company');
        $operator->name = $request->get('name');
        $operator->firstname = $request->get('firstname');
        $operator->email = $request->get('email');
        $operator->phone = $request->get('phone');
        $operator->position = $request->get('position');

        # Bild updaten
        $this->setImageToObject($operator);

        # Speichern
        try {
            $operator->save();
        } catch (\Exception $e) {
            Log::error("Fehler beim Speichern der Daten für Bearbeiter " . $operator->name
                . $operator->firstname . ", (ID: " . $operator->id . " ), Mandant " .
                $client->id . ": " . $e->getMessage());
            return ["Es ist ein Fehler aufgetreten."];
        }

        return $operator;
    }


    /* Asynchrone Suche für Live-Search */
    public function asyncSearch($search = "") {
        $loggedUser = User::find(Auth::user()->id);
        # Zugehörigen Mandanten bestimmen
        $clientID = $loggedUser->client->id;

        # Erst ab zwei Buchstaben die Suche beginnen
#        if (strlen($search) < 2) return json_encode([]);

        # Suchstring aufsplitten
        $searchParts = explode(" ", $search);

        # Nach Bearbeitern suchen, die zum Mandanten gehören
        $query = Operator::where('client_id', '=', $clientID)
            ->whereNotNull('user_id')
            ->where(

            # closure function ist für Gruppierung der OR-WHERE
                function ($query) use ($searchParts) {
                    # Query bauen, um nach Namen / Vornamen zu suchen
                    $i = 0;
                    foreach ($searchParts as $searchPart) {
                        if ($i == 0) {
                            $query->Where('name', 'LIKE', $searchPart . '%')
                                ->orWhere('firstname', 'LIKE', $searchPart . '%');
                        }
                        else {
                            $query->Where('name', 'LIKE', $searchPart . '%')
                                ->orWhere('firstname', 'LIKE', $searchPart . '%');
                        }
                        $i++;
                    }
                });

        # Ergebnisse holen
        $possibleOperators = $query->get();

        if (count($possibleOperators) < 0) {
            $possibleOperators = false;
        }

        return json_encode($possibleOperators);
    }

}
