<?php

namespace App\Models;

use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class Employee extends Model
{
    use BelongsToTenant, HasFactory, SoftDeletes;

    protected $fillable = [
        'uuid',
        'tenant_id',
        'branch_id',
        'department_id',
        'employee_code',
        'first_name',
        'middle_name',
        'last_name',
        'full_name',
        'display_name',
        'gender',
        'date_of_birth',
        'nationality',
        'marital_status',
        'profile_photo_path',
        'email',
        'mobile',
        'personal_mobile',
        'personal_email',
        'uae_address',
        'home_country_address',
        'emergency_contact_name',
        'emergency_contact_relation',
        'emergency_contact_mobile',
        'designation',
        'employment_type',
        'joining_date',
        'reporting_manager_id',
        'probation_start',
        'probation_end',
        'contract_start',
        'contract_end',
        'work_location',
        'weekly_off',
        'payroll_group_code',
        'emirates_id',
        'emirates_id_issue_date',
        'emirates_id_expiry',
        'passport_number',
        'passport_issue_date',
        'passport_expiry',
        'passport_country',
        'visa_number',
        'visa_file_number',
        'visa_issue_date',
        'visa_expiry',
        'visa_type',
        'sponsor',
        'work_permit_number',
        'work_permit_issue_date',
        'work_permit_expiry',
        'labour_card_number',
        'insurance_provider',
        'insurance_number',
        'insurance_expiry',
        'documents_json',
        'status',
    ];

    protected $casts = [
        'joining_date' => 'date',
        'date_of_birth' => 'date',
        'probation_start' => 'date',
        'probation_end' => 'date',
        'contract_start' => 'date',
        'contract_end' => 'date',
        'passport_issue_date' => 'date',
        'passport_expiry' => 'date',
        'emirates_id_issue_date' => 'date',
        'emirates_id_expiry' => 'date',
        'visa_issue_date' => 'date',
        'visa_expiry' => 'date',
        'work_permit_issue_date' => 'date',
        'work_permit_expiry' => 'date',
        'insurance_expiry' => 'date',
        'documents_json' => 'array',
    ];

    protected static function boot()
    {
        parent::boot();
        static::creating(function ($model) {
            if (! $model->uuid) {
                $model->uuid = (string) Str::uuid();
            }
            if (empty($model->full_name)) {
                $model->full_name = trim($model->first_name.' '.($model->last_name ?? ''));
            }
        });
    }

    public function branch()
    {
        return $this->belongsTo(Branch::class);
    }

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

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

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

    public function reportingManager()
    {
        return $this->belongsTo(self::class, 'reporting_manager_id');
    }

    public function salaryStructures()
    {
        return $this->hasMany(EmployeeSalaryStructure::class)->orderByDesc('effective_from');
    }

    public function currentSalary()
    {
        return $this->hasOne(EmployeeSalaryStructure::class)
            ->whereDate('effective_from', '<=', today())
            ->where(fn ($query) => $query->whereNull('effective_to')->orWhereDate('effective_to', '>=', today()))
            ->latestOfMany('effective_from');
    }

    public function bankDetail()
    {
        return $this->hasOne(EmployeeBankDetail::class);
    }

    public function attendanceRecords()
    {
        return $this->hasMany(AttendanceRecord::class);
    }

    public function leaveRequests()
    {
        return $this->hasMany(LeaveRequest::class);
    }

    public function loans()
    {
        return $this->hasMany(EmployeeLoan::class);
    }

    public function payrollItems()
    {
        return $this->hasMany(PayrollItem::class)->latest();
    }

    public function leaveBalances()
    {
        return $this->hasMany(LeaveBalance::class);
    }

    public function gratuities()
    {
        return $this->hasMany(EmployeeGratuity::class)->latest();
    }
}
