<?php

declare(strict_types=1);

namespace Bot\Infrastructure\Link;

use Bot\Domain\Entity\Media;

/**
 * ذخیره‌ساز in-memory برای لینک‌های یکتای مدیا.
 * در نسخه مینیمال، داده‌ها فقط در طول اجرای پروسه نگه‌داری می‌شوند.
 * 
 * توجه: این کلاس از UUID برای ساخت لینک استفاده می‌کند.
 * برای استفاده پایدار، باید از DatabaseLinkStore استفاده شود.
 */
final class InMemoryLinkStore
{
    /**
     * ساخت لینک یکتا برای مدیا
     * 
     * @return string کد لینک (به صورت get_{uuid})
     */
    public function createForMedia(Media $media): string
    {
        $uuid = $media->getUuid();
        
        if ($uuid !== null && $uuid !== '') {
            // استفاده مستقیم از UUID
            return 'get_' . $uuid;
        }
        
        // اگر UUID وجود ندارد (مدیا قدیمی)، یک UUID v4 معتبر تولید می‌کنیم
        // این تضمین می‌کند که لینک فرمت معتبری دارد و قابل استخراج باشد
        // ⚠️ توجه: این UUID در دیتابیس ذخیره نمی‌شود، بنابراین findByUuid آن را پیدا نمی‌کند
        // برای حل این مشکل، باید UUID را در دیتابیس به‌روزرسانی کنید
        $generatedUuid = $this->generateUuid();
        return 'get_' . $generatedUuid;
    }

    /**
     * تولید UUID v4 معتبر
     * 
     * @return string 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))
        );
    }

    /**
     * استخراج UUID از کد لینک
     * 
     * @return string|null UUID در صورت موفقیت، null در غیر این صورت
     */
    public function extractUuid(string $code): ?string
    {
        // لاگ برای دیباگ
        error_log("[InMemoryLinkStore] extractUuid called with code: '{$code}'");
        
        // حذف پیشوند get_ اگر وجود دارد
        $payload = str_starts_with($code, 'get_') ? substr($code, 4) : $code;
        error_log("[InMemoryLinkStore] After removing 'get_' prefix: '{$payload}' | Length: " . strlen($payload));
        
        if (empty($payload)) {
            error_log("[InMemoryLinkStore] Payload is empty, returning null");
            return null;
        }
        
        // اگر payload یک UUID معتبر است (36 کاراکتر با فرمت استاندارد)
        $uuidPattern = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
        if (preg_match($uuidPattern, $payload)) {
            error_log("[InMemoryLinkStore] ✅ UUID pattern matched! Returning: '{$payload}'");
            return $payload;
        } else {
            error_log("[InMemoryLinkStore] ❌ UUID pattern did NOT match. Payload: '{$payload}' | Pattern: {$uuidPattern}");
        }
        
        // اگر payload فقط عدد است (لینک قدیمی)، null برمی‌گردانیم
        // چون دیگر از media_id استفاده نمی‌کنیم
        error_log("[InMemoryLinkStore] Returning null (not a valid UUID)");
        return null;
    }

    /**
     * استخراج media_id از کد لینک (برای سازگاری با لینک‌های قدیمی)
     * 
     * پشتیبانی از فرمت‌های مختلف:
     * - عدد خالص: 123456
     * - فرمت {user_id}_{media_id}: 8512015885_352108286
     * 
     * @deprecated استفاده از extractUuid توصیه می‌شود
     * @return int|null media_id در صورت موفقیت، null در غیر این صورت
     */
    public function extractMediaId(string $code): ?int
    {
        // حذف پیشوند get_ اگر وجود دارد
        $payload = str_starts_with($code, 'get_') ? substr($code, 4) : $code;
        
        if (empty($payload)) {
            return null;
        }
        
        // اگر payload فقط عدد است (لینک قدیمی)، مستقیماً برمی‌گردانیم
        if (ctype_digit($payload)) {
            return (int) $payload;
        }
        
        // اگر payload فرمت {user_id}_{media_id} دارد (مثل: 8512015885_352108286)
        if (preg_match('/^(\d+)_(\d+)$/', $payload, $matches)) {
            // قسمت دوم media_id است
            return (int) $matches[2];
        }
        
        // برای لینک‌های جدید با UUID، null برمی‌گردانیم
        return null;
    }

}


