<?php

namespace App\Http\Controllers;

use App\Models\Applience;
use App\Models\Department;
use App\Models\RoleToolRelation;
use App\Models\Tool;
use App\Models\User;
use App\Models\UserAccessLink;
use App\Models\UserToolSetup;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Spatie\SlackAlerts\Facades\SlackAlert;

class UserController extends Controller
{
    public function show() : View 
    {
        return view('users.users');
    }

    public function loadUsers() 
    {
        $formattedArray = [];

        foreach (User::users() as $user) {
            $formattedArray[] = [
                'id'        => $user->id,
                'name'      => $user->firstname.' '.$user->lastname,
                'email'     => $user->email,
                'role'      => $user->jobRole != 0 ? Department::find($user->jobRole)->first()->name : 'None',
                'setupDone' => $user->setupDone,
                'tools'     => $user->userTools(),
            ];
        }

        return $this->generateResponse('Success', '', $formattedArray);
    }

    public function loadUsersByAmount() 
    {
        $users = [];

        foreach (User::users()->sortByDesc('id')->take(5) as $user) {
            $users[] = [
                'ID'                => $user->id,
                'firstname'         => $user->firstname,
                'lastname'          => $user->lastname,
                'personal_email'    => $user->personal_email,
                'email'             => $user->email,
                'jobRole'           => $user->jobRole != 0 ? Department::find($user->jobRole)->first()->name : 'None',
                'setupDone'         => $user->setupDone,
                
            ];
        }

        return $this->generateResponse('Success', '', $users);
    }

