<?php

namespace App\Modules\HR\Recruitment\Services;

use App\Modules\HR\Employees\Enums\EmployeeDocumentType;
use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Employees\Models\EmployeeDocument;
use App\Modules\HR\Employees\Repositories\EmployeeDocumentRepository;
use App\Modules\HR\Employees\Services\EmployeePrivateFileStorage;
use App\Modules\HR\Recruitment\Models\RecruitmentOnboardingCase;
use App\Modules\HR\Recruitment\Support\OnboardingSection;
use App\Modules\HR\Recruitment\Support\OnboardingTaskStatus;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;

class OnboardingDocumentService
{
    public function __construct(
        private readonly EmployeePrivateFileStorage $storage,
        private readonly EmployeeDocumentRepository $documents,
        private readonly OnboardingTaskService $tasks,
        private readonly OnboardingCaseService $cases,
    ) {}

    /** @return Collection<int, EmployeeDocument> */
    public function listForEmployee(Employee $employee): Collection
    {
        return EmployeeDocument::query()
            ->where('employee_id', $employee->id)
            ->orderBy('type')
            ->get();
    }

    public function upload(
        RecruitmentOnboardingCase $case,
        string $type,
        UploadedFile $file,
        int $userId,
        ?string $expiresAt = null,
    ): EmployeeDocument {
        $this->cases->assertNotCancelled($case);
        $docType = EmployeeDocumentType::from($type);
        $employee = $case->employee;
        abort_if($employee === null, 404);

        $path = $this->storage->storeUploaded($file, (int) $case->tenant_id, (int) $employee->id, $docType);
        $doc = $this->documents->replace((int) $employee->id, $docType, $path, $userId, $expiresAt);
        $this->completeMatchingDocumentTask($case, $docType->value, $userId);

        return $doc;
    }

    private function completeMatchingDocumentTask(
        RecruitmentOnboardingCase $case,
        string $hint,
        int $userId,
    ): void {
        $task = $case->tasks
            ->where('section', OnboardingSection::DOCUMENTS)
            ->first(fn ($t) => ($t->meta['document_hint'] ?? null) === $hint
                && ! in_array((string) $t->status, OnboardingTaskStatus::doneLike(), true));

        if ($task === null) {
            return;
        }

        $this->tasks->update($task, ['status' => OnboardingTaskStatus::COMPLETED], $userId);
    }
}
