<?php

namespace App\Livewire\Users;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\User;
use App\Models\Role;
use App\Models\Branch;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class Index extends Component
{
    use WithPagination;

    // Search and filtering
    public $search = '';
    public $roleFilter = '';
    public $statusFilter = '';
    public $departmentFilter = '';
    public $branchFilter = '';
    public $customerFilter = '';
    public $hireYearFilter = '';
    
    // Sorting
    public $sortField = 'name';
    public $sortDirection = 'asc';
    
    // Display options
    public $perPage = 25;
    public $showInactive = false;
    public $showDetails = false;
    
    // Bulk operations
    public $selectedUsers = [];
    public $selectAll = false;
    
    // Modal states
    public $showDeleteModal = false;
    public $userToDelete = null;
    public $showBulkDeleteModal = false;
    
    protected $queryString = [
        'search' => ['except' => ''],
        'roleFilter' => ['except' => ''],
        'statusFilter' => ['except' => ''],
        'departmentFilter' => ['except' => ''],
        'branchFilter' => ['except' => ''],
        'customerFilter' => ['except' => ''],
        'hireYearFilter' => ['except' => ''],
        'sortField' => ['except' => 'name'],
        'sortDirection' => ['except' => 'asc'],
        'perPage' => ['except' => 25],
        'showInactive' => ['except' => false],
        'page' => ['except' => 1],
    ];

    protected $listeners = [
        'userUpdated' => '$refresh',
        'userCreated' => '$refresh',
        'userDeleted' => '$refresh',
    ];

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function updatingRoleFilter()
    {
        $this->resetPage();
    }

    public function updatingStatusFilter()
    {
        $this->resetPage();
    }

    public function updatingDepartmentFilter()
    {
        $this->resetPage();
    }

    public function updatingBranchFilter()
    {
        $this->resetPage();
    }

    public function updatingCustomerFilter()
    {
        $this->resetPage();
    }

    public function updatingHireYearFilter()
    {
        $this->resetPage();
    }

    public function updatingPerPage()
    {
        $this->resetPage();
    }

    public function render()
    {
        $query = User::query()
            ->with([
                'roles' => function($query) {
                    $query->where('user_roles.is_active', true)
                          ->where(function ($q) {
                              $q->whereNull('user_roles.expires_at')
                                ->orWhere('user_roles.expires_at', '>', now());
                          });
                }, 
                'customer', 
                'branch',
                'jobCards' => function($query) {
                    $query->select('id', 'service_advisor_id', 'created_at');
                }
            ])
            ->withCount([
                'roles as active_roles_count' => function($query) {
                    $query->where('user_roles.is_active', true)
                          ->where(function ($q) {
                              $q->whereNull('user_roles.expires_at')
                                ->orWhere('user_roles.expires_at', '>', now());
                          });
                },
                'jobCards as job_cards_count'
            ])
            ->when($this->search, function ($q) {
                $searchTerm = '%' . $this->search . '%';
                $q->where(function ($query) use ($searchTerm) {
                    $query->where('name', 'like', $searchTerm)
                          ->orWhere('email', 'like', $searchTerm)
                          ->orWhere('employee_id', 'like', $searchTerm)
                          ->orWhere('phone', 'like', $searchTerm)
                          ->orWhere('national_id', 'like', $searchTerm)
                          ->orWhereHas('branch', function($q) use ($searchTerm) {
                              $q->where('name', 'like', $searchTerm);
                          });
                });
            })
            ->when($this->roleFilter, function ($q) {
                $q->whereHas('roles', function ($query) {
                    $query->where('roles.name', $this->roleFilter)
                          ->where('user_roles.is_active', true)
                          ->where(function ($subQ) {
                              $subQ->whereNull('user_roles.expires_at')
                                   ->orWhere('user_roles.expires_at', '>', now());
                          });
                });
            })
            ->when($this->statusFilter, function ($q) {
                $q->where('status', $this->statusFilter);
            })
            ->when($this->departmentFilter, function ($q) {
                $q->where('department', $this->departmentFilter);
            })
            ->when($this->branchFilter, function ($q) {
                $q->where('branch_code', $this->branchFilter);
            })
            ->when($this->hireYearFilter, function ($q) {
                $q->whereYear('hire_date', $this->hireYearFilter);
            })
            ->when($this->customerFilter, function ($q) {
                if ($this->customerFilter === 'customers_only') {
                    $q->whereHas('customer');
                } elseif ($this->customerFilter === 'non_customers') {
                    $q->whereDoesntHave('customer');
                }
            })
            ->when(!$this->showInactive, function ($q) {
                $q->where('status', '!=', 'inactive');
            })
            ->orderBy($this->sortField, $this->sortDirection);

        $users = $query->paginate($this->perPage);

        // Filter options data
        $roles = Role::where('is_active', true)->orderBy('display_name')->get();
        $departments = User::select('department')
            ->distinct()
            ->whereNotNull('department')
            ->where('department', '!=', '')
            ->orderBy('department')
            ->pluck('department');
        $branches = Branch::where('is_active', true)
            ->orderBy('name')
            ->get();
        $hireYears = User::selectRaw('YEAR(hire_date) as year')
            ->whereNotNull('hire_date')
            ->distinct()
            ->orderByDesc('year')
            ->pluck('year')
            ->filter();

        // Enhanced statistics
        $stats = [
            'total' => User::count(),
            'active' => User::where('status', 'active')->count(),
            'inactive' => User::where('status', 'inactive')->count(),
            'suspended' => User::where('status', 'suspended')->count(),
            'customers' => User::whereHas('customer')->count(),
            'staff' => User::whereDoesntHave('customer')->count(),
            'recent_hires' => User::where('hire_date', '>=', now()->subDays(30))->count(),
            'no_roles' => User::whereDoesntHave('roles', function($q) {
                $q->where('user_roles.is_active', true);
            })->count(),
        ];

        // Branch distribution for stats
        $branchStats = User::select('branch_code')
            ->selectRaw('count(*) as count')
            ->with('branch:code,name')
            ->groupBy('branch_code')
            ->get()
            ->mapWithKeys(function($item) {
                $branchName = $item->branch ? $item->branch->name : $item->branch_code;
                return [$branchName => $item->count];
            });

        return view('livewire.users.index', compact(
            'users', 
            'roles', 
            'departments', 
            'branches', 
            'hireYears',
            'stats', 
            'branchStats'
        ));
    }

    public function sortBy($field)
    {
        if ($this->sortField === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortField = $field;
            $this->sortDirection = 'asc';
        }
        $this->resetPage();
    }

    public function clearFilters()
    {
        $this->search = '';
        $this->roleFilter = '';
        $this->statusFilter = '';
        $this->departmentFilter = '';
        $this->branchFilter = '';
        $this->customerFilter = '';
        $this->hireYearFilter = '';
        $this->showInactive = false;
        $this->resetPage();
    }

    public function toggleShowInactive()
    {
        $this->showInactive = !$this->showInactive;
        $this->resetPage();
    }

    public function toggleShowDetails()
    {
        $this->showDetails = !$this->showDetails;
    }

    public function selectAllUsers()
    {
        if ($this->selectAll) {
            $this->selectedUsers = [];
            $this->selectAll = false;
        } else {
            // Only select users from current page for performance
            $currentPageUsers = User::when($this->search, function ($q) {
                $searchTerm = '%' . $this->search . '%';
                $q->where(function ($query) use ($searchTerm) {
                    $query->where('name', 'like', $searchTerm)
                          ->orWhere('email', 'like', $searchTerm);
                });
            })->pluck('id')->toArray();
            
            $this->selectedUsers = $currentPageUsers;
            $this->selectAll = true;
        }
    }

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

    public function confirmBulkDelete()
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }
        $this->showBulkDeleteModal = true;
    }

    public function bulkActivate()
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }

        try {
            $count = User::whereIn('id', $this->selectedUsers)
                ->where('id', '!=', auth()->id())
                ->update(['status' => 'active']);

            // Log bulk action
            activity()
                ->causedBy(auth()->user())
                ->log('Bulk activated ' . $count . ' users');

            $this->selectedUsers = [];
            $this->selectAll = false;
            
            session()->flash('success', "Successfully activated {$count} users.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to activate users: ' . $e->getMessage());
        }
    }

    public function bulkDeactivate()
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }

        try {
            $count = User::whereIn('id', $this->selectedUsers)
                ->where('id', '!=', auth()->id())
                ->update(['status' => 'inactive']);

            // Log bulk action
            activity()
                ->causedBy(auth()->user())
                ->log('Bulk deactivated ' . $count . ' users');

            $this->selectedUsers = [];
            $this->selectAll = false;
            
            session()->flash('success', "Successfully deactivated {$count} users.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to deactivate users: ' . $e->getMessage());
        }
    }

    public function bulkSuspend()
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }

        try {
            $count = User::whereIn('id', $this->selectedUsers)
                ->where('id', '!=', auth()->id())
                ->update(['status' => 'suspended']);

            // Log bulk action
            activity()
                ->causedBy(auth()->user())
                ->log('Bulk suspended ' . $count . ' users');

            $this->selectedUsers = [];
            $this->selectAll = false;
            
            session()->flash('success', "Successfully suspended {$count} users.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to suspend users: ' . $e->getMessage());
        }
    }

    public function bulkAssignRole($roleId)
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }

        try {
            $role = Role::findOrFail($roleId);
            $count = 0;

            foreach ($this->selectedUsers as $userId) {
                $user = User::find($userId);
                if ($user && !$user->hasRole($role->name)) {
                    $user->assignRole($role);
                    $count++;
                }
            }

            // Log bulk action
            activity()
                ->causedBy(auth()->user())
                ->log('Bulk assigned role "' . $role->display_name . '" to ' . $count . ' users');

            $this->selectedUsers = [];
            $this->selectAll = false;
            
            session()->flash('success', "Successfully assigned role '{$role->display_name}' to {$count} users.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to assign role: ' . $e->getMessage());
        }
    }

    public function deactivateUser($userId)
    {
        try {
            $user = User::findOrFail($userId);
            
            if ($user->id === auth()->id()) {
                session()->flash('error', 'You cannot deactivate your own account.');
                return;
            }

            $user->update(['status' => 'inactive']);
            
            // Log the action
            activity()
                ->performedOn($user)
                ->causedBy(auth()->user())
                ->log('User deactivated');
                
            session()->flash('success', "User '{$user->name}' deactivated successfully.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to deactivate user: ' . $e->getMessage());
        }
    }

    public function activateUser($userId)
    {
        try {
            $user = User::findOrFail($userId);
            $user->update(['status' => 'active']);
            
            // Log the action
            activity()
                ->performedOn($user)
                ->causedBy(auth()->user())
                ->log('User activated');
                
            session()->flash('success', "User '{$user->name}' activated successfully.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to activate user: ' . $e->getMessage());
        }
    }

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

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

    public function deleteUser($userId = null)
    {
        $userId = $userId ?? $this->userToDelete;
        
        try {
            $user = User::findOrFail($userId);
            
            if ($user->id === auth()->id()) {
                session()->flash('error', 'You cannot delete your own account.');
                return;
            }

            // Check if user has dependencies
            $jobCardsCount = $user->jobCards()->count();
            if ($jobCardsCount > 0) {
                session()->flash('error', "Cannot delete user '{$user->name}'. User has {$jobCardsCount} associated job cards.");
                return;
            }

            // Log before deletion
            activity()
                ->performedOn($user)
                ->causedBy(auth()->user())
                ->log('User deleted');
                
            $userName = $user->name;
            $user->delete();
            
            session()->flash('success', "User '{$userName}' deleted successfully.");
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to delete user: ' . $e->getMessage());
        } finally {
            $this->showDeleteModal = false;
            $this->userToDelete = null;
        }
    }

    public function bulkDelete()
    {
        if (empty($this->selectedUsers)) {
            session()->flash('error', 'No users selected.');
            return;
        }

        try {
            $users = User::whereIn('id', $this->selectedUsers)
                ->where('id', '!=', auth()->id())
                ->get();

            $deletedCount = 0;
            $skippedCount = 0;

            foreach ($users as $user) {
                // Check dependencies
                if ($user->jobCards()->count() > 0) {
                    $skippedCount++;
                    continue;
                }

                // Log before deletion
                activity()
                    ->performedOn($user)
                    ->causedBy(auth()->user())
                    ->log('User deleted (bulk)');

                $user->delete();
                $deletedCount++;
            }

            $this->selectedUsers = [];
            $this->selectAll = false;
            $this->showBulkDeleteModal = false;

            $message = "Deleted {$deletedCount} users successfully.";
            if ($skippedCount > 0) {
                $message .= " {$skippedCount} users were skipped due to dependencies.";
            }
            
            session()->flash('success', $message);
        } catch (\Exception $e) {
            session()->flash('error', 'Failed to delete users: ' . $e->getMessage());
        }
    }

    public function exportUsers()
    {
        try {
            $users = User::with(['roles', 'branch'])
                ->when($this->search, function ($q) {
                    $searchTerm = '%' . $this->search . '%';
                    $q->where(function ($query) use ($searchTerm) {
                        $query->where('name', 'like', $searchTerm)
                              ->orWhere('email', 'like', $searchTerm);
                    });
                })
                ->when($this->roleFilter, function ($q) {
                    $q->whereHas('roles', function ($query) {
                        $query->where('roles.name', $this->roleFilter);
                    });
                })
                ->when($this->statusFilter, function ($q) {
                    $q->where('status', $this->statusFilter);
                })
                ->when($this->branchFilter, function ($q) {
                    $q->where('branch_code', $this->branchFilter);
                })
                ->get();

            // Create CSV content
            $csvData = [];
            $csvData[] = [
                'Name', 'Email', 'Employee ID', 'Phone', 'Department', 
                'Position', 'Branch', 'Status', 'Hire Date', 'Roles'
            ];

            foreach ($users as $user) {
                $csvData[] = [
                    $user->name,
                    $user->email,
                    $user->employee_id,
                    $user->phone,
                    $user->department,
                    $user->position,
                    $user->branch ? $user->branch->name : $user->branch_code,
                    $user->status,
                    $user->hire_date ? $user->hire_date->format('Y-m-d') : '',
                    $user->roles->pluck('display_name')->join(', ')
                ];
            }

            // Store CSV file
            $fileName = 'users_export_' . now()->format('Y_m_d_H_i_s') . '.csv';
            $csv = '';
            foreach ($csvData as $row) {
                $csv .= '"' . implode('","', $row) . '"' . "\n";
            }

            Storage::put('exports/' . $fileName, $csv);

            session()->flash('success', 'Export completed! Downloaded ' . $users->count() . ' users to ' . $fileName);
        } catch (\Exception $e) {
            session()->flash('error', 'Export failed: ' . $e->getMessage());
        }
    }

    public function getUserRoles($user)
    {
        return $user->roles()
                   ->where('user_roles.is_active', true)
                   ->where(function ($q) {
                       $q->whereNull('user_roles.expires_at')
                         ->orWhere('user_roles.expires_at', '>', now());
                   })
                   ->pluck('display_name')
                   ->join(', ');
    }

    public function getUserPermissionCount($user)
    {
        return $user->getAllPermissions()->count();
    }

    public function hasActiveFilters()
    {
        return !empty($this->search) || 
               !empty($this->roleFilter) || 
               !empty($this->statusFilter) || 
               !empty($this->departmentFilter) || 
               !empty($this->branchFilter) ||
               !empty($this->customerFilter) ||
               !empty($this->hireYearFilter) ||
               $this->showInactive;
    }

    public function getSelectedCount()
    {
        return count($this->selectedUsers);
    }

    public function resetFilters()
    {
        $this->clearFilters();
    }

    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_coordinator' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200',
            'service_supervisor' => 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200',
            'technician' => 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200',
            'receptionist' => 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200',
            'parts_clerk' => 'bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200',
            'service_advisor' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200',
            'cashier' => 'bg-pink-100 dark:bg-pink-900 text-pink-800 dark:text-pink-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',
            default => 'bg-zinc-100 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-200',
        };
    }

    public function getStatusBadgeClass($status)
    {
        return match($status) {
            'active' => 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200',
            'inactive' => 'bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-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 getUserActivityClass($user)
    {
        $lastSeen = $user->last_seen_at;
        if (!$lastSeen) return 'text-gray-500';
        
        $minutesAgo = now()->diffInMinutes($lastSeen);
        if ($minutesAgo < 5) return 'text-green-500';
        if ($minutesAgo < 60) return 'text-yellow-500';
        if ($minutesAgo < 1440) return 'text-orange-500';
        return 'text-red-500';
    }

    public function getUserLastSeenText($user)
    {
        $lastSeen = $user->last_seen_at;
        if (!$lastSeen) return 'Never';
        
        return $lastSeen->diffForHumans();
    }

    public function canDeleteUser($user)
    {
        return $user->id !== auth()->id() && 
               $user->jobCards()->count() === 0 &&
               !$user->hasRole('super_admin');
    }

    public function canModifyUser($user)
    {
        return $user->id !== auth()->id() || auth()->user()->hasRole('super_admin');
    }
}