    public function saveNewUser(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'firstname'         => 'required|string|max:255',
            'lastname'          => 'required|string|max:255',
            'personalEmail'     => 'nullable|email',
            'workEmail'         => 'required|email|unique:users,email',
        ],[], [
            'firstname'     => 'First name',
            'lastname'      => 'Last name',
            //'personalEmail' => 'Personal E-Mail',
            'workEmail'     => 'Work E-Mail'
        ]);

        if ($validator->fails()) {
            return $this->generateResponse('Error', 'Validation Error.', [$validator->errors()]);
        }

        $user = new User();
        $user->firstname            = $request->input('firstname');
        $user->lastname             = $request->input('lastname');
        $user->personal_email       = $request->input('personalEmail');
        $user->email                = $request->input('workEmail');
        $user->password             = Hash::make(self::generateRandomString());
        $user->jobRole              = !empty($request->input('NewUserJobRole')) ? $request->input('NewUserJobRole') : 0;
        $user->role                 = 4;
        $user->save();

        foreach (RoleToolRelation::where('role_id', $user->jobRole)->get() as $roleTool) {
            $userToolSetup = new UserToolSetup();
            $userToolSetup->user_id = $user->id;
            $userToolSetup->tool_id = $roleTool->tool_id;
            $userToolSetup->tool_option_id = $roleTool->tool_option_id;
            $userToolSetup->status = 0;
            $userToolSetup->isPassboltLink = 0;
            $userToolSetup->save();
        }

        foreach ($request->input('AdditionalTools') as $additionalTool) {
            $userToolSetup = new UserToolSetup();
            $userToolSetup->user_id = $user->id;
            $userToolSetup->tool_id = $additionalTool['tool'];
            $userToolSetup->tool_option_id = json_encode($additionalTool["role"]);
            $userToolSetup->status = 0;
            $userToolSetup->isPassboltLink = 0;
            $userToolSetup->save();
        }

        foreach (Tool::default() as $defaultTool) {
            $userToolSetup = new UserToolSetup();
            $userToolSetup->user_id = $user->id;
            $userToolSetup->tool_id = $defaultTool->id;
            $userToolSetup->tool_option_id = json_encode([0]);
            $userToolSetup->status = 0;
            $userToolSetup->isPassboltLink = 0;
            $userToolSetup->save();
        }

        $userAccessLink = new UserAccessLink();
        $userAccessLink->user_id    = $user->id;
        $userAccessLink->link_hash  = self::generateRandomString(120);
        $userAccessLink->expires_at = Carbon::now()->addMinutes(5);
        $userAccessLink->save();

        $data = array('link'=>env('APP_URL')."/user/activate/".$userAccessLink->user_id ."/". $userAccessLink->link_hash);

        //Mail::send(['text'=>'mails.mail'], $data, function($message) use($user) {
            //$message->to($user->personal_email, $user->firstname.' '.$user->lastname)->subject
               //('Ha Teams Activation Link');
         //});

        $appUrl = config('app.url'); 
        SlackAlert::message("Request for creating user: <{$appUrl}/access-manager-process-usser/{$user->id}|{$user->firstname} {$user->lastname}>");

        return $this->generateResponse('Success', '', []);
    }

    
    
    public function activateAccountView($userId, $randString)
    {
        Auth::logout();
        $userAccessLink = UserAccessLink::where('user_id', $userId)->where('link_hash', $randString)->firstOrFail();
        if (Carbon::parse($userAccessLink->expires_at)->isPast()) {
            abort(404);
        } else {
            $user = User::find($userId);
            return view('users.activate')
            ->with('email', $user->email);
        }
    }

    public function activateAccount($userId, $randString, Request $request)
    {
        $userAccessLink = UserAccessLink::where('user_id', $userId)->where('link_hash', $randString)->firstOrFail();
        if (Carbon::parse($userAccessLink->expires_at)->isPast()) {
            abort(404);
        } else {
            $user = User::find($userId);
            $user->password = Hash::make($request->input('password'));
            $user->save();
            $userAccessLink->delete();

            return redirect()->route('login');
        }
    }

    public function deleteUser($ID)
    {
        $user = User::find($ID);
        if (!empty($user)) {
            $user->setupDone = 2;
            $user->save();

            $user->toolsSetup()->where('status', 0)->delete();
            if ($user->toolsSetup()->count() > 0) {
                $user->toolsSetup()->update(['status' => 2]);
            } else {
                $user->delete();
            }

        } else {
            return $this->generateResponse('Error', 'User with ID: '.$ID.' not found.', []);
        }
        return $this->generateResponse('Success', 'User delete requeste created.', []);
    }

    public function detailsUser($ID)
    {
        $formattedData = [];
        $user = User::find($ID);
        if (!empty($user)) {

            $formattedData['userDetails'] = [
                'id'                => $user->id,
                'firstname'         => $user->firstname,
                'lastname'          => $user->lastname,
                'email'             => $user->email,
                'personalEmail'     => $user->personal_email,
                'jobRole'           => $user->jobRole,
            ];

            $formattedData['userTools'] = $user->userTools();

        } else {
            return $this->generateResponse('Error', 'User with ID: '.$ID.' not found.', []);
        }
        return $this->generateResponse('Success', '', $formattedData);
    }

    public function editUser($ID, Request $request)
    {
        $updateRequired = 0;
        $user = User::find($ID);
        if (!empty($user)) {
            $validator = Validator::make($request->all(), [
                'firstname'         => 'required|string|max:255',
                'lastname'          => 'required|string|max:255',
                'personalEmail'     => 'nullable|email',
                'workEmail'         => 'required|email',
            ],[], [
                'firstname'     => 'First name',
                'lastname'      => 'Last name',
                'personalEmail' => 'Personal E-Mail',
                'workEmail'     => 'Work E-Mail'
            ]);
    
            if ($validator->fails()) {
                return $this->generateResponse('Error', 'Validation Error.', [$validator->errors()]);
            }

            $user->firstname        = $request->input('firstname');
            $user->lastname         = $request->input('lastname');
            $user->email            = $request->input('workEmail');
            $user->personal_email   = $request->input('personalEmail');
            $user->jobRole          = $request->input('NewUserJobRole');
            $user->save();

            foreach ($request->input('AdditionalTools') as $additionalTool) {
                $userToolSetup = new UserToolSetup();
                $userToolSetup->user_id = $user->id;
                $userToolSetup->tool_id = $additionalTool['tool'];
                $userToolSetup->tool_option_id = json_encode($additionalTool["role"]);
                $userToolSetup->status = 0;
                $userToolSetup->isPassboltLink = 0;
                $userToolSetup->save();
                $updateRequired = 1;
            }

            foreach ($request->input('ToolsDelete') as $toolToDelete) {
                $tool = $user->toolsSetup()->where('tool_id', $toolToDelete['tool'])->first();

                if ($tool->status == 0) {
                    $tool->delete();
                } else {
                    $tool->status = 2;
                    $tool->save();
                    $updateRequired = 1;
                }
            }

            if ($updateRequired == 1) {
                $user->setupDone = 3;
                $user->save();
            }

        } else {
            return $this->generateResponse('Error', 'User with ID: '.$ID.' not found.', []);
        }
        return $this->generateResponse('Success', 'User updated.', []);
    }

    public static function generateRandomString($length = 14) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $randomString = '';
    
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, strlen($characters) - 1)];
        }
    
        return $randomString;
    } 
}
