<?php

declare(strict_types=1);

namespace App\MessageHandler;

use App\Message\RunImageCleanupMessage;
use App\Repository\ImageRepository;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
class RunImageCleanupMessageHandler
{
    public function __construct(
        private readonly ImageRepository        $imageRepository,
        private readonly EntityManagerInterface $em,
        private readonly LoggerInterface        $logger,
        #[Autowire('%kernel.project_dir%')]
        private readonly string                 $projectDir,
    ) {}

    public function __invoke(RunImageCleanupMessage $message): void
    {
        $images = $this->imageRepository->findSoftDeleted();

        foreach ($images as $image) {
            if ($image->getApprovedDevices()->count() > 0) {
                continue;
            }

            try {
                $dir = $this->projectDir . '/var/storage/images/' . $image->getId();
                if (is_dir($dir)) {
                    $this->deleteDirectory($dir);
                }
                $this->em->remove($image);
                $this->logger->info('Hard-deleted image {id}', ['id' => $image->getId()]);
            } catch (\Throwable $e) {
                $this->logger->error('Failed to hard-delete image {id}: {msg}', [
                    'id'  => $image->getId(),
                    'msg' => $e->getMessage(),
                ]);
            }
        }

        $this->em->flush();
    }

    private function deleteDirectory(string $dir): void
    {
        foreach (new \FilesystemIterator($dir) as $item) {
            if ($item->isDir()) {
                $this->deleteDirectory($item->getPathname());
            } else {
                unlink($item->getPathname());
            }
        }
        rmdir($dir);
    }
}
