<?php

namespace App\Livewire\Users;

use Livewire\Component;
use App\Models\User;
use App\Models\Role;
use App\Models\Permission;
use Illuminate\Support\Facades\Hash;
use Spatie\Activitylog\Models\Activity;

class Show extends Component
{
    public User $user;
    public $activeTab = 'profile';
    public $showRoleModal = false;
    public $showPermissionModal = false;
    public $selectedRole = null;
    public $selectedPermission = null;
    public $showDeleteModal = false;
    public $showImpersonateModal = false;
    public $showActivityModal = false;
    
    // User actions
    public $confirmingAction = false;
    public $pendingAction = '';

    protected $queryString = ['activeTab'];

    public function mount(User $user)
    {
        $this->user = $user->load(['roles.permissions', 'permissions', 'customer']);
    }

    public function render()
    {
        $userRoles = $this->user->roles()
            ->where('user_roles.is_active', true)
            ->where(function ($q) {
                $q->whereNull('user_roles.expires_at')
                  ->orWhere('user_roles.expires_at', '>', now());
            })
            ->withPivot(['branch_code', 'assigned_at', 'expires_at'])
            ->get();

        $userDirectPermissions = $this->user->permissions()
            ->where('user_permissions.granted', true)
            ->where(function ($q) {
                $q->whereNull('user_permissions.expires_at')
                  ->orWhere('user_permissions.expires_at', '>', now());
            })
            ->withPivot(['branch_code', 'assigned_at', 'expires_at'])
            ->get();

        $allPermissions = $this->user->getAllPermissions();
        $permissionsByModule = $allPermissions->groupBy('module');

        // Get role-based permissions
        $rolePermissions = collect();
        foreach ($userRoles as $role) {
            $rolePermissions = $rolePermissions->merge($role->permissions);
        }
        $rolePermissions = $rolePermissions->unique('id');

        // Get recent activity
        $causedByUser = Activity::where('causer_id', $this->user->id)
            ->where('causer_type', User::class)
            ->latest()
            ->limit(10)
            ->get();
            
        $performedOnUser = Activity::where('subject_id', $this->user->id)
            ->where('subject_type', User::class)
            ->latest()
            ->limit(10)
            ->get();
            
        $recentActivity = $causedByUser->merge($performedOnUser)
            ->sortByDesc('created_at')
            ->take(20);

        // Get user metrics
        $metrics = $this->getUserMetrics();

        // Get user's work orders, service orders, etc. (if applicable)
        $workStats = $this->getUserWorkStats();

        return view('livewire.users.show', [
            'userRoles' => $userRoles,
            'userDirectPermissions' => $userDirectPermissions,
            'allPermissions' => $allPermissions,
            'permissionsByModule' => $permissionsByModule,
            'rolePermissions' => $rolePermissions,
            'recentActivity' => $recentActivity,
            'metrics' => $metrics,
            'workStats' => $workStats,
        ]);
    }

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

    public function showRoleDetails($roleId)
    {
        $this->selectedRole = Role::with('permissions')->find($roleId);
        $this->showRoleModal = true;
    }

    public function showPermissionDetails($permissionId)
    {
        $this->selectedPermission = Permission::find($permissionId);
        $this->showPermissionModal = true;
    }

    public function closeModals()
    {
        $this->showRoleModal = false;
        $this->showPermissionModal = false;
        $this->showDeleteModal = false;
        $this->showImpersonateModal = false;
        $this->showActivityModal = false;
        $this->selectedRole = null;
        $this->selectedPermission = null;
    }

    public function removeRole($roleId)
    {
        try {
            $this->user->roles()->detach($roleId);
            $this->user->refresh();
            
            // Log the action
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->withProperties(['role_id' => $roleId])
                ->log('Role removed from user');
                
            session()->flash('success', 'Role removed successfully.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to remove role: ' . $e->getMessage());
        }
    }

    public function removePermission($permissionId)
    {
        try {
            $this->user->permissions()->detach($permissionId);
            $this->user->refresh();
            
            // Log the action
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->withProperties(['permission_id' => $permissionId])
                ->log('Permission removed from user');
                
            session()->flash('success', 'Permission removed successfully.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to remove permission: ' . $e->getMessage());
        }
    }

