<?php

namespace App\Modules\Inventory\Contracts;

interface InventoryServiceInterface
{
    /**
     * Check if a product has sufficient stock in a specific warehouse.
     *
     * @param int $productId
     * @param int $warehouseId
     * @param float $quantity
     * @return bool
     */
    public function checkStock(int $productId, int $warehouseId, float $quantity): bool;

    /**
     * @param int $productId
     * @param int $warehouseId
     * @param float $quantity
     * @param string|null $reason
     * @param bool $force
     * @param string|null $slot
     * @return void
     */
    public function decreaseStock(int $productId, int $warehouseId, float $quantity, ?string $reason = null, bool $force = false, ?string $slot = null): void;

    /**
     * Get all active warehouses.
     * 
     * @return \Illuminate\Support\Collection
     */
    public function getAllWarehouses();

    /**
     * Get multiple products by their IDs.
     * 
     * @param array $ids
     * @return \Illuminate\Support\Collection
     */
    public function getProductsByIds(array $ids);

    /**
     * Get multiple warehouses by their codes.
     * 
     * @param array $codes
     * @return \Illuminate\Support\Collection
     */
    public function getWarehousesByCodes(array $codes);

    /**
     * Search products by name.
     * 
     * @param string $name
     * @return \Illuminate\Support\Collection
     */
    public function getProductsByName(string $name);

    /**
     * Get a specific product by ID.
     * 
     * @param int $id
     * @return object|null
     */
    public function getProduct(int $id);

    /**
     * Get a specific warehouse by ID.
     * 
     * @param int $id
     * @return object|null
     */
    public function getWarehouse(int $id);

    /**
     * Get all available inventories in a specific warehouse.
     * 
     * @param int $warehouseId
     * @return \Illuminate\Support\Collection
     */
    public function getInventoriesByWarehouse(int $warehouseId);

    /**
     * Get all products.
     * 
     * @return \Illuminate\Support\Collection
     */
    public function getAllProducts();

    /**
     * Get all units.
     * 
     * @return \Illuminate\Support\Collection
     */
    public function getUnits();

    /**
     * Create a new inventory record (e.g., for finished goods).
     * 
     * @param array $data
     * @return object
     */
    public function createInventoryRecord(array $data);

    /**
     * Decrease quantity of a specific inventory record.
     * 
     * @param int $inventoryId
     * @param float $quantity
     * @param string|null $reason
     * @param string|null $referenceType
     * @param int|string|null $referenceId
     * @return void
     */
    public function decreaseInventoryQuantity(int $inventoryId, float $quantity, ?string $reason = null, ?string $referenceType = null, $referenceId = null);

    /**
     * Find a specific inventory record by warehouse, product and batch.
     * 
     * @param int $warehouseId
     * @param int $productId
     * @param string|null $batchNumber
     * @return object|null
     */
    public function findInventoryByBatch(int $warehouseId, int $productId, ?string $batchNumber);

    /**
     * 取得即時庫存查詢資料（含統計卡片 + 分頁明細）。
     *
     * @param array $filters 篩選條件
     * @param int $perPage 每頁筆數
     * @return array
     */
    public function getStockQueryData(array $filters = [], ?int $perPage = null): array;

    /**
     * Get statistics for the dashboard.
     * 
     * @return array
     */
    public function getDashboardStats(): array;

    /**
     * 依倉庫名稱查找或建立倉庫（供外部整合用）。
     *
     * @param string $warehouseName
     * @return object
     */
    public function findOrCreateWarehouseByName(string $warehouseName);

    /**
     * Get top inventory value for dashboard.
     */
    public function getTopInventoryValue(int $limit = 5): \Illuminate\Support\Collection;

    /**
     * Get items expiring soon for dashboard.
     */
    public function getExpiringSoon(int $limit = 5): \Illuminate\Support\Collection;

    /**
     * Get inventory summary (group by product) for a specific warehouse code
     * 
     * @param string $code
     * @return \Illuminate\Support\Collection|null
     */
    public function getPosInventoryByWarehouseCode(string $code);

    /**
     * 處理批量入庫邏輯 (含批號產生與現有批號累加)。
     *
     * @param \App\Modules\Inventory\Models\Warehouse $warehouse
     * @param array $items 入庫品項清單
     * @param array $meta 資料包含 inboundDate, reason, notes
     * @return void
     */
    public function processIncomingInventory(\App\Modules\Inventory\Models\Warehouse $warehouse, array $items, array $meta): void;

    /**
     * 處理單一庫存項目的調整。
     *
     * @param \App\Modules\Inventory\Models\Inventory $inventory
     * @param array $data 包含 quantity, operation, type, reason, unit_cost 等
     * @return void
     */
    public function adjustInventory(\App\Modules\Inventory\Models\Inventory $inventory, array $data): void;
}