<?php

namespace App\Modules\Sales\Repositories;

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

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, Request $request): 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');

        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,
            ]);
        }

        ListQuery::applySort(
            $q,
            $request->input('sort'),
            $request->input('dir'),
            [
                'order_number' => 'order_number',
                'status' => 'status',
                'created_at' => 'created_at',
            ],
            'id',
            'desc',
        );

        return ListQuery::paginate($q, $request);
    }

    /**
     * @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']);
    }
}
