<?php

namespace App\Services\Inventory;

use App\Services\BaseService;
use App\Repositories\StockItemRepository;
use App\Models\StockItem;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class StockItemService extends BaseService
{
    protected StockItemRepository $stockItemRepository;

    public function __construct(StockItemRepository $repository)
    {
        parent::__construct($repository);
        $this->stockItemRepository = $repository;
    }

    /**
     * Get with category
     */
    public function getAllWithCategory(): Collection
    {
        return $this->stockItemRepository->getWithCategory();
    }

    /**
     * Get by category
     */
    public function getByCategory(int $categoryId): Collection
    {
        return $this->stockItemRepository->getByCategory($categoryId);
    }

    /**
     * Get active items
     */
    public function getActive(): Collection
    {
        return $this->stockItemRepository->getActive();
    }

    /**
     * Search items
     */
    public function search(string $term): Collection
    {
        return $this->stockItemRepository->search($term);
    }

    /**
     * Get low stock items
     */
    public function getLowStock(): Collection
    {
        return $this->stockItemRepository->getLowStock();
    }

    /**
     * Generate item code
     */
    public function generateItemCode(): string
    {
        return nextNumber('STK', 'stock_items', 'item_code', 1);
    }

    /**
     * Adjust stock
     */
    public function adjustStock(int $id, float $quantity, string $type, ?string $reason = null): StockItem
    {
        return DB::transaction(function () use ($id, $quantity, $type, $reason) {
            $item = $this->findByIdOrFail($id);

            if ($type === 'add') {
                $item->increment('quantity', $quantity);
            } else {
                $item->decrement('quantity', $quantity);
            }

            $this->logAction('Stock adjusted', [
                'id' => $id,
                'type' => $type,
                'quantity' => $quantity,
                'reason' => $reason,
            ]);

            return $item->fresh();
        });
    }

    /**
     * Transfer stock between items
     */
    public function transferStock(int $fromId, int $toId, float $quantity): void
    {
        DB::transaction(function () use ($fromId, $toId, $quantity) {
            $this->adjustStock($fromId, $quantity, 'remove', 'Transfer to another item');
            $this->adjustStock($toId, $quantity, 'add', 'Transfer from another item');
        });
    }
}
