<?php

namespace App\Livewire\Users;

use Livewire\Component;
use App\Models\User;
use App\Models\Role;
use App\Models\Permission;

class ManageRolesPermissions extends Component
{

    public User $user;
    public $selectedRoles = [];
    public $selectedPermissions = [];
    public $branchCode = '';
    public $expiresAt = '';
    public $notes = '';
    public $activeTab = 'roles';

    // Bulk operations
    public $bulkRoleIds = [];
    public $bulkPermissionIds = [];
    public $bulkAction = '';

    protected $rules = [
        'selectedRoles' => 'array',
        'selectedPermissions' => 'array',
        'branchCode' => 'required|string|max:10',
        'expiresAt' => 'nullable|date|after:today',
        'notes' => 'nullable|string|max:500',
    ];

    public function mount(User $user)
    {
        
        $this->user = $user->load('customer');
        $this->branchCode = $user->branch_code ?? auth()->user()->branch_code ?? '';
        
        // Load current roles
        $this->selectedRoles = $user->roles()
            ->where('user_roles.is_active', true)
            ->where(function ($q) {
                $q->whereNull('user_roles.expires_at')
                  ->orWhere('user_roles.expires_at', '>', now());
            })
            ->pluck('roles.id')
            ->toArray();

        // Load current direct permissions
        $this->selectedPermissions = $user->permissions()
            ->where('user_permissions.granted', true)
            ->where(function ($q) {
                $q->whereNull('user_permissions.expires_at')
                  ->orWhere('user_permissions.expires_at', '>', now());
            })
            ->pluck('permissions.id')
            ->toArray();
    }

    public function render()
    {
        $roles = Role::where('is_active', true)
                   ->with('permissions')
                   ->get();
        
        $permissions = Permission::where('is_active', true)
                                ->orderBy('module')
                                ->orderBy('name')
                                ->get();
        
        $permissionsByModule = $permissions->groupBy('module');
        
        // Get user's current roles with details
        $currentRoles = $this->user->roles()
            ->where('user_roles.is_active', true)
            ->withPivot(['branch_code', 'assigned_at', 'expires_at'])
            ->get();

        // Get user's current direct permissions with details
        $currentPermissions = $this->user->permissions()
            ->where('user_permissions.granted', true)
            ->withPivot(['branch_code', 'assigned_at', 'expires_at'])
            ->get();

        // Get all effective permissions
        $allPermissions = $this->user->getAllPermissions($this->branchCode);
        $effectivePermissionsByModule = $allPermissions->groupBy('module');

        return view('livewire.users.manage-roles-permissions', [
            'availableRoles' => $roles,
            'permissions' => $permissions,
            'groupedPermissions' => $permissionsByModule,
            'currentRoles' => $currentRoles,
            'currentPermissions' => $currentPermissions,
            'effectivePermissionsByModule' => $effectivePermissionsByModule,
        ]);
    }

    public function setActiveTab($tab)
    {
        $this->activeTab = $tab;
    }

    public function updateRoles()
    {
        $this->validate();

        try {
            // Sync roles with additional data
            $roleData = [];
            foreach ($this->selectedRoles as $roleId) {
                $roleData[$roleId] = [
                    'branch_code' => $this->branchCode,
                    'is_active' => true,
                    'assigned_at' => now(),
                    'expires_at' => $this->expiresAt ? $this->expiresAt : null,
                ];
            }
            
            $this->user->roles()->sync($roleData);
            
            session()->flash('success', 'User roles updated successfully!');
            $this->user->refresh();

        } catch (\Exception $e) {
            session()->flash('error', 'Failed to update roles: ' . $e->getMessage());
        }
    }

    public function updatePermissions()
    {
        $this->validate();

        try {
            // Sync direct permissions
            $permissionData = [];
            foreach ($this->selectedPermissions as $permissionId) {
                $permissionData[$permissionId] = [
                    'granted' => true,
                    'branch_code' => $this->branchCode,
                    'assigned_at' => now(),
                    'expires_at' => $this->expiresAt ? $this->expiresAt : null,
                ];
            }
            
            $this->user->permissions()->sync($permissionData);
            
            session()->flash('success', 'User permissions updated successfully!');
            $this->user->refresh();

        } catch (\Exception $e) {
            session()->flash('error', 'Failed to update permissions: ' . $e->getMessage());
        }
    }

    public function addRole($roleId)
    {
        
        if (!in_array($roleId, $this->selectedRoles)) {
            $this->selectedRoles[] = $roleId;
        }
    }

    public function removeRole($roleId)
    {
        
        $this->selectedRoles = array_filter($this->selectedRoles, fn($id) => $id != $roleId);
    }

    public function addPermission($permissionId)
    {
        
        if (!in_array($permissionId, $this->selectedPermissions)) {
            $this->selectedPermissions[] = $permissionId;
        }
    }

    public function removePermission($permissionId)
    {
        
        $this->selectedPermissions = array_filter($this->selectedPermissions, fn($id) => $id != $permissionId);
    }

    public function selectAllPermissionsInModule($module)
    {
        $modulePermissions = Permission::where('module', $module)
                                     ->where('is_active', true)
                                     ->pluck('id')
                                     ->toArray();
        
        $this->selectedPermissions = array_unique(array_merge($this->selectedPermissions, $modulePermissions));
    }

    public function deselectAllPermissionsInModule($module)
    {
        $modulePermissions = Permission::where('module', $module)
                                     ->pluck('id')
                                     ->toArray();
        
        $this->selectedPermissions = array_diff($this->selectedPermissions, $modulePermissions);
    }

