<?php

namespace App\Http\Requests\MoveOrder;

use App\Models\InventoryMovement;
use App\Models\Item;
use App\Models\MoveOrderItem;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class MoveUpdateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'order_date'                 => ['required', 'date'],
            'description'                => ['nullable', 'string', 'max:500'],
            'remarks'                    => ['nullable', 'string', 'max:500'],
            'caretaker_id'               => ['nullable', 'integer', 'exists:users,id'],

            'items'                      => ['required', 'array', 'min:1'],
            'items.*.item_id'            => ['required', 'integer', 'exists:items,id', 'distinct'],
            'items.*.requested_qty'      => ['required', 'numeric', 'min:0.01'],
        ];
    }

    public function messages(): array
    {
        return [
            'order_date.required'               => 'Order date is required.',
            'items.required'                    => 'At least one item is required.',
            'items.*.item_id.required'          => 'Item is required.',
            'items.*.item_id.exists'            => 'Selected item does not exist.',
            'items.*.item_id.distinct'          => 'Duplicate items found. Please combine them into one line.',
            'items.*.requested_qty.required'    => 'Requested quantity is required.',
            'items.*.requested_qty.min'         => 'Requested quantity must be greater than zero.',
        ];
    }

    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {

            if ($validator->errors()->isNotEmpty()) {
                return;
            }

            $moveOrderId = $this->route('id') ?? $this->route('move_order');
            $farmId      = Auth::user()->farm_id;

            foreach ($this->items ?? [] as $index => $row) {

                $line = $index + 1;

                if (empty($row['item_id']) || empty($row['requested_qty'])) {
                    continue;
                }

                $item = Item::find($row['item_id']);

                if (!$item) {
                    $validator->errors()->add(
                        "items.$index.item_id",
                        "Line {$line}: Item not found or has been deleted."
                    );
                    continue;
                }

                $computedSOH = (float) InventoryMovement::where('item_id', $item->id)
                    ->where('farm_id', $farmId)
                    ->selectRaw("SUM(CASE WHEN type = 'IN' THEN quantity ELSE -quantity END) as soh")
                    ->value('soh') ?? 0;

                if ($computedSOH <= 0) {
                    $validator->errors()->add(
                        "items.$index.requested_qty",
                        "Line {$line}: {$item->name} has no available stock in this farm."
                    );
                    continue;
                }

                if ($computedSOH < (float) $row['requested_qty']) {
                    $validator->errors()->add(
                        "items.$index.requested_qty",
                        "Line {$line}: Insufficient stock for {$item->name}. " .
                            "Available: {$computedSOH}, requested: {$row['requested_qty']}."
                    );
                    continue;
                }

                // Update only — block if requested_qty < already released
                $moveOrderItem = MoveOrderItem::where('move_order_id', $moveOrderId)
                    ->where('item_id', $row['item_id'])
                    ->first();

                if ($moveOrderItem && $moveOrderItem->released_qty > 0) {
                    if ((float) $row['requested_qty'] < $moveOrderItem->released_qty) {
                        $validator->errors()->add(
                            "items.$index.requested_qty",
                            "Line {$line}: Requested qty cannot be less than already released qty ({$moveOrderItem->released_qty})."
                        );
                    }
                }
            }
        });
    }
}