    public function toggleUserStatus()
    {
        if ($this->user->id === auth()->id()) {
            session()->flash('error', 'You cannot change your own status.');
            return;
        }

        try {
            $newStatus = $this->user->status === 'active' ? 'inactive' : 'active';
            $oldStatus = $this->user->status;
            
            $this->user->update(['status' => $newStatus]);
            
            // Log the action
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->withProperties([
                    'old_status' => $oldStatus,
                    'new_status' => $newStatus,
                ])
                ->log('User status changed');
            
            $statusText = $newStatus === 'active' ? 'activated' : 'deactivated';
            session()->flash('success', "User {$statusText} successfully.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to update status: ' . $e->getMessage());
        }
    }

    public function suspendUser()
    {
        if ($this->user->id === auth()->id()) {
            session()->flash('error', 'You cannot suspend your own account.');
            return;
        }

        try {
            $oldStatus = $this->user->status;
            $this->user->update(['status' => 'suspended']);
            
            // Log the action
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->withProperties([
                    'old_status' => $oldStatus,
                    'new_status' => 'suspended',
                ])
                ->log('User suspended');
            
            session()->flash('success', 'User suspended successfully.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to suspend user: ' . $e->getMessage());
        }
    }

    public function impersonateUser()
    {
        if ($this->user->id === auth()->id()) {
            session()->flash('error', 'You cannot impersonate yourself.');
            return;
        }

        if ($this->user->status !== 'active') {
            session()->flash('error', 'Cannot impersonate inactive user.');
            return;
        }

        try {
            // Log the impersonation start
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->log('Impersonation started');

            // Store original user ID for returning later
            session(['impersonate_original_user' => auth()->id()]);
            auth()->loginUsingId($this->user->id);

            session()->flash('success', 'Now impersonating ' . $this->user->name);
            return redirect()->route('dashboard');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to impersonate user: ' . $e->getMessage());
        }
    }

    public function sendPasswordReset()
    {
        try {
            // Generate a secure temporary password
            $tempPassword = $this->generateSecurePassword();
            
            $this->user->update([
                'password' => Hash::make($tempPassword),
                'password_changed_at' => now(),
            ]);
            
            // Log the action
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->log('Password reset by admin');
            
            // TODO: Send password reset email with new temporary password
            // $this->user->notify(new PasswordResetByAdminNotification($tempPassword));
            
            session()->flash('success', "Password reset successfully. New temporary password: {$tempPassword}");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to reset password: ' . $e->getMessage());
        }
    }

    public function generateSecurePassword($length = 12)
    {
        $uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $lowercase = 'abcdefghijklmnopqrstuvwxyz';
        $numbers = '0123456789';
        $symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';
        
        $password = '';
        $password .= $uppercase[random_int(0, strlen($uppercase) - 1)];
        $password .= $lowercase[random_int(0, strlen($lowercase) - 1)];
        $password .= $numbers[random_int(0, strlen($numbers) - 1)];
        $password .= $symbols[random_int(0, strlen($symbols) - 1)];
        
        $allChars = $uppercase . $lowercase . $numbers . $symbols;
        for ($i = 4; $i < $length; $i++) {
            $password .= $allChars[random_int(0, strlen($allChars) - 1)];
        }
        
        return str_shuffle($password);
    }

    public function exportUserData()
    {
        try {
            // Log the export request
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->log('User data export requested');
                
            // TODO: Implement user data export (GDPR compliance)
            // This should include all user data, activity logs, etc.
            
            session()->flash('success', 'User data export initiated. You will receive an email when ready.');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to export user data: ' . $e->getMessage());
        }
    }

    public function deleteUser()
    {
        if ($this->user->id === auth()->id()) {
            session()->flash('error', 'You cannot delete your own account.');
            return;
        }
        
        try {
            // Log before deletion
            activity()
                ->performedOn($this->user)
                ->causedBy(auth()->user())
                ->withProperties([
                    'deleted_user_data' => [
                        'name' => $this->user->name,
                        'email' => $this->user->email,
                        'employee_id' => $this->user->employee_id,
                    ]
                ])
                ->log('User deleted by admin');
                
            $userName = $this->user->name;
            $this->user->delete();
            
            session()->flash('success', "User '{$userName}' deleted successfully.");
            return redirect()->route('users.index');
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to delete user: ' . $e->getMessage());
        }
        
        $this->showDeleteModal = false;
    }

    public function confirmDelete()
    {
        $this->showDeleteModal = true;
    }

    public function confirmImpersonate()
    {
        $this->showImpersonateModal = true;
    }

    public function getUserMetrics()
    {
        $totalPermissions = $this->user->getAllPermissions()->count();
        $directPermissions = $this->user->permissions()
            ->where('user_permissions.granted', true)
            ->where(function ($q) {
                $q->whereNull('user_permissions.expires_at')
                  ->orWhere('user_permissions.expires_at', '>', now());
            })
            ->count();
        
        $activeRoles = $this->user->roles()
            ->where('user_roles.is_active', true)
            ->where(function ($q) {
                $q->whereNull('user_roles.expires_at')
                  ->orWhere('user_roles.expires_at', '>', now());
            })
            ->count();

        return [
            'total_permissions' => $totalPermissions,
            'direct_permissions' => $directPermissions,
            'role_permissions' => $totalPermissions - $directPermissions,
            'active_roles' => $activeRoles,
            'days_since_created' => $this->user->created_at->diffInDays(now()),
            'last_login' => $this->user->last_login_at ? $this->user->last_login_at->diffForHumans() : 'Never',
            'password_age' => $this->user->password_changed_at ? $this->user->password_changed_at->diffInDays(now()) : null,
        ];
    }

    public function getUserWorkStats()
    {
        // Get work-related statistics for the user
        $stats = [
            'work_orders_assigned' => 0,
            'work_orders_completed' => 0,
            'service_orders_created' => 0,
            'total_revenue_generated' => 0,
        ];

        try {
            // Work orders assigned to user (if technician)
            if (\Schema::hasTable('work_orders')) {
                $stats['work_orders_assigned'] = \DB::table('work_orders')
                    ->where('assigned_technician_id', $this->user->id)
                    ->count();
                
                $stats['work_orders_completed'] = \DB::table('work_orders')
                    ->where('assigned_technician_id', $this->user->id)
                    ->where('status', 'completed')
                    ->count();
            }

            // Service orders created by user (if service advisor)
            if (\Schema::hasTable('service_orders')) {
                $stats['service_orders_created'] = \DB::table('service_orders')
                    ->where('created_by', $this->user->id)
                    ->count();
                
                $stats['total_revenue_generated'] = \DB::table('service_orders')
                    ->where('created_by', $this->user->id)
                    ->where('status', 'completed')
                    ->sum('total_amount') ?? 0;
            }
        } catch (\Exception $e) {
            // Tables might not exist, return default stats
        }

        return $stats;
    }

    public function getStatusBadgeClass($status)
    {
        return match($status) {
            'active' => 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200',
            'inactive' => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200',
            'suspended' => 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200',
            default => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200'
        };
    }

    public function getRoleBadgeClass($roleName)
    {
        return match($roleName) {
            'super_admin' => 'bg-gradient-to-r from-purple-500 to-pink-500 text-white',
            'administrator' => 'bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200',
            'manager' => 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200',
            'service_manager' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200',
            'technician' => 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200',
            'senior_technician' => 'bg-emerald-100 dark:bg-emerald-900 text-emerald-800 dark:text-emerald-200',
            'parts_clerk' => 'bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200',
            'service_advisor' => 'bg-teal-100 dark:bg-teal-900 text-teal-800 dark:text-teal-200',
            'receptionist' => 'bg-pink-100 dark:bg-pink-900 text-pink-800 dark:text-pink-200',
            'cashier' => 'bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200',
            'customer_portal' => 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200',
            'customer' => 'bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200',
            'viewer' => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200',
            default => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200'
        };
    }

    public function canPerformAction($action)
    {
        // Check if current user can perform certain actions on this user
        $currentUser = auth()->user();
        
        // Super admin can do anything
        if ($currentUser->hasRole('super_admin')) {
            return true;
        }

        // Can't perform actions on yourself (except view)
        if ($currentUser->id === $this->user->id && $action !== 'view') {
            return false;
        }

        // Check specific permissions based on action
        return match($action) {
            'edit' => $currentUser->can('users.edit'),
            'delete' => $currentUser->can('users.delete'),
            'impersonate' => $currentUser->can('users.impersonate'),
            'reset_password' => $currentUser->can('users.reset-password'),
            'manage_roles' => $currentUser->can('users.manage-roles'),
            'view_activity' => $currentUser->can('users.view-activity'),
            default => false,
        };
    }

    public function getLastActivityDate()
    {
        $lastActivity = Activity::where('causer_id', $this->user->id)
            ->where('causer_type', User::class)
            ->latest()
            ->first();

        return $lastActivity ? $lastActivity->created_at->diffForHumans() : 'No activity recorded';
    }

    public function getTotalLoginCount()
    {
        // This would require a login tracking system
        return Activity::where('causer_id', $this->user->id)
            ->where('causer_type', User::class)
            ->where('description', 'like', '%login%')
            ->count();
    }
}
