<?php

namespace App\Livewire\Admin;

use App\Services\FlashMessageService;
use Livewire\Component;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class RoleForm extends Component
{
    public $roleId;
    public $editMode = false;
    public $name = '';
    public $selectedPermissions = [];

    protected $rules = [
        'name' => 'required|string|max:255|unique:roles,name',
        'selectedPermissions' => 'array',
    ];

    protected $messages = [
        'name.required' => 'Role name is required.',
        'name.unique' => 'This role name already exists.',
        'name.max' => 'Role name must not exceed 255 characters.',
    ];

    public function mount($roleId = null)
    {
        if ($roleId) {
            $this->roleId = $roleId;
            $this->editMode = true;
            $this->loadRole();
            $this->rules['name'] = 'required|string|max:255|unique:roles,name,' . $roleId;
        }
    }

    public function loadRole()
    {
        $role = Role::findOrFail($this->roleId);
        $this->name = $role->name;
        $this->selectedPermissions = $role->permissions->pluck('id')->toArray();
        
        // Debug logging
        \Log::info('Role loaded - roleId: ' . $this->roleId);
        \Log::info('Role loaded - selectedPermissions: ' . json_encode($this->selectedPermissions));
    }

    public function updated($propertyName)
    {
        // Update validation rules for edit mode when validating
        if ($this->editMode && $propertyName === 'name') {
            $this->rules['name'] = 'required|string|max:255|unique:roles,name,' . $this->roleId;
        }
        
        // Debug logging for selectedPermissions updates
        if ($propertyName === 'selectedPermissions') {
            \Log::info('selectedPermissions updated: ' . json_encode($this->selectedPermissions));
        }
        
        $this->validateOnly($propertyName);
    }

    public function save()
    {
        // Check permissions
        if ($this->editMode && !auth()->user()->can('roles.edit')) {
            FlashMessageService::insufficientPermissions();
            
            // Dispatch flash message event
            $this->dispatch('flashMessage', 'error', 'You do not have permission to edit roles.', 'Insufficient Permissions', 8000);
            
            return;
        } elseif (!$this->editMode && !auth()->user()->can('roles.create')) {
            FlashMessageService::insufficientPermissions();
            
            // Dispatch flash message event
            $this->dispatch('flashMessage', 'error', 'You do not have permission to create roles.', 'Insufficient Permissions', 8000);
            
            return;
        }

        // Update validation rules for edit mode
        if ($this->editMode) {
            $this->rules['name'] = 'required|string|max:255|unique:roles,name,' . $this->roleId;
        }

        $this->validate();

        try {
            if ($this->editMode) {
                $role = Role::findOrFail($this->roleId);
                
                // Prevent editing Owner role name
                if ($role->name === 'Owner' && $this->name !== 'Owner') {
                    FlashMessageService::error('Cannot change the name of the Owner role!', 'Protected Role');
                    
                    // Dispatch flash message event
                    $this->dispatch('flashMessage', 'error', 'Cannot change the name of the Owner role!', 'Protected Role', 8000);
                    
                    return;
                }
                
                $role->update(['name' => $this->name]);
                
                // Convert permission IDs to permission names for sync
                $validPermissionIds = array_filter($this->selectedPermissions, function($permissionId) {
                    return is_numeric($permissionId) && $permissionId > 0;
                });
                
                $permissionNames = \Spatie\Permission\Models\Permission::whereIn('id', $validPermissionIds)->pluck('name')->toArray();
                
                // Debug logging
                \Log::info('Role update - selectedPermissions: ' . json_encode($this->selectedPermissions));
                \Log::info('Role update - validPermissionIds: ' . json_encode($validPermissionIds));
                \Log::info('Role update - permissionNames: ' . json_encode($permissionNames));
                
                $role->syncPermissions($permissionNames);
                
                FlashMessageService::success('Role updated successfully!', 'Success');
                
                // Dispatch flash message event
                $this->dispatch('flashMessage', 'success', 'Role updated successfully!', 'Success', 5000);
            } else {
                $role = Role::create(['name' => $this->name]);
                
                // Convert permission IDs to permission names for sync
                $validPermissionIds = array_filter($this->selectedPermissions, function($permissionId) {
                    return is_numeric($permissionId) && $permissionId > 0;
                });
                
                $permissionNames = \Spatie\Permission\Models\Permission::whereIn('id', $validPermissionIds)->pluck('name')->toArray();
                
                // Debug logging
                \Log::info('Role create - selectedPermissions: ' . json_encode($this->selectedPermissions));
                \Log::info('Role create - validPermissionIds: ' . json_encode($validPermissionIds));
                \Log::info('Role create - permissionNames: ' . json_encode($permissionNames));
                
                $role->syncPermissions($permissionNames);
                
                FlashMessageService::success('Role created successfully!', 'Success');
                
                // Dispatch flash message event
                $this->dispatch('flashMessage', 'success', 'Role created successfully!', 'Success', 5000);
            }

            return redirect()->route('admin.roles');

        } catch (\Exception $e) {
            if ($this->editMode) {
                FlashMessageService::error('Failed to update role. Please try again.', 'Error');
                
                // Dispatch flash message event with more specific error
                $errorMessage = 'Failed to update role. Error: ' . $e->getMessage();
                $this->dispatch('flashMessage', 'error', $errorMessage, 'Error', 8000);
            } else {
                FlashMessageService::error('Failed to create role. Please try again.', 'Error');
                
                // Dispatch flash message event with more specific error
                $errorMessage = 'Failed to create role. Error: ' . $e->getMessage();
                $this->dispatch('flashMessage', 'error', $errorMessage, 'Error', 8000);
            }
            \Log::error('Role form save error: ' . $e->getMessage());
            \Log::error('Role form save error - selectedPermissions: ' . json_encode($this->selectedPermissions));
        }
    }

    public function cancel()
    {
        return redirect()->route('admin.roles');
    }

    public function render()
    {
        $permissions = Permission::all()->groupBy(function ($permission) {
            $parts = explode('.', $permission->name);
            return $parts[0] ?? 'general';
        });

        return view('livewire.admin.role-form', [
            'permissions' => $permissions
        ]);
    }
}
