<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use App\UserStatus;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use App\Helpers\CMail;


class AuthController extends Controller
{
    /**
     * Zeigt das Login-Formular im Backend an.
     *
     * ROUTE: /login
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
    */
    public function loginForm(Request $request) {
        $data = [
            "pageTitle" => "Login"
        ];
        return view("back.pages.auth.login", $data);
    }

    /**
     * Zeigt das Formular zum Zurücksetzen des Passworts an.
     *
     * ROUTE: /forgot-password
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\View\View
    */
    public function forgotForm(Request $request) {
        $data = [
            "pageTitle" => "Forgot Password"
        ];
        return view("back.pages.auth.forgot", $data);
    }

    /**
     * Verarbeitet den Login-Vorgang für Benutzer.
     *
     * ROUTE: /login
     * METHOD: POST
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
    */
    public function loginHandler(Request $request) {
        $fieldType = filter_var($request->login_id, FILTER_VALIDATE_EMAIL) ? "email" : "username";

        if($fieldType == "email") {
            $request->validate([
                "login_id" => "required|email|exists:users,email",
                "password"=> "required|min:5"
            ], [
                "login_id.required" => "Gebe deine Email oder Benutzernamen ein",
                "login_id.email" => "Ungültige Email Adresse",
                "login_id.exists" => "Kein Account unter dieser Email gefunden",
                "password.required" => "Passwort wird benötigt",
                "password.min" => "Bitte gebe mind. 5 Zeichen ein",
            ]);
        } else {
             $request->validate([
                "login_id" => "required|exists:users,username",
                "password"=> "required|min:5"
            ], [
                "login_id.required" => "Gebe deine Email oder Benutzernamen ein",
                "login_id.exists" => "Kein Account unter dieser Email gefunden",
                "password.required" => "Passwort wird benötigt",
                "password.min" => "Bitte gebe mind. 5 Zeichen ein",
            ]);
        }

        
        $creds = array(
            $fieldType=>$request->login_id,
            "password" => $request->password
        );

        if(Auth::attempt($creds)) {
            // Überprüfen ob Benutzer inactive ist
            if(auth()->user()->status == UserStatus::Inactive) {
                Auth::logout();
                $request->session()->invalidate();
                $request->session()->regenerateToken();
                return redirect()->route("admin.login")->with("fail", "Dein Account ist derzeit Inactive. Bitte kontaktiere den Support unter (support@larablog.dev) für weitere Informationen");
            }

             if(auth()->user()->status == UserStatus::Pending) {
                Auth::logout();
                $request->session()->invalidate();
                $request->session()->regenerateToken();
                return redirect()->route("admin.login")->with("fail", "Dein Account ist derzeit in Bearbeitung. Bitte kontaktiere den Support unter (support@larablog.dev) für weitere Informationen");
            }
            
            return redirect()->route("admin.dashboard");
        } else {
            return redirect()->route("admin.login")->withInput()->with("fail", "Incorrect Password");
        }
    }

    /**
     * Versendet einen Link zum Zurücksetzen des Passworts per E-Mail.
     *
     * ROUTE: /forgot-password
     * METHOD: POST
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
    */
    public function sendPasswordresetLink(Request $request) {
        $request->validate([
            "email" => "required|email|exists:users,email"
        ], [
            "email.required"=>"Email Adresse wird benötigt",
            "email.email" => "Ungültige Email Adresse",
            "email.exists" => "Wir konnte diese Email nicht in unseren System finden",
        ]);

        $user = User::where("email", $request->email)->first();

        $token = base64_encode(Str::random(64));

        $oldToken = DB::table("password_reset_tokens")->where("email", $user->email)->first();

        if($oldToken) {
            DB::table("password_reset_tokens")->where("email", $request->email)->update([
                "token" => $token,
                "created_at" => Carbon::now()
            ]);
        } else {
            DB::table("password_reset_tokens")->insert([
                "email" => $user->email,
                "token" => $token,
                "created_at" => Carbon::now(),
            ]);
        }

        $actionLink = route("admin.reset_password_form", ["token" => $token]);

        $data = array("actionlink" => $actionLink, "user" => $user);
        $mail_body = view("email-templates.forgot-template", $data)->render();

        $mailConfig = array(
            "recipient_address" => $user->email,
            "recipient_name" => $user->name,
            "subject" => "Reset Passwort",
            "body" => $mail_body
        );

        if(CMail::send($mailConfig)) {
            return redirect()->route("admin.forgot")->with("success", "Wir haben Ihnen einen Link per E-Mail zugesendet");
        } else {
            return redirect()->route("admin.forgot")->with("fail", "Leider ist etwas schief gegangen, bitte versuchen Sie es später wieder");
        }

    }

    /**
     * Zeigt das Formular zum Zurücksetzen des Passworts an.
     *
     * ROUTE: /reset-password/{token}
     * METHOD: GET
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string|null  $token   Passwort-Reset-Token
     * @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
    */
    public function resetForm(Request $request, $token = null) {
        $isTokenExists = DB::table("password_reset_tokens")->where("token", $token)->first();

        if(!$isTokenExists) {
            return redirect()->route("admin.forgot")->with("fail", "Ungültiger Token, fordere einen neuen an");
        } else {

            $diffMins = Carbon::createFromFormat("Y-m-D H:i:s", $isTokenExists->created_at)->diffInMinutes(Carbon::now());

            if($diffMins > 30) {
                return redirect()->route("admin.forgot")->with("fail", "Der Reset Link ist leider abgelaufen, fordere einen neuen Link an");
            }
            
            $data = [
                "pageTitle" => "Passwort zurücksetzen",
                "token" => $token
            ];
            return view("back.pages.auth.reset", $data);
        }
    }

    /**
     * Verarbeitet das Zurücksetzen des Passworts.
     *
     * ROUTE: /reset-password
     * METHOD: POST
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
    */
    public function resetPasswordHandler(Request $request) {
        $request->validate([
            "new_password" => "required|min:5|required_with:new_password_confirm|same:new_password_confirm",
            "new_password_confirm" => "required"
        ], [
            "new_password.required" => "Neues Passwort wird benötigt",
            "new_password_confirm.required" => "Neues Passwort wird benötigt",
            "new_password.same" => "Du musst das neue Passwort bestätigen",
            "new_password.min" => "Bitte gebe mind. 5 Zeichen ein",
        ]);

        $dbToken = DB::table("password_reset_tokens")->where("token", $request->token)->first();

        $user = User::where("email", $dbToken->email)->first();

        User::where("email", $user->email)->update([
            "password" => Hash::make($request->new_password)
        ]);

        $data = array(
            "user" => $user,
            "new_password" => $request->new_password
        );

        $mail_body = view("email-templates.password-changes-template", $data)->render();

        $mailConfig = array(
            "recipient_address" => $user->email,
            "recipient_name" => $user->name,
            "subject" => "Passwort geändert",
            "body" => $mail_body
        );

        if(CMail::send($mailConfig)) {
            DB::table("password_reset_tokens")->where([
                "email" => $dbToken->email,
                "token" => $dbToken->token,
            ])->delete();
            return redirect()->route("admin.login")->with("success", "Wir haben Ihr Passwort geändert, Sie können sich nun einloggen");
        } else {
            return redirect()->route("admin.reset_password_form", ["token" => $dbToken->token])->with("fail", "Leider ist etwas schief gegangen, bitte versuchen Sie es später wieder");
        }
    }
}
