<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Enums\UserRole;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

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

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

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

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

    /**
     * Get the service bookings for the user.
     */
    public function serviceBookings()
    {
        return $this->hasMany(ServiceBooking::class, 'customer_id');
    }

    /**
     * Get the invoices for the user.
     */
    public function invoices()
    {
        return $this->hasMany(Invoice::class, 'customer_id');
    }

    /**
     * Get the tickets for the user.
     */
    public function tickets()
    {
        return $this->hasMany(Ticket::class, 'customer_id');
    }

    /**
     * Check if user is admin.
     */
    public function isAdmin(): bool
    {
        $allowedRoleValues = array_map(fn (UserRole $role) => $role->value, UserRole::adminRoles());

        return in_array($this->role, $allowedRoleValues, true);
    }

    /**
     * Check if user is customer.
     */
    public function isCustomer(): bool
    {
        return $this->role === 'CUSTOMER';
    }

    /**
     * Check if user is employee.
     */
    public function isEmployee(): bool
    {
        $allowedRoleValues = array_map(fn (UserRole $role) => $role->value, UserRole::employeeRoles());

        return in_array($this->role, $allowedRoleValues, true);
    }

    public function employee()
    {
        return $this->hasOne(Employee::class, 'user_id');
    }

    /**
     * Get the employee profile associated with the user.
     */
    public function employeeProfile()
    {
        return $this->hasOne(EmployeeProfile::class);
    }

    /**
     * Get the leave requests for the user.
     */
    public function leaveRequests()
    {
        return $this->hasMany(LeaveRequest::class);
    }

    /**
     * Get the payroll records for the user.
     */
    public function payrollRecords()
    {
        return $this->hasMany(PayrollRecord::class);
    }

    /**
     * Get the attendance records for the user.
     */
    public function attendanceRecords()
    {
        return $this->hasManyThrough(
            AttendanceRecord::class,
            Employee::class,
            'user_id',
            'employee_id',
            'id',
            'id'
        );
    }

    /**
     * Get the performance reviews for the user.
     */
    public function performanceReviews()
    {
        return $this->hasManyThrough(
            PerformanceReview::class,
            Employee::class,
            'user_id',
            'employee_id',
            'id',
            'id'
        );
    }

    /**
     * Get the performance metrics for the user.
     */
    public function performanceMetrics()
    {
        return $this->hasManyThrough(
            PerformanceMetric::class,
            Employee::class,
            'user_id',
            'employee_id',
            'id',
            'id'
        );
    }

    /**
     * Get the training records for the user.
     */
    public function trainingRecords()
    {
        return $this->hasManyThrough(
            TrainingRecord::class,
            Employee::class,
            'user_id',
            'employee_id',
            'id',
            'id'
        );
    }

    /**
     * Get the salary advances for the user.
     */
    public function salaryAdvances()
    {
        return $this->hasManyThrough(
            SalaryAdvance::class,
            Employee::class,
            'user_id',
            'employee_id',
            'id',
            'id'
        );
    }

    public function getFirstNameAttribute(): string
    {
        $name = trim((string) $this->name);
        if ($name === '') {
            return '';
        }

        return explode(' ', $name)[0];
    }

    public function getLastNameAttribute(): string
    {
        $name = trim((string) $this->name);
        if ($name === '' || ! str_contains($name, ' ')) {
            return '';
        }

        return trim(substr($name, strpos($name, ' ') + 1));
    }

    public function getJobTitleAttribute(): ?string
    {
        return $this->employee?->position?->title;
    }
}
