<?php

namespace App\Services\Recruitment;

use App\Models\Applicant;
use App\Models\ApplicantStageEvent;
use App\Models\User;
use App\Notifications\ExternalApplicationNotification;
use App\Notifications\ReferralStageChangedNotification;
use App\Notifications\ReferralSubmittedNotification;
use App\Services\HrmsNotificationService;

class ApplicantStageService
{
    public function __construct(
        protected HrmsNotificationService $notifications,
        protected RecruitmentSlaService $sla
    ) {}

    public function recordInitial(Applicant $applicant, ?User $user = null, bool $notifyHr = true): ApplicantStageEvent
    {
        $event = ApplicantStageEvent::create([
            'company_id' => $applicant->company_id,
            'applicant_id' => $applicant->id,
            'from_stage' => null,
            'to_stage' => (string) ($applicant->stage ?? 'applied'),
            'changed_by_user_id' => $user?->id,
            'note_internal' => null,
            'note_referrer' => match ($applicant->source) {
                'referral' => 'Your referral was submitted successfully.',
                'careers' => 'Application received. Our HR team will review your profile.',
                default => null,
            },
        ]);

        if ($notifyHr && $applicant->company_id) {
            if ($applicant->source === 'referral') {
                $applicant->loadMissing(['referredBy', 'jobPosting']);
                $this->notifications->notifyUsersWithAnyPermission(
                    (int) $applicant->company_id,
                    ['recruitment_view'],
                    new ReferralSubmittedNotification($applicant),
                    array_filter([(int) ($user?->id ?? 0), (int) $applicant->referred_by_user_id])
                );
            } elseif ($applicant->source === 'careers') {
                $applicant->loadMissing('jobPosting');
                $this->notifications->notifyUsersWithAnyPermission(
                    (int) $applicant->company_id,
                    ['recruitment_view'],
                    new ExternalApplicationNotification($applicant)
                );
            }
        }

        return $event;
    }

    public function recordChange(
        Applicant $applicant,
        string $fromStage,
        string $toStage,
        User $user,
        ?string $noteInternal = null,
        ?string $noteReferrer = null
    ): ApplicantStageEvent {
        $event = ApplicantStageEvent::create([
            'company_id' => $applicant->company_id,
            'applicant_id' => $applicant->id,
            'from_stage' => $fromStage,
            'to_stage' => $toStage,
            'changed_by_user_id' => $user->id,
            'note_internal' => $noteInternal,
            'note_referrer' => $noteReferrer,
        ]);

        if ($applicant->referred_by_user_id) {
            $applicant->loadMissing(['referredBy', 'jobPosting']);
            $referrer = $applicant->referredBy;
            if ($referrer) {
                $referrer->notify(new ReferralStageChangedNotification(
                    $applicant,
                    $fromStage,
                    $toStage,
                    $noteReferrer
                ));
            }
        }

        return $event;
    }
}