    public function copyRolesFromUser($sourceUserId)
    {
        
        try {
            $sourceUser = User::findOrFail($sourceUserId);
            $sourceRoles = $sourceUser->roles()
                ->where('user_roles.is_active', true)
                ->pluck('roles.id')
                ->toArray();
            
            $this->selectedRoles = $sourceRoles;
            session()->flash('success', 'Roles copied from ' . $sourceUser->name);
            
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to copy roles: ' . $e->getMessage());
        }
    }

    public function presetForRole($roleType)
    {
        $presets = [
            'admin' => Role::where('name', 'admin')->pluck('id')->toArray(),
            'manager' => Role::whereIn('name', ['manager', 'service_supervisor'])->pluck('id')->toArray(),
            'technician' => Role::where('name', 'technician')->pluck('id')->toArray(),
            'advisor' => Role::where('name', 'service_advisor')->pluck('id')->toArray(),
        ];

        if (isset($presets[$roleType])) {
            $this->selectedRoles = $presets[$roleType];
        }
    }

    public function bulkExecute()
    {
        
        try {
            switch ($this->bulkAction) {
                case 'add_roles':
                    foreach ($this->bulkRoleIds as $roleId) {
                        if (!in_array($roleId, $this->selectedRoles)) {
                            $this->selectedRoles[] = $roleId;
                        }
                    }
                    break;
                    
                case 'remove_roles':
                    $this->selectedRoles = array_diff($this->selectedRoles, $this->bulkRoleIds);
                    break;
                    
                case 'add_permissions':
                    foreach ($this->bulkPermissionIds as $permissionId) {
                        if (!in_array($permissionId, $this->selectedPermissions)) {
                            $this->selectedPermissions[] = $permissionId;
                        }
                    }
                    break;
                    
                case 'remove_permissions':
                    $this->selectedPermissions = array_diff($this->selectedPermissions, $this->bulkPermissionIds);
                    break;
            }
            
            session()->flash('success', 'Bulk operation completed successfully!');
            
        } catch (\Exception $e) {
            session()->flash('error', 'Bulk operation failed: ' . $e->getMessage());
        }
    }

    public function resetToDefault()
    {
        // Reset to basic role based on user's department/position
        $defaultRoles = [];
        
        switch ($this->user->department) {
            case 'Service':
                $defaultRoles = Role::whereIn('name', ['service_advisor'])->pluck('id')->toArray();
                break;
            case 'Technician':
                $defaultRoles = Role::where('name', 'technician')->pluck('id')->toArray();
                break;
            case 'Parts':
                $defaultRoles = Role::where('name', 'parts_manager')->pluck('id')->toArray();
                break;
            case 'Management':
                $defaultRoles = Role::where('name', 'manager')->pluck('id')->toArray();
                break;
        }
        
        $this->selectedRoles = $defaultRoles;
        $this->selectedPermissions = [];
    }

    public function applyRolePreset($roleType)
    {
        
        // Define role presets
        $presets = [
            'manager' => [
                'roles' => ['manager', 'senior_technician'],
                'permissions' => [] // Manager gets permissions through role
            ],
            'technician' => [
                'roles' => ['technician'],
                'permissions' => [] // Technician gets permissions through role
            ],
            'receptionist' => [
                'roles' => ['receptionist'],
                'permissions' => [] // Receptionist gets permissions through role
            ],
            'parts_clerk' => [
                'roles' => ['parts_manager'],
                'permissions' => [] // Parts clerk gets permissions through role
            ],
            'customer_portal' => [
                'roles' => ['customer_portal'],
                'permissions' => [] // Customer portal gets basic customer permissions through role
            ]
        ];

        if (!isset($presets[$roleType])) {
            session()->flash('error', 'Invalid role preset.');
            return;
        }

        $preset = $presets[$roleType];
        
        // Get role IDs
        $roleIds = Role::whereIn('name', $preset['roles'])->pluck('id')->toArray();
        $this->selectedRoles = $roleIds;
        
        // Get permission IDs if any
        if (!empty($preset['permissions'])) {
            $permissionIds = Permission::whereIn('name', $preset['permissions'])->pluck('id')->toArray();
            $this->selectedPermissions = $permissionIds;
        } else {
            $this->selectedPermissions = [];
        }

        session()->flash('success', 'Applied ' . ucfirst(str_replace('_', ' ', $roleType)) . ' preset successfully.');
    }

    public function selectAllPermissions()
    {
        $this->selectedPermissions = Permission::where('is_active', true)->pluck('id')->toArray();
    }

    public function deselectAllPermissions()
    {
        $this->selectedPermissions = [];
    }

    public function selectModulePermissions($module)
    {
        $modulePermissions = Permission::where('is_active', true)
            ->where('module', $module)
            ->pluck('id')
            ->toArray();
        
        $this->selectedPermissions = array_unique(array_merge($this->selectedPermissions, $modulePermissions));
    }

    public function deselectModulePermissions($module)
    {
        $modulePermissions = Permission::where('is_active', true)
            ->where('module', $module)
            ->pluck('id')
            ->toArray();
        
        $this->selectedPermissions = array_diff($this->selectedPermissions, $modulePermissions);
    }

    public function removeAllRoles()
    {
        
        try {
            $this->user->roles()->detach();
            session()->flash('success', 'All roles removed successfully.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to remove roles: ' . $e->getMessage());
        }
    }

    public function removeAllPermissions()
    {
        
        try {
            $this->user->permissions()->detach();
            session()->flash('success', 'All direct permissions removed successfully.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to remove permissions: ' . $e->getMessage());
        }
    }

    public function isCustomerPortalUser()
    {
        return $this->user->customer !== null;
    }

    public function getRecommendedRoleForCustomer()
    {
        return $this->user->customer ? 'customer_portal' : null;
    }

    public function hasCustomerPortalRole()
    {
        return $this->user->hasRole('customer_portal');
    }
}
