<?php

namespace App\Modules\HR\Recruitment\Services;

use App\Modules\HR\Recruitment\Events\RecruitmentCandidateCvCreated;
use App\Modules\HR\Recruitment\Events\RecruitmentCandidateCvDeleted;
use App\Modules\HR\Recruitment\Models\RecruitmentCandidate;
use App\Modules\HR\Recruitment\Models\RecruitmentCandidateCv;
use App\Modules\HR\Recruitment\Repositories\RecruitmentCandidateCvRepository;
use App\Support\SystemReferenceAssigner;
use App\Support\SystemReferenceGenerator;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class RecruitmentCandidateCvService
{
    public function __construct(
        private readonly RecruitmentCandidateCvRepository $repository,
        private readonly SystemReferenceAssigner $references,
        private readonly Dispatcher $events,
    ) {}

    public function store(
        RecruitmentCandidate $candidate,
        UploadedFile $file,
        ?int $userId = null,
        bool $isPrimary = false,
        ?string $notes = null,
    ): RecruitmentCandidateCv {
        $tenantId = (int) $candidate->tenant_id;
        $path = $file->store("tenants/{$tenantId}/recruitment/cvs", 'local');
        $actor = $userId !== null && $userId > 0 ? $userId : null;

        $cv = DB::transaction(function () use ($candidate, $file, $path, $actor, $isPrimary, $notes, $tenantId) {
            if ($isPrimary) {
                $this->repository->clearPrimaryForCandidate($tenantId, (int) $candidate->id);
            }

            $row = $this->repository->create([
                'tenant_id' => $tenantId,
                'candidate_id' => $candidate->id,
                'reference_code' => $this->references->pendingPlaceholder(SystemReferenceGenerator::CANDIDATE_CV),
                'file_path' => $path,
                'original_name' => $file->getClientOriginalName(),
                'file_size' => (int) $file->getSize(),
                'mime_type' => $file->getClientMimeType(),
                'is_primary' => $isPrimary,
                'notes' => $notes,
                'uploaded_by' => $actor,
            ]);

            return $this->references->assign($row, SystemReferenceGenerator::CANDIDATE_CV, 'reference_code');
        });

        $this->events->dispatch(new RecruitmentCandidateCvCreated($cv));

        return $cv;
    }

    public function destroy(RecruitmentCandidateCv $cv): void
    {
        if ($cv->file_path) {
            Storage::disk('local')->delete($cv->file_path);
        }
        $this->repository->softDelete($cv);
        $this->events->dispatch(new RecruitmentCandidateCvDeleted($cv));
    }
}
