<?php

namespace App\Modules\HR\Employees\Services;

use App\Modules\HR\Employees\DTOs\EmployeeFileUploads;
use App\Modules\HR\Employees\Enums\EmployeeDocumentType;
use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Employees\Repositories\EmployeeDocumentRepository;
use Illuminate\Http\UploadedFile;

class EmployeeDocumentSyncService
{
    public function __construct(
        private readonly EmployeePrivateFileStorage $storage,
        private readonly EmployeeDocumentRepository $documents,
    ) {}

    public function syncNewUploads(Employee $employee, EmployeeFileUploads $files): void
    {
        $tenantId = (int) $employee->tenant_id;
        $employeeId = (int) $employee->id;
        $userId = auth()->id();

        $this->storeOne($files->photo, $tenantId, $employeeId, $userId, EmployeeDocumentType::Photo);
        $this->storeOne($files->cv, $tenantId, $employeeId, $userId, EmployeeDocumentType::Cv);
        $this->storeOne(
            $files->nationalIdFront,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::NationalIdFront,
            $files->nationalIdExpiresAt,
        );
        $this->storeOne($files->nationalIdBack, $tenantId, $employeeId, $userId, EmployeeDocumentType::NationalIdBack);
        $this->storeOne(
            $files->passport,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::Passport,
            $files->passportExpiresAt,
        );
        $this->storeOne(
            $files->contract,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::Contract,
            $files->contractExpiresAt,
        );
        $this->storeOne($files->certificate, $tenantId, $employeeId, $userId, EmployeeDocumentType::Certificate);
        $this->storeOne(
            $files->residency,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::Residency,
            $files->residencyExpiresAt,
        );
        $this->storeOne(
            $files->visa,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::Visa,
            $files->visaExpiresAt,
        );
        $this->storeOne(
            $files->workPermit,
            $tenantId,
            $employeeId,
            $userId,
            EmployeeDocumentType::WorkPermit,
            $files->workPermitExpiresAt,
        );

        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::NationalIdFront, $files->nationalIdExpiresAt, $files->nationalIdFront);
        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::Passport, $files->passportExpiresAt, $files->passport);
        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::Contract, $files->contractExpiresAt, $files->contract);
        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::Residency, $files->residencyExpiresAt, $files->residency);
        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::Visa, $files->visaExpiresAt, $files->visa);
        $this->syncExpiryOnly($employeeId, EmployeeDocumentType::WorkPermit, $files->workPermitExpiresAt, $files->workPermit);
    }

    private function storeOne(
        ?UploadedFile $file,
        int $tenantId,
        int $employeeId,
        ?int $userId,
        EmployeeDocumentType $type,
        ?string $expiresAt = null,
    ): void {
        if (! $file instanceof UploadedFile) {
            return;
        }

        $path = $this->storage->storeUploaded($file, $tenantId, $employeeId, $type);
        $this->documents->replace($employeeId, $type, $path, $userId, $expiresAt);
    }

    private function syncExpiryOnly(
        int $employeeId,
        EmployeeDocumentType $type,
        ?string $expiresAt,
        ?UploadedFile $file,
    ): void {
        if ($file instanceof UploadedFile || $expiresAt === null || $expiresAt === '') {
            return;
        }

        $this->documents->updateExpiry($employeeId, $type, $expiresAt);
    }
}
