<?php

namespace App\Modules\HR\Employees\Models;

use App\Models\User;
use App\Modules\Admin\Tenancy\Traits\BelongsToTenant;
use App\Modules\HR\Departments\Models\Department;
use App\Modules\HR\EmploymentStatuses\Models\EmploymentStatus;
use App\Modules\HR\Positions\Models\Position;
use App\Modules\HR\Recruitment\Models\RecruitmentOnboardingCase;
use App\Modules\HR\Shifts\Models\EmployeeShiftAssignment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Employee extends Model
{
    use BelongsToTenant;

    protected $fillable = [
        'tenant_id',
        'employee_code',
        'full_name',
        'arabic_name',
        'fingerprint_id',
        'phone_1',
        'phone_2',
        'email',
        'company_email',
        'department_id',
        'position_id',
        'manager_employee_id',
        'salary',
        'hire_date',
        'probation_end_date',
        'confirmation_date',
        'onboarding_completed_at',
        'gender',
        'date_of_birth',
        'marital_status',
        'nationality',
        'national_id',
        'passport_number',
        'social_insurance_number',
        'bank_name',
        'bank_account_number',
        'iban',
        'employment_status_id',
        'is_active',
        'created_by',
        'updated_by',
    ];

    protected function casts(): array
    {
        return [
            'hire_date' => 'date',
            'probation_end_date' => 'date',
            'confirmation_date' => 'date',
            'onboarding_completed_at' => 'datetime',
            'date_of_birth' => 'date',
            'salary' => 'decimal:2',
            'is_active' => 'boolean',
        ];
    }

    public function employmentStatus(): BelongsTo
    {
        return $this->belongsTo(EmploymentStatus::class, 'employment_status_id');
    }

    public function department(): BelongsTo
    {
        return $this->belongsTo(Department::class);
    }

    public function position(): BelongsTo
    {
        return $this->belongsTo(Position::class);
    }

    public function manager(): BelongsTo
    {
        return $this->belongsTo(Employee::class, 'manager_employee_id');
    }

    public function directReports(): HasMany
    {
        return $this->hasMany(Employee::class, 'manager_employee_id');
    }

    public function user(): HasOne
    {
        return $this->hasOne(User::class);
    }

    public function address(): HasOne
    {
        return $this->hasOne(EmployeeAddress::class);
    }

    public function documents(): HasMany
    {
        return $this->hasMany(EmployeeDocument::class);
    }

    public function emergencyContacts(): HasMany
    {
        return $this->hasMany(EmployeeEmergencyContact::class);
    }

    public function skills(): HasMany
    {
        return $this->hasMany(EmployeeSkill::class);
    }

    public function assetAssignments(): HasMany
    {
        return $this->hasMany(EmployeeAssetAssignment::class);
    }

    public function onboardingCase(): HasOne
    {
        return $this->hasOne(RecruitmentOnboardingCase::class, 'employee_id');
    }

    public function shiftAssignments(): HasMany
    {
        return $this->hasMany(EmployeeShiftAssignment::class);
    }

    public function activeShiftAssignment(): HasOne
    {
        return $this->hasOne(EmployeeShiftAssignment::class)
            ->where('is_active', true);
    }

    public function createdByUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updatedByUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }
}
