<?php

namespace App\Http\Requests\FeedConsumption;

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

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

    public function rules(): array
    {
        return [
            'farm_id'                => 'required|exists:farms,id',
            'consumption_date'       => 'required|date',
            'remarks'                => 'nullable|string',

            'items'                  => 'required|array|min:1',
            'items.*.building_id'    => 'required|exists:buildings,id',
            'items.*.batch_id'       => 'required|exists:batches,id',
            'items.*.age'            => 'required|integer|min:1',
            'items.*.item_id'        => 'required|exists:items,id',
            'items.*.quantity'       => 'required|numeric|min:0.001',
        ];
    }

    public function messages(): array
    {
        return [
            'farm_id.required'             => 'Farm is required.',
            'farm_id.exists'               => 'Selected farm does not exist.',

            'items.required'               => 'At least one item is required.',

            'items.*.building_id.required' => 'Building is required.',
            'items.*.building_id.exists'   => 'Selected building does not exist.',

            'items.*.batch_id.required'    => 'Batch is required.',
            'items.*.batch_id.exists'      => 'Selected batch does not exist.',

            'items.*.item_id.required'     => 'Feed item is required.',
            'items.*.item_id.exists'       => 'Selected feed item does not exist.',

            'items.*.quantity.required'    => 'Quantity is required.',
            'items.*.quantity.min'         => 'Quantity must be greater than zero.',
        ];
    }

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

            $farmId = Auth::user()->farm_id;

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

                $line = $index + 1;

                /*
            |--------------------------------------------------------------------------
            | Validate Building (must belong to user's farm)
            |--------------------------------------------------------------------------
            */
                $building = Building::where('id', $row['building_id'] ?? null)
                    ->where('farm_id', $farmId)
                    ->first();

                if (!$building) {
                    $validator->errors()->add(
                        "items.$index.building_id",
                        "Line {$line}: Invalid building for your farm."
                    );
                    continue; // stop further checks for this row
                }

                /*
            |--------------------------------------------------------------------------
            | Validate Batch (must belong to building + farm)
            |--------------------------------------------------------------------------
            */
                $batch = Batches::where('id', $row['batch_id'] ?? null)
                    ->where('building_id', $building->id)
                    ->whereHas('building', function ($q) use ($farmId) {
                        $q->where('farm_id', $farmId);
                    })
                    ->with('loading')
                    ->first();

                if (!$batch) {
                    $validator->errors()->add(
                        "items.$index.batch_id",
                        "Line {$line}: Invalid batch for selected building."
                    );
                    continue;
                }

                /*
            |--------------------------------------------------------------------------
            | FIFO Allocation Validation
            |--------------------------------------------------------------------------
            */
                if (!empty($row['item_id']) && !empty($row['quantity'])) {

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

                    if (!$item || !$batch->loading) {
                        continue;
                    }

                    $caretakerId = $batch->loading->caretaker_id;

                    $totalAllocated = MoveOrderItem::where('item_id', $row['item_id'])
                        ->where('remaining_qty', '>', 0)
                        ->whereHas('moveOrder', function ($query) use ($caretakerId) {
                            $query->where('caretaker_id', $caretakerId);
                        })
                        ->sum('remaining_qty');

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