<?php

namespace Modules\Inventory\Repositories;

use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Modules\Inventory\DTO\PurchaseRequisitionListFilter;
use Modules\Inventory\Enums\PurchaseRequisitionStatusEnum;
use Modules\Inventory\Models\PurchaseRequisition;
use Modules\Inventory\Models\PurchaseRequisitionItem;

class PurchaseRequisitionRepository
{
    public function getPurchaseInvoices(PurchaseRequisitionListFilter $filters, array $columns = ['*'], array $relations = []): LengthAwarePaginator
    {
        return PurchaseRequisition::query()
            ->select($columns)
            ->with($relations)
            ->filterStatus($filters->status)
            ->reqDateBetween($filters->fromDate, $filters->toDate)
            ->search($filters->search)
            ->latest('id')
            ->paginate($filters->perPage ?? 15);
    }

    public function find(int $id): PurchaseRequisition
    {
        return PurchaseRequisition::query()
            ->findOrFail($id);
    }

    public function findById(int $id, array $columns = ['*'], array $relations = []): PurchaseRequisition
    {
        return PurchaseRequisition::query()
            ->with($relations)
            ->select($columns)
            ->findOrFail($id);
    }

    public function findForUpdate(int $id, array $columns = ['*'], array $relations = []): PurchaseRequisition
    {
        return PurchaseRequisition::query()
            ->with($relations)
            ->select($columns)
            ->lockForUpdate()
            ->findOrFail($id);
    }

    public function create(array $data): PurchaseRequisition
    {
        return PurchaseRequisition::query()->create($data);
    }

    public function createItems(array $items): void
    {
        PurchaseRequisitionItem::query()->insert($items);
    }

    public function update(PurchaseRequisition $requisition, array $data): bool
    {
        return $requisition->update($data);
    }

    public function deleteItems(PurchaseRequisition $requisition): void
    {
        $requisition->items()->delete();
    }

    public function close(PurchaseRequisition $requisition): void
    {
        $requisition->update([
            'status' => PurchaseRequisitionStatusEnum::CLOSED->value,
            'closed_at' => now(),
        ]);
    }

    public function increasePurchasedQty(PurchaseRequisition $requisition, array $items): void
    {
        $calculatedItems = collect($items)->keyBy('purchase_requisition_item_id');

        foreach ($requisition->items as $requisitionItem) {
            if (!$item = $calculatedItems->get($requisitionItem->id)) {
                continue;
            }

            $requisitionItem->update([
                'purchased_qty' => $requisitionItem->purchased_qty + $item['base_qty']
            ]);
        }
    }
}
