<?php

namespace App\Modules\Operations\Repositories;

use App\Modules\Procurement\Models\GoodsReceipt;
use App\Modules\Procurement\Models\GoodsReceiptItem;
use App\Modules\Procurement\Models\PurchaseOrder;
use App\Modules\Procurement\Support\GoodsReceiptLifecycleStatus;
use App\Modules\Procurement\Support\PurchaseOrderLifecycleStatus;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Carbon;

class OperationalControlCenterQueryRepository
{
    /**
     * @return Collection<int, GoodsReceipt>
     */
    public function failedReceipts(int $tenantId): Collection
    {
        return GoodsReceipt::query()
            ->where('status', GoodsReceiptLifecycleStatus::Failed->value)
            ->with(['purchaseOrder:id,po_number'])
            ->orderByDesc('updated_at')
            ->limit(50)
            ->get();
    }

    /**
     * @return Collection<int, GoodsReceipt>
     */
    public function receiptsWithQuarantinedLines(int $tenantId): Collection
    {
        $ids = GoodsReceiptItem::query()
            ->where('tenant_id', $tenantId)
            ->whereNotNull('quarantined_at')
            ->distinct()
            ->pluck('goods_receipt_id')
            ->all();

        if ($ids === []) {
            return new Collection;
        }

        return GoodsReceipt::query()
            ->whereIn('id', $ids)
            ->with(['purchaseOrder:id,po_number'])
            ->orderByDesc('updated_at')
            ->limit(50)
            ->get();
    }

    /**
     * @return Collection<int, GoodsReceipt>
     */
    public function staleDraftReceipts(int $tenantId, int $draftStaleHours): Collection
    {
        $cut = Carbon::now()->subHours($draftStaleHours);

        return GoodsReceipt::query()
            ->where('status', GoodsReceiptLifecycleStatus::Draft->value)
            ->where('updated_at', '<', $cut)
            ->with(['purchaseOrder:id,po_number'])
            ->orderBy('updated_at')
            ->limit(50)
            ->get();
    }

    /**
     * @return Collection<int, GoodsReceipt>
     */
    public function staleValidatedReceipts(int $tenantId, int $validatedStaleHours): Collection
    {
        $cut = Carbon::now()->subHours($validatedStaleHours);

        return GoodsReceipt::query()
            ->where('status', GoodsReceiptLifecycleStatus::Validated->value)
            ->where('updated_at', '<', $cut)
            ->whereNull('posted_at')
            ->with(['purchaseOrder:id,po_number'])
            ->orderBy('updated_at')
            ->limit(50)
            ->get();
    }

    /**
     * @return \Illuminate\Database\Eloquent\Collection<int, PurchaseOrder>
     */
    public function purchaseOrdersAwaitingApproval(int $tenantId, int $limit = 25): Collection
    {
        return PurchaseOrder::query()
            ->where('tenant_id', $tenantId)
            ->where('status', PurchaseOrderLifecycleStatus::Draft->value)
            ->orderBy('updated_at')
            ->limit($limit)
            ->get(['id', 'tenant_id', 'po_number', 'status', 'updated_at']);
    }
}
