<?php

namespace Modules\Inventory\Services;

use Modules\Inventory\Entities\InventoryItem;
use Modules\Inventory\Entities\InventoryStock;
use Modules\Inventory\Entities\InventoryItemCategory;
use Modules\Inventory\Entities\Supplier;
use Illuminate\Support\Facades\Cache;

/**
 * Inventory Cache Service
 * Provides caching for frequently accessed inventory data
 */
class InventoryCacheService
{
    /**
     * Cache duration in seconds
     */
    const CACHE_TTL = 300; // 5 minutes
    const STOCK_CACHE_TTL = 60; // 1 minute (more frequent updates)
    const LIST_CACHE_TTL = 600; // 10 minutes

    /**
     * Get stock level for an item (cached)
     * 
     * @param int $itemId
     * @param int $branchId
     * @return float
     */
    public static function getStockLevel(int $itemId, int $branchId): float
    {
        $cacheKey = "inventory.stock.{$itemId}.{$branchId}";
        
        return Cache::remember($cacheKey, self::STOCK_CACHE_TTL, function () use ($itemId, $branchId) {
            return InventoryStock::where('inventory_item_id', $itemId)
                ->where('branch_id', $branchId)
                ->sum('quantity');
        });
    }

    /**
     * Clear stock cache for an item
     * 
     * @param int $itemId
     * @param int|null $branchId
     */
    public static function clearStockCache(int $itemId, ?int $branchId = null): void
    {
        if ($branchId) {
            Cache::forget("inventory.stock.{$itemId}.{$branchId}");
        } else {
            // Clear for all branches
            Cache::forget("inventory.stock.{$itemId}.*");
        }
    }

    /**
     * Get inventory items list for a branch (cached)
     * 
     * @param int $branchId
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getItemsForBranch(int $branchId)
    {
        $cacheKey = "inventory.items.branch.{$branchId}";
        
        return Cache::remember($cacheKey, self::LIST_CACHE_TTL, function () use ($branchId) {
            return InventoryItem::where('branch_id', $branchId)
                ->with(['category', 'unit', 'stocks'])
                ->get();
        });
    }

    /**
     * Get categories for a branch (cached)
     * 
     * @param int $branchId
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getCategoriesForBranch(int $branchId)
    {
        $cacheKey = "inventory.categories.branch.{$branchId}";
        
        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($branchId) {
            return InventoryItemCategory::where('branch_id', $branchId)->get();
        });
    }

    /**
     * Get suppliers for a restaurant (cached)
     * 
     * @param int $restaurantId
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getSuppliersForRestaurant(int $restaurantId)
    {
        $cacheKey = "inventory.suppliers.restaurant.{$restaurantId}";
        
        return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($restaurantId) {
            return Supplier::where('restaurant_id', $restaurantId)->get();
        });
    }

    /**
     * Clear all inventory caches for a branch
     * 
     * @param int $branchId
     */
    public static function clearBranchCache(int $branchId): void
    {
        Cache::forget("inventory.items.branch.{$branchId}");
        Cache::forget("inventory.categories.branch.{$branchId}");
        
        // Clear stock caches for all items in this branch
        $items = InventoryItem::where('branch_id', $branchId)->pluck('id');
        foreach ($items as $itemId) {
            Cache::forget("inventory.stock.{$itemId}.{$branchId}");
        }
    }

    /**
     * Clear all inventory caches for a restaurant
     * 
     * @param int $restaurantId
     */
    public static function clearRestaurantCache(int $restaurantId): void
    {
        Cache::forget("inventory.suppliers.restaurant.{$restaurantId}");
        
        // Clear branch caches
        $branches = \App\Models\Branch::where('restaurant_id', $restaurantId)->pluck('id');
        foreach ($branches as $branchId) {
            self::clearBranchCache($branchId);
        }
    }

    /**
     * Clear all inventory caches
     */
    public static function clearAll(): void
    {
        Cache::flush(); // Nuclear option - consider more selective clearing
    }
}

