<?php

namespace App\Http\Controllers;

use App\Models\Tool;
use App\Models\Department;
use App\Models\RoleToolRelation;
use App\Models\ToolAdditionalOption;
use App\Models\User;
use App\Models\UserToolSetup;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

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

    public function new(Request $request) 
    {
        $validator = Validator::make($request->all(), [
            'RoleName'      => 'required|string|max:255',
        ],[], [
            'RoleName' => 'Role Name'
        ]);

        if ($validator->fails()) {
            return $this->generateResponse('Error', 'Validation Error.', [$validator->errors()]);
        }
        
        $role = new Department();
        $role->name = $request->input('RoleName');
        $role->save();

        foreach ($request->input('RoleTools') as $roleTool) {
            $tool = Tool::byID($roleTool["tool"]);
            //$toolAdditionalOption = ToolAdditionalOption::byToolAndOptionIDAndType($tool->id, $roleTool["role"], 'Role');

            $roleToolRelation = new RoleToolRelation();
            $roleToolRelation->role_id          = $role->id;
            $roleToolRelation->tool_id          = $tool->id;
            $roleToolRelation->tool_option_id   = json_encode($roleTool["role"]);
            $roleToolRelation->save();
        }

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

    public function load()
    {
        $departments = [];

        foreach (Department::all() as $role) {
            $departments[] = [
                'id'            => $role->id,
                'name'          => $role->name,
                'userAssing'    => $role->users()->count(),
            ];
        }

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

    public function loadTools()
    {
        $departments = Tool::all();

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

    public function loadNodefaultTools()
    {
        $departments = Tool::where('defaultTool', '!=', 1)->get();

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

    public function loadToolsRoles()
    {
        $formattedArray = [];
        $tools = Tool::all();

        foreach ($tools as $tool) {
            $formattedArray[$tool->id] =  $tool->roles()->get()->toArray();
        }

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

    public function newTool(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'ToolName'      => 'required|string|max:255',
            'ToolUrl'       => 'nullable|url',
            'onlineTool'    => 'required|in:Yes,No',
            'toolHas2FA'    => 'required|in:Yes,No',
            'defaultTool'   => 'required|in:Yes,No',
        ],[], [
            'ToolName' => 'Tool Name',
            'ToolUrl'  => 'Tool Url',
        ]);

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

        $tool = new Tool();
        $tool->name         = $request->input('ToolName');
        $tool->onlineTool   = $request->input('onlineTool') == 'Yes' ? 1 : 0;
        $tool->has2FA       = $request->input('toolHas2FA') == 'Yes' ? 1 : 0;
        $tool->defaultTool  = $request->input('defaultTool') == 'Yes' ? 1 : 0;
        $tool->url          = !empty($request->input('ToolUrl')) ? $request->input('ToolUrl') : '';
        $tool->save();

        if (!empty($request->input('ToolRoles') )) {
            foreach ($request->input('ToolRoles') as $option) {
                $ToolAdditionalOption = new ToolAdditionalOption();
                $ToolAdditionalOption->tool_id = $tool->id;
                $ToolAdditionalOption->type   = 'Role';
                $ToolAdditionalOption->option = $option['role'];
                $ToolAdditionalOption->save();
            }
        } else {
                $ToolAdditionalOption = new ToolAdditionalOption();
                $ToolAdditionalOption->tool_id = $tool->id;
                $ToolAdditionalOption->type   = 'Role';
                $ToolAdditionalOption->option = 'None';
                $ToolAdditionalOption->save();
        }

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

    public function loadJobRoleTools($roleID)
    {
        $formattedTools = [];
        foreach (Tool::default() as $defaultTool) {
            $formattedTools[] = [
                'toolName' => $defaultTool->name,
                //'toolRole' => $defaultTool->roles()->first()->option
            ];
        }

        if ($roleID != 0) {
            foreach (RoleToolRelation::where('role_id', $roleID)->get() as $roleRelation) {
                $formattedTools[] = [
                    'toolName' => $roleRelation->tool()->first()->name,
                    //'toolRole' => $roleRelation->toolOption()->first()->option
                ];
            }
        }
        return $this->generateResponse('Success', '', $formattedTools);
    }

    public function deleteRole($roleID)
    {
        $role = Department::find($roleID);

        if (!empty($role)) {
            $roleTools = $role->tools()->get();
            foreach ($roleTools as $roleTool) {
                $roleTool->delete();
            }
            User::where(['jobRole' => $roleID])->update(['jobRole' => 0]);
            $role->delete();
        } else {
            return $this->generateResponse('Error', 'Role not found.', []);
        }
        return $this->generateResponse('Success', 'Role deleted.', []);
    }

    public function editRole($roleID, Request $request)
    {
        $role = Department::find($roleID);

        if (!empty($role)) {
            $validator = Validator::make($request->all(), [
                'RoleName'      => 'required|string|max:255',
            ],[], [
                'RoleName' => 'Role Name'
            ]);
    
            if ($validator->fails()) {
                return $this->generateResponse('Error', 'Validation Error.', [$validator->errors()]);
            }

            $role->name = $request->input('RoleName');
            $role->save();

            $role->tools()->delete();

            if (!empty($request->input('RoleTools'))) {
                foreach ($request->input('RoleTools') as $roleTool) {
                    $tool = Tool::byID($roleTool["tool"]);
                    //$toolAdditionalOption = ToolAdditionalOption::byToolAndOptionIDAndType($tool->id, $roleTool["role"], 'Role');
        
                    $roleToolRelation = new RoleToolRelation();
                    $roleToolRelation->role_id          = $role->id;
                    $roleToolRelation->tool_id          = $tool->id;
                    $roleToolRelation->tool_option_id   = json_encode($roleTool["role"]);
                    $roleToolRelation->save();
                }
            }
        } else {
            return $this->generateResponse('Error', 'Role not found.', []);
        }
        return $this->generateResponse('Success', 'Role edited.', []);
    }

    public function loadRoleDetails($roleID)
    {
        $formattedTools = [];
        $role = Department::find($roleID);
        if (!empty($role)) {
            foreach ($role->tools()->get() as $roleTool) {
                $formattedRoles = [];
                $roles = json_decode($roleTool->tool_option_id);

                foreach ($roles as $rol) {
                    $formattedRoles[] = (int) $rol;
                }

                $formattedTools[] = [
                    'tool' => $roleTool->tool_id,
                    'role' => $formattedRoles
                ];
            }
        } else {
            return $this->generateResponse('Error', 'Role not found.', []);
        }
        return $this->generateResponse('Success', '', $formattedTools);
    }

    public function deleteTool($id)
    {
        $tool = Tool::find($id);

        if (!empty($tool)) {
            if ($tool->userTools()->count() <= 0) {
                $tool->additionaRoles()->delete();
                $tool->delete();
            } else {
                return $this->generateResponse('Error', 'Tool is already assingned to users.', []);
            }
        } else {
            return $this->generateResponse('Error', 'Tool with ID: '.$id.' not found.', []);
        }
        return $this->generateResponse('Success', 'Tool: '.$tool->name.' deleted.', []);
    }

    public function loadToolDetails($id)
    {
        $formattedData = [];
        $tool = Tool::find($id);
        if (!empty($tool)) {
            $formattedData = [
                'toolName'      => $tool->name,
                'toolUrl'       => $tool->url,
                'onlineTool'    => $tool->onlineTool == 1 ? 'Yes' : 'No',
                'has2FA'        => $tool->has2FA == 1 ? 'Yes' : 'No',
                'defaultTool'   => $tool->defaultTool == 1 ? 'Yes' : 'No',
            ];

            $toolRoles = $tool->additionaRoles()->get();
            $formattedToolRoles = [];
            foreach ($toolRoles as $toolRole) {
                $formattedToolRoles[] = [
                    'ID'        => $toolRole->id,
                    'role'      => $toolRole->option,
                    'assingned' => self::ChackIfToolRoleAssigned($toolRole->id)
                ];
            }
            $formattedData['toolRoles'] = $formattedToolRoles;

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

    public function editTool($ID, Request $request)
    {
        $tool = Tool::find($ID);
        if (!empty($tool)) {

            $validator = Validator::make($request->all(), [
                'ToolName'      => 'required|string|max:255',
                'ToolUrl'       => 'nullable|url',
                'onlineTool'    => 'required|in:Yes,No',
                'toolHas2FA'    => 'required|in:Yes,No',
                'defaultTool'   => 'required|in:Yes,No',
            ],[], [
                'ToolName' => 'Tool Name',
                'ToolUrl'  => 'Tool Url',
            ]);

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

            $tool->name         = $request->input('ToolName');
            $tool->url          = !empty($request->input('ToolUrl')) ? $request->input('ToolUrl') : '';
            $tool->onlineTool   = $request->input('onlineTool') == 'Yes' ? 1 : 0;
            $tool->has2FA       = $request->input('toolHas2FA') == 'Yes' ? 1 : 0;
            $tool->defaultTool  = $request->input('defaultTool') == 'Yes' ? 1 : 0;
            $tool->save();

            if (!empty($request->input('ToolRoles') )) {
                foreach ($request->input('ToolRoles') as $option) {
                    if ($option['ID'] == 'new') {
                        $ToolAdditionalOption = new ToolAdditionalOption();
                    } else {
                        $ToolAdditionalOption = ToolAdditionalOption::find($option['ID']);
                    }
                    $ToolAdditionalOption->tool_id = $tool->id;
                    $ToolAdditionalOption->type   = 'Role';
                    $ToolAdditionalOption->option = $option['role'];
                    $ToolAdditionalOption->save();
                }
            } else {
                    $ToolAdditionalOption = new ToolAdditionalOption();
                    $ToolAdditionalOption->tool_id = $tool->id;
                    $ToolAdditionalOption->type   = 'Role';
                    $ToolAdditionalOption->option = 'None';
                    $ToolAdditionalOption->save();
            }

            if (!empty($request->input('deletedRoles') )) {
                foreach ($request->input('deletedRoles') as $option) {
                    ToolAdditionalOption::find($option['ID'])->delete();
                }
            }

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

    public static function ChackIfToolRoleAssigned($roleId) 
    {
        $assignedToRoles = RoleToolRelation::where('tool_option_id',$roleId)->count();
        $assignedToUsers = UserToolSetup::where('tool_option_id',$roleId)->count();

        if ($assignedToUsers > 0 || $assignedToRoles > 0) {
            return 1;
        } else {
            return 0;
        }
    }
}
