<?php

namespace App\Modules\HR\Recruitment\Services;

use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Recruitment\Events\RecruitmentOfferLetterStatusChanged;
use App\Modules\HR\Recruitment\Models\RecruitmentOfferLetter;
use App\Modules\HR\Recruitment\Repositories\RecruitmentApplicationRepository;
use App\Modules\HR\Recruitment\Repositories\RecruitmentCandidateRepository;
use App\Modules\HR\Recruitment\Repositories\RecruitmentOfferLetterRepository;
use App\Modules\HR\Recruitment\Support\ApplicationStatus;
use App\Modules\HR\Recruitment\Support\OfferLetterStatus;
use DateTimeInterface;
use Illuminate\Contracts\Events\Dispatcher;

class HiringLinkService
{
    public function __construct(
        private readonly RecruitmentApplicationRepository $applications,
        private readonly RecruitmentCandidateRepository $candidates,
        private readonly RecruitmentOfferLetterRepository $offers,
        private readonly RecruitmentOfferLetterStatusHistoryService $history,
        private readonly Dispatcher $events,
    ) {}

    public function linkEmployee(
        RecruitmentOfferLetter $offer,
        Employee $employee,
        DateTimeInterface $hiredAt,
        int $userId,
    ): void {
        $app = $offer->application;
        if ($app !== null) {
            $this->applications->update($app, [
                'employee_id' => $employee->id,
                'hired_at' => $hiredAt,
                'status' => ApplicationStatus::HIRED,
            ]);
        }
        $candidate = $offer->candidate;
        if ($candidate !== null) {
            $this->candidates->update($candidate, [
                'employee_id' => $employee->id,
                'hired_at' => $hiredAt,
            ]);
        }
        $from = OfferLetterStatus::ACCEPTED;
        $to = OfferLetterStatus::HIRED;
        $updated = $this->offers->update($offer, [
            'status' => $to,
            'employee_id' => $employee->id,
            'hired_at' => $hiredAt,
        ]);
        $this->history->record($updated, $from, $to, 'hire', $userId);
        $this->events->dispatch(new RecruitmentOfferLetterStatusChanged($updated, 'hire', $from, $to));
    }
}
