<?php

namespace App\Services;

use App\Http\Resources\MoveOrderResource;
use App\Models\Building;
use App\Models\MoveOrder;
use App\Models\MoveOrderItem;
use App\Models\Item;
use Illuminate\Support\Facades\Auth;

class MoveOrderService
{
    protected InventoryService $inventoryService;
    protected AuditTrailService $auditTrail;
    protected DocumentNumberService $documentNumberService;

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

    public function getAll()
    {
        $move_order = MoveOrder::with(['moveItems.item'])
            ->useFilters()
            ->dynamicPaginate();

        return $move_order;
    }

    public function getById(int $id)
    {
        $move_order = MoveOrder::with(['moveItems.item'])->findOrFail($id);

        if (!$move_order) {
            return null;
        }

        return new MoveOrderResource(
            $move_order
        );
    }

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

        $documentNo = $this->documentNumberService->generate(
            prefix: 'MVO',
            table: 'move_orders',
        );

        $moveOrder = MoveOrder::create([
            'document_no'  => $documentNo,
            'order_date'   => $data['order_date'],
            'description'  => $data['description'] ?? null,
            'remarks'      => $data['remarks'] ?? null,
            'caretaker_id' => $data['caretaker_id'] ?? null,
            'user_id'      => Auth::id(),
            'farm_id'      => $farmId,
        ]);

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

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

            $moveOrderItem = MoveOrderItem::create([
                'move_order_id'      => $moveOrder->id,
                'item_id'            => $item->id,
                'requested_qty'      => $row['requested_qty'],
                'released_qty'       => 0,
                'remaining_qty'      => $row['requested_qty'],
                'item_code_snapshot' => $item->code,
                'item_name_snapshot' => $item->name,
            ]);

            $this->inventoryService->outWarehouse([
                'farm_id'            => $farmId,
                'item_id'            => $item->id,
                'quantity'           => $row['requested_qty'],
                'reference_id'       => $moveOrder->id,
                'move_order_item_id' => $moveOrderItem->id,
                'remarks'            => $data['remarks'] ?? null,
                'user_id'            => Auth::id(),
            ]);
        }

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

        return new MoveOrderResource(
            $moveOrder->load(['moveItems.item'])
        );
    }

    public function update(array $data, int $id)
    {
        $farmId = Auth::user()->farm_id;

        $moveOrder = MoveOrder::findOrFail($id);

        $moveOrder->update([
            'order_date'   => $data['order_date'],
            'description'  => $data['description'] ?? null,
            'remarks'      => $data['remarks'] ?? null,
            'caretaker_id' => $data['caretaker_id'] ?? null,
        ]);

        $submittedItemIds = collect($data['items'])->pluck('item_id')->toArray();

        // Remove items that were deleted from the request
        $moveOrder->moveItems()
            ->whereNotIn('item_id', $submittedItemIds)
            ->each(function ($moveOrderItem) use ($farmId) {
                if ($moveOrderItem->released_qty > 0) {
                    $this->inventoryService->reverseOutWarehouse([
                        'farm_id'     => $farmId,
                        'item_id'     => $moveOrderItem->item_id,
                        'reference_id' => $moveOrderItem->move_order_id,
                    ]);
                }
                $moveOrderItem->delete();
            });

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

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

            // ✅ $existing goes here — before updateOrCreate
            // so we know the current released/remaining state BEFORE it gets overwritten
            $existing = MoveOrderItem::where('move_order_id', $moveOrder->id)
                ->where('item_id', $item->id)
                ->first();

            $moveOrderItem = MoveOrderItem::updateOrCreate(
                [
                    'move_order_id' => $moveOrder->id,
                    'item_id'       => $item->id,
                ],
                [
                    'requested_qty'      => $row['requested_qty'],
                    'released_qty'       => $existing?->released_qty ?? 0,
                    'remaining_qty'      => $existing?->remaining_qty ?? $row['requested_qty'],
                    'item_code_snapshot' => $item->code,
                    'item_name_snapshot' => $item->name,
                ]
            );

            // If already released, sync the inventory movement too
            if ($existing && $existing->released_qty > 0) {
                $this->inventoryService->outWarehouseUpdate([
                    'farm_id'            => $farmId,
                    'item_id'            => $item->id,
                    'quantity'           => $existing->released_qty,
                    'reference_id'       => $moveOrder->id,
                    'move_order_item_id' => $moveOrderItem->id,
                    'remarks'            => $data['remarks'] ?? null,
                ]);
            }
        }

        $this->auditTrail->log(
            __("models.transaction"),
            __("models.move_order"),
            $moveOrder->id,
            __("models.lc_updated"),
            $moveOrder,
            null,
            $data
        );

        return new MoveOrderResource(
            $moveOrder->load(['moveItems.item'])
        );
    }

    public function toggleArchive(int $id) {}
}
