<?php

namespace App\Modules\Sales\Repositories;

use App\Modules\Sales\Models\SalesOrder;
use App\Modules\Sales\Support\SalesOrderLifecycleStatus;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Collection;

class SalesOrderRepository
{
    public function lockByIdForTenant(int $tenantId, int $salesOrderId): ?SalesOrder
    {
        return SalesOrder::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->whereKey($salesOrderId)
            ->lockForUpdate()
            ->first();
    }

    public function save(SalesOrder $order): void
    {
        $order->save();
    }

    /**
     * @return LengthAwarePaginator<int, SalesOrder>
     */
    public function paginateOperationalIndex(?string $status, ?string $viewFocus, int $perPage = 25): LengthAwarePaginator
    {
        $q = SalesOrder::query()
            ->withSum('lines as ordered_qty_sum', 'quantity_ordered')
            ->withSum('lines as reserved_qty_sum', 'quantity_reserved')
            ->withSum('lines as fulfilled_qty_sum', 'quantity_fulfilled')
            ->orderByDesc('id');

        if ($status !== null && $status !== '') {
            $q->where('status', $status);
        }

        if ($viewFocus === 'allocation') {
            $q->whereIn('status', [
                SalesOrderLifecycleStatus::Confirmed->value,
                SalesOrderLifecycleStatus::PartiallyAllocated->value,
                SalesOrderLifecycleStatus::Allocated->value,
                SalesOrderLifecycleStatus::PartiallyFulfilled->value,
            ]);
        } elseif ($viewFocus === 'fulfillment') {
            $q->whereIn('status', [
                SalesOrderLifecycleStatus::PartiallyAllocated->value,
                SalesOrderLifecycleStatus::Allocated->value,
                SalesOrderLifecycleStatus::PartiallyFulfilled->value,
            ]);
        }

        return $q->paginate($perPage)->withQueryString();
    }

    /**
     * @return Collection<int, SalesOrder>
     */
    public function recentDraftOrdersForTenant(int $tenantId, int $limit = 25): Collection
    {
        return SalesOrder::query()
            ->where('tenant_id', $tenantId)
            ->where('status', SalesOrderLifecycleStatus::Draft->value)
            ->orderByDesc('id')
            ->limit($limit)
            ->get(['id', 'tenant_id', 'status', 'updated_at']);
    }
}
