<?php

namespace App\Services;

use App\Http\Resources\FeedConsumptionResource;
use App\Models\Batches;
use App\Models\Building;
use App\Models\FeedConsumption;
use App\Models\FeedConsumptionItem;
use App\Models\MoveOrderItem;
use App\Models\Transaction;
use Illuminate\Support\Facades\Auth;
use Exception;

class FeedConsumptionService
{
    protected $inventoryService;
    protected $auditTrail;

    public function __construct(InventoryService $inventoryService, AuditTrailService $auditTrail)
    {
        $this->inventoryService = $inventoryService;
        $this->auditTrail       = $auditTrail;
    }

    public function getAll($status)
    {
        $user_id = Auth::user()->id;

        return FeedConsumption::with([
            'consumption_items' => function ($query) {
                $query->with('item:id,code,name');
            },
        ])
            ->where("user_id", $user_id)
            ->useFilters()
            ->dynamicPaginate();
    }

    public function buildingBatches()
    {
        $lead_man = Auth::user()->id;

        return Batches::with(['farm', 'loading'])
            ->whereHas('farm', function ($query) use ($lead_man) {
                $query->where('lead_man_id', $lead_man);
            })
            ->where('status', 'active')
            ->dynamicPaginate();
    }

    public function getAvailableItems(int $batchId)
    {
        $farmId = Auth::user()->farm_id;

        $batch = Batches::with('loading')->where('farm_id', $farmId)->where("id", $batchId)->first();

        if (!$batch || !$batch->loading) {
            return collect();
        }

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

        $items = MoveOrderItem::with(['item:id,code,name', 'moveOrder:id,order_date,caretaker_id'])
            ->whereHas('moveOrder', function ($query) use ($caretakerId) {
                $query->where('caretaker_id', $caretakerId);
            })
            ->where('remaining_qty', '>', 0)
            ->orderBy('created_at', 'asc') // FIFO order
            ->get();

        return $items;
    }

    public function getById(int $id)
    {
        $feedConsumption = FeedConsumption::with([
            'consumption_items' => function ($query) {
                $query->with('item:id,code,name');
            },
        ])->where('id', $id)->first();

        if (!$feedConsumption) {
            return null;
        }

        return new FeedConsumptionResource($feedConsumption);
    }

    public function create(array $data)
    {
        $farmId = Auth::user()->farm_id;

        $feedConsumption = FeedConsumption::create([
            'farm_id'          => $farmId,
            'consumption_date' => $data['consumption_date'],
            'remarks'          => $data['remarks'] ?? null,
            'total_quantity'   => collect($data['items'])->sum('quantity'),
            'user_id'          => Auth::id(),
        ]);

        $lastBatch = null;

        foreach ($data['items'] as $row) {

            $building = Building::findOrFail($row['building_id']);
            $batch    = Batches::findOrFail($row['batch_id']);
            $lastBatch = $batch;

            $remainingToConsume = $row['quantity'];

            /**
             * FIFO: Query move order items for this item
             * ordered by created_at ASC (oldest allocation first).
             * Only pick items that still have remaining_qty > 0.
             */
            $moveOrderItems = MoveOrderItem::where('item_id', $row['item_id'])
                ->where('remaining_qty', '>', 0)
                ->orderBy('created_at', 'asc')
                ->get();

            foreach ($moveOrderItems as $moveOrderItem) {

                if ($remainingToConsume <= 0) break;

                // Take as much as available from this move order item
                $consumeQty = min($remainingToConsume, $moveOrderItem->remaining_qty);

                FeedConsumptionItem::create([
                    'feed_consumption_id' => $feedConsumption->id,
                    'move_order_item_id'  => $moveOrderItem->id,
                    'building_id'         => $building->id,
                    'batch_id'            => $batch->id,
                    'age_days'            => $row['age'] ?? null,
                    'item_id'             => $moveOrderItem->item_id,
                    'item_code_snapshot'  => $moveOrderItem->item_code_snapshot,
                    'item_name_snapshot'  => $moveOrderItem->item_name_snapshot,
                    'quantity'            => $consumeQty,
                ]);

                /**
                 * Consume allocation only.
                 * NO warehouse stock deduction here — that already
                 * happened when the move order was released.
                 */
                $this->inventoryService->consumeAllocation([
                    'farm_id'            => $farmId,
                    'move_order_item_id' => $moveOrderItem->id,
                    'quantity'           => $consumeQty,
                    'reference_id'       => $feedConsumption->id,
                    'remarks'            => $data['remarks'] ?? null,
                    'user_id'            => Auth::id(),
                ]);

                $remainingToConsume -= $consumeQty;
            }
        }

        if ($lastBatch) {
            Transaction::create([
                'batch_id'         => $lastBatch->id,
                'farm_id'          => $lastBatch->farm_id,
                'farm_name'        => $lastBatch->farm_name,
                'building_id'      => $lastBatch->building_id,
                'building_name'    => $lastBatch->building_name,
                'transaction_id'   => $feedConsumption->id,
                'transaction_type' => 'feed_consumption',
                'quantity'         => -$feedConsumption->total_quantity,
                'transaction_date' => $feedConsumption->consumption_date,
                'remarks'          => "Feed Consumption - Total: {$feedConsumption->total_quantity}",
                'created_by'       => Auth::id(),
            ]);
        }

        $this->auditTrail->log(
            __("models.transaction"),
            __("models.feed_consumption"),
            $feedConsumption->id,
            __("models.lc_created"),
            $feedConsumption,
            null,
            $data
        );

        return new FeedConsumptionResource(
            $feedConsumption->load(['consumption_items'])
        );
    }

    public function update(array $data, int $id) {}

    public function toggleArchive(int $id) {}
}
