<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'first_name',
        'last_name',
        'email',
        'password',
        'phone',
        'department',
        'employee_id',
        'avatar',
        'role_id',
        'status',
        'first_login',
        'created_by_admin_id',
        'last_login_at',
        'last_login_ip',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'first_login' => 'boolean',
            'last_login_at' => 'datetime',
        ];
    }

    /**
     * Get the user's role.
     */
    public function role(): BelongsTo
    {
        return $this->belongsTo(Role::class);
    }

    /**
     * Get the admin who created this user.
     */
    public function createdByAdmin(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by_admin_id');
    }

    /**
     * Get users created by this admin.
     */
    public function createdUsers(): HasMany
    {
        return $this->hasMany(User::class, 'created_by_admin_id');
    }

    /**
     * Get the user's activities.
     */
    public function activities(): HasMany
    {
        return $this->hasMany(UserActivity::class);
    }

    /**
     * Get the user's full name.
     */
    public function getFullNameAttribute(): string
    {
        return trim($this->first_name . ' ' . $this->last_name) ?: $this->name;
    }

    /**
     * Get the user's avatar URL.
     */
    public function getAvatarUrlAttribute(): string
    {
        if ($this->avatar && Storage::exists('public/' . $this->avatar)) {
            return Storage::url($this->avatar);
        }
        
        // Generate initials-based avatar
        $initials = substr($this->first_name ?? $this->name ?? 'U', 0, 1) . 
                   substr($this->last_name ?? '', 0, 1);
        return 'https://ui-avatars.com/api/?name=' . urlencode($initials) . '&background=038BB9&color=fff';
    }

    /**
     * Check if user has a specific permission.
     */
    public function hasPermission(string $permission): bool
    {
        return $this->role?->hasPermission($permission) ?? false;
    }

    /**
     * Check if user has any of the given permissions.
     */
    public function hasAnyPermission(array $permissions): bool
    {
        foreach ($permissions as $permission) {
            if ($this->hasPermission($permission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Check if user has a specific role.
     */
    public function hasRole(string $role): bool
    {
        return $this->role?->name === $role;
    }

    /**
     * Check if user is an admin.
     */
    public function isAdmin(): bool
    {
        return $this->hasRole('super_admin') || $this->hasRole('admin');
    }

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

    /**
     * Check if user has warehouse access.
     */
    public function hasWarehouseAccess(): bool
    {
        return $this->hasAnyPermission([
            'warehouse.dashboard.view',
            'warehouse.suppliers.view',
            'warehouse.projects.view',
            'warehouse.items.view',
            'warehouse.inventory.view',
            'warehouse.incoming.view',
            'warehouse.outgoing.view',
            'warehouse.returns.view',
        ]);
    }

    /**
     * Check if user is a warehouse manager.
     */
    public function isWarehouseManager(): bool
    {
        return $this->hasRole('warehouse_manager');
    }

    /**
     * Check if user is a warehouse supervisor.
     */
    public function isWarehouseSupervisor(): bool
    {
        return $this->hasRole('warehouse_supervisor');
    }

    /**
     * Check if user is a warehouse clerk.
     */
    public function isWarehouseClerk(): bool
    {
        return $this->hasRole('warehouse_clerk');
    }

    /**
     * Check if user is a project manager.
     */
    public function isProjectManager(): bool
    {
        return $this->hasRole('project_manager');
    }

    /**
     * Check if user is a warehouse viewer/auditor.
     */
    public function isWarehouseViewer(): bool
    {
        return $this->hasRole('warehouse_viewer');
    }

    /**
     * Check if user can approve warehouse transactions.
     */
    public function canApproveWarehouseTransactions(): bool
    {
        return $this->hasPermission('warehouse.outgoing.approve') ||
               $this->hasPermission('warehouse.returns.process');
    }

    /**
     * Check if user can manage warehouse settings.
     */
    public function canManageWarehouseSettings(): bool
    {
        return $this->hasPermission('warehouse.settings.manage');
    }

    /**
     * Check if user can create warehouse items.
     */
    public function canCreateWarehouseItems(): bool
    {
        return $this->hasPermission('warehouse.items.create');
    }

    /**
     * Check if user can adjust inventory.
     */
    public function canAdjustInventory(): bool
    {
        return $this->hasPermission('warehouse.inventory.adjust');
    }

    /**
     * Get warehouse role display name.
     */
    public function getWarehouseRoleDisplayNameAttribute(): ?string
    {
        if (!$this->hasWarehouseAccess()) {
            return null;
        }

        return $this->role?->display_name;
    }

    /**
     * Get warehouse permissions for the user.
     */
    public function getWarehousePermissionsAttribute(): array
    {
        if (!$this->role) {
            return [];
        }

        return $this->role->permissions()
            ->where('name', 'LIKE', 'warehouse.%')
            ->pluck('name')
            ->toArray();
    }

    /**
     * Check if user is active.
     */
    public function isActive(): bool
    {
        return $this->status === 'active';
    }

    /**
     * Scope for active users.
     */
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    /**
     * Scope for users by role.
     */
    public function scopeByRole($query, string $role)
    {
        return $query->whereHas('role', function ($q) use ($role) {
            $q->where('name', $role);
        });
    }

    /**
     * Scope for users by status.
     */
    public function scopeByStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * Record user login activity.
     */
    public function recordLogin(): void
    {
        $this->update([
            'last_login_at' => now(),
            'last_login_ip' => request()->ip(),
            'first_login' => false,
        ]);

        UserActivity::log('login', 'User logged in');
    }
}
