<?php
// app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Get the roles assigned to this user
     */
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class, 'user_roles', 'user_id', 'role_id')
            ->withTimestamps();
    }

    /**
     * Get all permissions for this user through roles
     * RENAMED to avoid conflict with Laravel's morph methods
     */
    public function getUserPermissions(): Collection
    {
        return $this->roles->flatMap(function ($role) {
            return $role->permissions;
        })->unique('id');
    }

    /**
     * Check if user has a specific role
     */
    public function hasRole($role): bool
    {
        if (is_int($role)) {
            return $this->roles->contains('id', $role);
        }
        
        if (is_string($role)) {
            return $this->roles->contains('slug', $role);
        }
        
        if ($role instanceof Role) {
            return $this->roles->contains('id', $role->id);
        }
        
        return false;
    }

    /**
     * Check if user has a specific permission
     */
    public function hasPermission($permission): bool
    {
        $permissions = $this->getUserPermissions();
        
        if (is_int($permission)) {
            return $permissions->contains('id', $permission);
        }
        
        if (is_string($permission)) {
            return $permissions->contains('slug', $permission);
        }
        
        if ($permission instanceof Permission) {
            return $permissions->contains('id', $permission->id);
        }
        
        return false;
    }

    /**
     * Assign a role to the user
     */
    public function assignRole($role): self
    {
        if (is_string($role)) {
            $role = Role::where('slug', $role)->first();
            if (!$role) {
                return $this;
            }
        }
        
        if (is_int($role)) {
            $role = Role::find($role);
            if (!$role) {
                return $this;
            }
        }
        
        if ($role instanceof Role) {
            if (!$this->hasRole($role)) {
                $this->roles()->attach($role->id);
            }
        }
        
        return $this;
    }

    /**
     * Sync user roles
     */
    public function syncRoles($roles): self
    {
        $roleIds = [];
        
        if (empty($roles)) {
            $this->roles()->detach();
            return $this;
        }
        
        foreach ($roles as $role) {
            if (is_int($role)) {
                $roleIds[] = $role;
            } elseif (is_string($role)) {
                $roleModel = Role::where('slug', $role)->first();
                if ($roleModel) {
                    $roleIds[] = $roleModel->id;
                }
            } elseif ($role instanceof Role) {
                $roleIds[] = $role->id;
            }
        }
        
        if (!empty($roleIds)) {
            $this->roles()->sync($roleIds);
        }
        
        return $this;
    }

    /**
     * Remove a role from the user
     */
    public function removeRole($role): self
    {
        if (is_string($role)) {
            $role = Role::where('slug', $role)->first();
            if (!$role) {
                return $this;
            }
        }
        
        if (is_int($role)) {
            $role = Role::find($role);
            if (!$role) {
                return $this;
            }
        }
        
        if ($role instanceof Role) {
            $this->roles()->detach($role->id);
        }
        
        return $this;
    }

    /**
     * Check if user is super admin
     */
    public function isSuperAdmin(): bool
    {
        return $this->hasRole('super-admin');
    }
}