<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use App\Traits\HasRolesAndPermissions;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'password_changed_at',
        'employee_id',
        'phone',
        'department',
        'position',
        'branch_code',
        'hire_date',
        'salary',
        'status',
        'emergency_contact_name',
        'emergency_contact_phone',
        'address',
        'date_of_birth',
        'national_id',
        'last_login_at',
    ];

    /**
     * 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',
            'password_changed_at' => 'datetime',
            'hire_date' => 'date',
            'date_of_birth' => 'date',
            'last_login_at' => 'datetime',
            'salary' => 'decimal:2',
        ];
    }

    /**
     * Get the user's initials
     */
    public function initials(): string
    {
        return Str::of($this->name)
            ->explode(' ')
            ->take(2)
            ->map(fn ($word) => Str::substr($word, 0, 1))
            ->implode('');
    }

    /**
     * Get the branch that the user belongs to
     */
    public function branch()
    {
        return $this->belongsTo(Branch::class, 'branch_code', 'code');
    }

    /**
     * Check if user is a service supervisor
     */
    public function isServiceSupervisor(): bool
    {
        return $this->hasRole('service_supervisor');
    }

    /**
     * Check if user is a service coordinator
     */
    public function isServiceCoordinator(): bool
    {
        return $this->hasRole('service_coordinator');
    }

    /**
     * Check if user is parts manager
     */
    public function isPartsManager(): bool
    {
        return $this->hasRole('parts_manager');
    }

    /**
     * Check if user is service advisor
     */
    public function isServiceAdvisor(): bool
    {
        return $this->hasRole('service_advisor');
    }

    /**
     * Check if user is a customer
     */
    public function isCustomer(): bool
    {
        return $this->hasRole('customer_portal');
    }

    /**
     * Get the customer profile associated with this user (if they are a customer)
     */
    public function customer()
    {
        return $this->hasOne(Customer::class);
    }

    /**
     * Get job cards where this user is the service advisor
     */
    public function jobCards()
    {
        return $this->hasMany(JobCard::class, 'service_advisor_id');
    }

    /**
     * Get job cards assigned to this user for diagnosis
     */
    public function assignedJobCards()
    {
        return $this->hasMany(JobCard::class, 'service_advisor_id');
    }

    /**
     * Get timesheets for this user
     */
    public function timesheets()
    {
        return $this->hasMany(Timesheet::class);
    }

    /**
     * Get user's active roles
     */
    public function activeRoles()
    {
        return $this->roles()
                    ->where('user_roles.is_active', true)
                    ->where(function ($q) {
                        $q->whereNull('user_roles.expires_at')
                          ->orWhere('user_roles.expires_at', '>', now());
                    })
                    ->where('roles.is_active', true)
                    ->get();
    }

    /**
     * Get the options for logging activities.
     */
    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['name', 'email', 'employee_id', 'phone', 'department', 'position', 'branch_code', 'status'])
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }
}
