<?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\MorphOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use Spatie\Permission\Traits\HasRoles;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'username',
        'email',
        'password',
        'is_active',
        'license_key',
        'shop_id',
    ];

    /**
     * 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',
            'is_active' => 'boolean',
        ];
    }

    // Relationships
    public function account(): MorphOne
    {
        return $this->morphOne(Account::class, 'model');
    }

    public function shop(): BelongsTo
    {
        return $this->belongsTo(Account::class, 'shop_id')->where('model_type', 'shop');
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeInactive($query)
    {
        return $query->where('is_active', false);
    }

    /**
     * Get the name of the unique identifier for the user.
     *
     * @return string
     */
    public function getAuthIdentifierName()
    {
        return 'id';
    }

    /**
     * Get the unique identifier for the user.
     *
     * @return mixed
     */
    public function getAuthIdentifier()
    {
        return $this->getAttribute($this->getAuthIdentifierName());
    }

    /**
     * Get the password for the user.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->password;
    }

    // Helper methods
    public function getAccountBalanceAttribute()
    {
        return $this->account ? $this->account->balance : 0;
    }

    public function getFormattedAccountBalanceAttribute()
    {
        return format_currency($this->account_balance);
    }

    public function getStatusBadgeAttribute()
    {
        return $this->is_active
            ? '<span class="badge bg-success">Active</span>'
            : '<span class="badge bg-danger">Inactive</span>';
    }

    // Role-related helper methods
    public function hasAnyRole($roles): bool
    {
        return $this->hasAnyRole($roles);
    }

    public function hasRole($role): bool
    {
        return $this->hasRole($role);
    }

    public function hasPermissionTo($permission): bool
    {
        return $this->hasPermissionTo($permission);
    }

    public function getRoleNamesAttribute(): array
    {
        return $this->getRoleNames()->toArray();
    }

    public function getPrimaryRoleAttribute(): string
    {
        $roles = $this->getRoleNames();
        return $roles->first() ?? 'No Role';
    }

    public function getRoleBadgeAttribute(): string
    {
        $role = $this->primary_role;
        $badgeClass = match($role) {
            'superadmin' => 'bg-danger',
            'admin' => 'bg-primary',
            'pr_officer' => 'bg-success',
            'po_officer' => 'bg-info',
            'igp_officer' => 'bg-warning',
            'qc_officer' => 'bg-secondary',
            default => 'bg-secondary'
        };

        return "<span class='badge {$badgeClass}'>{$role}</span>";
    }

    public function isSuperadmin(): bool
    {
        return $this->hasRole('superadmin');
    }

    public function isAdmin(): bool
    {
        return $this->hasRole('admin');
    }

    public function isOfficer(): bool
    {
        return $this->hasAnyRole(['pr_officer', 'po_officer', 'igp_officer', 'qc_officer']);
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->useLogName('user')
            ->logFillable()
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }
}
