<?php

namespace App\Http\Controllers;

use App\Models\FactoryProduct;
use App\Models\ProductionOrder;
use App\Support\NumberFormat;
use App\Support\ProductionOrderStatus;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class FinishedGoodsStockController extends Controller
{
    private const PER_PAGE_OPTIONS = [5, 10, 25, 50];

    public function index(Request $request): Response
    {
        $perPage = $request->integer('per_page', 10);
        if (! in_array($perPage, self::PER_PAGE_OPTIONS, true)) {
            $perPage = 10;
        }

        $search = $request->string('search')->trim()->toString();

        /** @var array<int, float> $pipelineByProduct */
        $pipelineByProduct = ProductionOrder::query()
            ->whereIn('status', [
                ProductionOrderStatus::PENDING,
                ProductionOrderStatus::IN_PROCESS,
            ])
            ->groupBy('factory_product_id')
            ->selectRaw('factory_product_id, SUM(quantity) as pipeline_quantity')
            ->pluck('pipeline_quantity', 'factory_product_id')
            ->map(fn ($quantity): float => round((float) $quantity, 3))
            ->all();

        $stocks = FactoryProduct::query()
            ->with('unit:id,name')
            ->when($search !== '', function ($query) use ($search): void {
                $query->where(function ($q) use ($search): void {
                    $q->where('name', 'like', '%'.$search.'%')
                        ->orWhereHas('unit', function ($unitQuery) use ($search): void {
                            $unitQuery->where('name', 'like', '%'.$search.'%');
                        });
                });
            })
            ->orderByDesc('id')
            ->paginate($perPage)
            ->withQueryString()
            ->through(fn (FactoryProduct $product): array => [
                'id' => $product->id,
                'name' => $product->name,
                'unit_name' => $product->unit?->name,
                'is_active' => $product->is_active,
                'stock_on_hand' => (string) $product->stock_on_hand,
                'defective_stock' => (string) $product->defective_stock,
                'expired_stock' => (string) $product->expired_stock,
                'in_production' => NumberFormat::quantity($pipelineByProduct[$product->id] ?? 0),
            ]);

        $summaryQuery = FactoryProduct::query();
        $totalStock = round((float) (clone $summaryQuery)->sum('stock_on_hand'), 3);
        $totalDefective = round((float) (clone $summaryQuery)->sum('defective_stock'), 3);
        $totalExpired = round((float) (clone $summaryQuery)->sum('expired_stock'), 3);
        $totalInProduction = round((float) ProductionOrder::query()
            ->whereIn('status', [
                ProductionOrderStatus::PENDING,
                ProductionOrderStatus::IN_PROCESS,
            ])
            ->sum('quantity'), 3);

        return Inertia::render('factory/stocks/index', [
            'stocks' => $stocks,
            'summary' => [
                'product_count' => (clone $summaryQuery)->count(),
                'total_stock' => NumberFormat::quantity($totalStock),
                'total_defective' => NumberFormat::quantity($totalDefective),
                'total_expired' => NumberFormat::quantity($totalExpired),
                'total_in_production' => NumberFormat::quantity($totalInProduction),
            ],
            'filters' => [
                'search' => $search,
                'per_page' => $perPage,
            ],
        ]);
    }
}
