<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use App\Helpers\AuditLogger;

class RoleController extends Controller
{
    public function index()
    {
        $roles = Role::with('permissions')->get();
        $permissions = Permission::all();
        return view('roles.index', compact('roles', 'permissions'));
    }

    public function create()
    {
        $permissions = Permission::all();
        return view('roles.create', compact('permissions'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|unique:roles,name',
            'permissions' => 'array',
            'permissions.*' => 'exists:permissions,id'
        ]);

        try {
            $role = Role::create(['name' => $request->name]);
            if ($request->permissions) {
                $role->permissions()->sync($request->permissions);
            }

            AuditLogger::log('role', $role->id, 'created', null, [
                'id' => $role->id,
                'name' => $role->name,
                'permissions' => $role->permissions()->pluck('name')->toArray(),
            ]);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return redirect()->route('roles.index')
                ->withErrors($e->validator)
                ->withInput();
        } catch (\Exception $e) {
            return redirect()->route('roles.index')->with('error', 'An error occurred while creating the role.');
        }

        return redirect()->route('roles.index')->with('message', 'Role created successfully!');
    }

    public function edit($id)
    {
        $role = Role::findOrFail($id);
        $permissions = Permission::all();
        return view('roles.edit', compact('role', 'permissions'));
    }

    public function update(Request $request, $id)
    {
        $role = Role::findOrFail($id);
        $before = [
            'id' => $role->id,
            'name' => $role->name,
            'permissions' => $role->permissions()->pluck('name')->toArray(),
        ];

        $request->validate([
            'name' => 'required|unique:roles,name,' . $role->id,
            'permissions' => 'array',
            'permissions.*' => 'exists:permissions,id'
        ]);

        $role->name = $request->name;
        $role->save();
        
        // Use permission IDs with the permissions() relationship
        $role->permissions()->sync($request->permissions ?? []);

        AuditLogger::log('role', $role->id, 'updated', $before, [
            'id' => $role->id,
            'name' => $role->name,
            'permissions' => $role->permissions()->pluck('name')->toArray(),
        ]);

        return redirect()->route('roles.index')->with('message', 'Role updated successfully!');
    }

    public function show($id)
    {
        $role = Role::with('permissions')->findOrFail($id);
        return view('roles.show', compact('role'));
    }

    public function destroy($id)
    {
        try {
            $role = Role::findOrFail($id);
            $before = [
                'id' => $role->id,
                'name' => $role->name,
                'permissions' => $role->permissions()->pluck('name')->toArray(),
            ];
            
            // Check if role is assigned to users
            $usersWithRole = \DB::table('model_has_roles')
                ->where('role_id', $id)
                ->exists();
                
            if ($usersWithRole) {
                AuditLogger::log('role', $role->id, 'delete_blocked', $before, [
                    'reason' => 'Role is assigned to one or more users',
                ]);

                return redirect()->route('roles.index')
                    ->with('error', 'Cannot delete role. This role is assigned to users. Please remove this role from all users first.');
            }
            
            // Check if role is used in folder permissions
            $folderPermissions = \DB::table('folder_user_permissions')
                ->where('role_id', $id)
                ->exists();
                
            if ($folderPermissions) {
                AuditLogger::log('role', $role->id, 'delete_blocked', $before, [
                    'reason' => 'Role is used in folder permissions',
                ]);

                return redirect()->route('roles.index')
                    ->with('error', 'Cannot delete role. This role is used in folder permissions. Please remove this role from all folder permissions first.');
            }
            
            // If no constraints, delete the role
            $role->delete();

            AuditLogger::log('role', $id, 'deleted', $before, null);
            
            return redirect()->route('roles.index')
                ->with('message', 'Role deleted successfully!');
                
        } catch (\Illuminate\Database\QueryException $e) {
            // Handle foreign key constraint violations
            if ($e->getCode() == 23000) {
                return redirect()->route('roles.index')
                    ->with('error', 'Cannot delete role. This role is being used elsewhere in the system. Please remove all references first.');
            }
            
            return redirect()->route('roles.index')
                ->with('error', 'An error occurred while deleting the role.');
        } catch (\Exception $e) {
            return redirect()->route('roles.index')
                ->with('error', 'An unexpected error occurred while deleting the role.');
        }
    }
}

