<?php

namespace App\Modules\HR\Recruitment\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\Support\OfferLetterStatus;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class RecruitmentOfferLetter extends Model
{
    use BelongsToTenant;
    use SoftDeletes;

    protected $table = 'recruitment_offer_letters';

    protected $fillable = [
        'tenant_id', 'reference_code', 'application_id', 'candidate_id', 'vacancy_id',
        'department_id', 'position_id', 'employment_type', 'employment_status_id',
        'start_date', 'probation_period_days', 'salary', 'currency', 'allowances',
        'benefits', 'working_hours', 'notes', 'status', 'expires_at', 'acceptance_deadline_at',
        'submitted_at', 'approved_by', 'approved_at', 'sent_by', 'sent_at', 'sent_count',
        'accepted_at', 'rejected_at', 'expired_at', 'withdrawn_at', 'decision_notes',
        'version', 'parent_offer_id', 'is_current', 'template_key', 'template_version',
        'pdf_path', 'signed_pdf_path', 'email_sent_at', 'email_to', 'email_message_id',
        'email_status', 'esign_provider', 'esign_envelope_id', 'esign_status', 'signed_at',
        'signed_by_name', 'signature_meta', 'created_by', 'employee_id', 'hired_at',
    ];

    protected function casts(): array
    {
        return [
            'start_date' => 'date',
            'probation_period_days' => 'integer',
            'salary' => 'decimal:2',
            'expires_at' => 'datetime',
            'acceptance_deadline_at' => 'datetime',
            'submitted_at' => 'datetime',
            'approved_at' => 'datetime',
            'sent_at' => 'datetime',
            'sent_count' => 'integer',
            'accepted_at' => 'datetime',
            'rejected_at' => 'datetime',
            'expired_at' => 'datetime',
            'withdrawn_at' => 'datetime',
            'hired_at' => 'datetime',
            'version' => 'integer',
            'is_current' => 'boolean',
            'email_sent_at' => 'datetime',
            'signed_at' => 'datetime',
            'signature_meta' => 'array',
        ];
    }

    public function isAccepted(): bool
    {
        return OfferLetterStatus::isAccepted((string) $this->status);
    }

    public function isHired(): bool
    {
        return (string) $this->status === OfferLetterStatus::HIRED;
    }

    public function application(): BelongsTo
    {
        return $this->belongsTo(RecruitmentApplication::class, 'application_id');
    }

    public function candidate(): BelongsTo
    {
        return $this->belongsTo(RecruitmentCandidate::class, 'candidate_id');
    }

    public function vacancy(): BelongsTo
    {
        return $this->belongsTo(RecruitmentVacancy::class, 'vacancy_id');
    }

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

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

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

    public function parentOffer(): BelongsTo
    {
        return $this->belongsTo(self::class, 'parent_offer_id');
    }

    public function statusEvents(): HasMany
    {
        return $this->hasMany(RecruitmentOfferLetterStatusEvent::class, 'offer_letter_id');
    }

    public function attachments(): HasMany
    {
        return $this->hasMany(RecruitmentOfferLetterAttachment::class, 'offer_letter_id');
    }

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

    public function employee(): BelongsTo
    {
        return $this->belongsTo(\App\Modules\HR\Employees\Models\Employee::class);
    }
}
