<?php

declare(strict_types=1);

namespace Bot\Domain\Service;

use Bot\Domain\Entity\Media;
use Bot\Domain\Repository\MediaRepositoryInterface;

final class MediaService
{
    public function __construct(
        private readonly MediaRepositoryInterface $mediaRepository,
    ) {
    }

    /**
     * @return Media[]
     */
    public function findById(int $id): ?Media
    {
        return $this->mediaRepository->findById($id);
    }

    public function findByUuid(string $uuid): ?Media
    {
        return $this->mediaRepository->findByUuid($uuid);
    }

    /**
     * @return Media[]
     */
    public function listByFolder(int $folderId): array
    {
        return $this->mediaRepository->findByFolderId($folderId);
    }

    public function createMedia(
        int $folderId,
        int $ownerAdminId,
        string $telegramFileId,
        string $type,
        ?string $caption = null,
        ?string $thumbnailFileId = null,
    ): Media {
        // تولید UUID v4 برای لینک امن
        $uuid = $this->generateUuid();

        // In a real implementation, id would be generated by persistence layer.
        $media = new Media(
            0,
            $folderId,
            $ownerAdminId,
            $telegramFileId,
            $type,
            $uuid,
            $thumbnailFileId,
        );

        if ($caption !== null) {
            $media->setCaption($caption);
        }

        $this->mediaRepository->save($media);

        // بعد از save، media با ID جدید ذخیره شده است
        // برای Database Repository، باید media را از repository بازیابی کنیم
        // چون Media readonly است و نمی‌توانیم ID را تغییر دهیم
        
        // اگر repository از DatabaseMediaRepository است، از lastInsertId استفاده می‌کنیم
        if ($this->mediaRepository instanceof \Bot\Infrastructure\Repository\Database\DatabaseMediaRepository) {
            $newId = $this->mediaRepository->getLastInsertId();
            if ($newId > 0) {
                $savedMedia = $this->mediaRepository->findById($newId);
                if ($savedMedia !== null) {
                    return $savedMedia;
                }
            }
        }
        
        // اگر از InMemory استفاده می‌شود یا پیدا نشد، از findByFolderId استفاده می‌کنیم
        $savedMedia = $this->mediaRepository->findByFolderId($folderId);
        foreach ($savedMedia as $m) {
            if ($m->getTelegramFileId() === $telegramFileId && $m->getId() > 0) {
                return $m;
            }
        }

        // اگر پیدا نشد، media اصلی را برمی‌گردانیم
        // (این نباید اتفاق بیفتد، اما برای اطمینان)
        return $media;
    }

    public function updateMedia(Media $media): void
    {
        $this->mediaRepository->save($media);
    }

    public function deleteMedia(int $id): void
    {
        // استفاده از cascade delete برای حذف داده‌های مرتبط
        // این کار در Repository انجام می‌شود
        $this->mediaRepository->delete($id);
    }

    /**
     * تولید UUID v4
     */
    private function generateUuid(): string
    {
        // استفاده از random_bytes برای تولید UUID v4
        $data = random_bytes(16);
        
        // تنظیم version (4) و variant bits
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // version 4
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // variant bits
        
        // تبدیل به فرمت استاندارد UUID
        return sprintf(
            '%08s-%04s-%04s-%04s-%012s',
            bin2hex(substr($data, 0, 4)),
            bin2hex(substr($data, 4, 2)),
            bin2hex(substr($data, 6, 2)),
            bin2hex(substr($data, 8, 2)),
            bin2hex(substr($data, 10, 6))
        );
    }
}



