<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;

class CacheService
{
    // Cache TTL constants (in seconds)
    const MENU_CATEGORIES_TTL = 3600; // 1 hour
    const MENU_ITEMS_TTL = 1800; // 30 minutes
    const INVENTORY_TTL = 300; // 5 minutes
    const INVENTORY_SUMMARY_TTL = 600; // 10 minutes
    const REPORTS_TTL = 600; // 10 minutes

    /**
     * Generate a cache key with optional parameters
     */
    public static function key(string $prefix, ...$params): string
    {
        $filteredParams = array_filter($params, function ($param) {
            return $param !== null && $param !== '';
        });
        
        return $prefix . '_' . md5(serialize($filteredParams));
    }

    /**
     * Remember a value in cache
     */
    public static function remember(string $key, int $ttl, callable $callback)
    {
        return Cache::remember($key, $ttl, $callback);
    }

    /**
     * Forget a cache key
     */
    public static function forget(string $key): bool
    {
        return Cache::forget($key);
    }

    /**
     * Flush cache by pattern
     */
    public static function flushByPattern(string $pattern): void
    {
        try {
            // Try Redis first if available
            if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
                $keys = Cache::getRedis()->keys($pattern . '*');
                if (!empty($keys)) {
                    Cache::getRedis()->del($keys);
                }
            } else {
                // For file-based cache, we need to flush all cache since we can't pattern match
                Cache::flush();
            }
        } catch (\Exception $e) {
            // Fallback to simple cache flush
            Cache::flush();
        }
    }

    /**
     * Get HTTP headers for caching
     */
    public static function getHttpHeaders(string $type = 'default'): array
    {
        $headers = [
            'Cache-Control' => 'public, max-age=300', // 5 minutes default
            'Vary' => 'Accept, Authorization',
        ];

        switch ($type) {
            case 'menu':
                $headers['Cache-Control'] = 'public, max-age=1800'; // 30 minutes
                break;
            case 'inventory':
                $headers['Cache-Control'] = 'public, max-age=300'; // 5 minutes
                break;
            case 'reports':
                $headers['Cache-Control'] = 'public, max-age=600'; // 10 minutes
                break;
        }

        return $headers;
    }

    /**
     * Clear menu-related cache
     */
    public static function clearMenuCache(int $restaurantId, int $branchId = null): void
    {
        try {
            // Try to clear specific cache keys if possible
            if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
                $patterns = [
                    'pos_categories_' . $restaurantId,
                    'pos_items_' . $restaurantId,
                    'menu_categories_' . $restaurantId,
                    'menu_items_' . $restaurantId,
                ];

                foreach ($patterns as $pattern) {
                    self::flushByPattern($pattern);
                }
            } else {
                // For file-based cache, flush all cache to ensure menu changes are reflected
                Cache::flush();
            }
        } catch (\Exception $e) {
            // Fallback to simple cache flush
            Cache::flush();
        }
    }

    /**
     * Clear inventory-related cache
     */
    public static function clearInventoryCache(int $restaurantId, int $branchId = null): void
    {
        try {
            // Try to clear specific cache keys if possible
            if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
                $patterns = [
                    'inventory_' . $restaurantId,
                    'inventory_alerts_' . $restaurantId,
                    'inventory_summary_' . $restaurantId,
                ];

                foreach ($patterns as $pattern) {
                    self::flushByPattern($pattern);
                }
            } else {
                // For file-based cache, flush all cache to ensure inventory changes are reflected
                Cache::flush();
            }
        } catch (\Exception $e) {
            // Fallback to simple cache flush
            Cache::flush();
        }
    }
}