<?php

namespace App\Services;

use App\Http\Resources\StockTransferInResource;
use App\Models\Item;
use App\Models\StockTransferIn;
use App\Models\StockTransferInItem;
use App\Models\StockTransferOut;
use App\Models\StockTransferOutItem;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;

class StockTransferInService
{
    protected InventoryService $inventoryService;
    protected StockTransferOutService $stockTransferOutService;
    protected AuditTrailService $auditTrail;
    protected DocumentNumberService $documentNumberService;

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

    public function getAll()
    {
        $farmId = Auth::user()->farm_id;

        return StockTransferIn::with([
            'items.item',
            'transferOut.sourceFarm',
            'destinationFarm',
            'creator',
        ])
            ->where('destination_farm_id', $farmId)
            ->useFilters()
            ->dynamicPaginate();
    }

    public function getById(int $id)
    {
        $transferIn = StockTransferIn::with([
            'items.item',
            'transferOut.sourceFarm',
            'destinationFarm',
            'creator',
        ])->find($id);

        if (!$transferIn) {
            return null;
        }

        return new StockTransferInResource($transferIn);
    }

    public function getAllOutByFarm()
    {
        $farmId = Auth::user()->farm_id;

        return StockTransferOut::with([
            'items' => function ($query) {
                $query->where('remaining_qty', '>', 0);
            },
            'items.item',
            'destinationFarm',
            'creator',
            'sourceFarm',
        ])
            ->where('destination_farm_id', $farmId)
            ->whereHas('items', function ($query) {
                $query->where('remaining_qty', '>', 0);
            })
            ->useFilters()
            ->dynamicPaginate();
    }

    // -------------------------------------------------------------------------
    // CREATE (Transfer In / Receive)
    //
    // - Called by the DESTINATION farm user.
    // - Links to a Transfer Out via stock_transfer_out_id.
    // - Each item received must not exceed its remaining_qty on the Transfer Out.
    // - Destination farm SOH is credited per item received.
    // - Transfer Out item received_qty / remaining_qty is updated after each receive.
    // - Transfer Out status recalculated:
    //     pending            → partially_received (some items still have remaining_qty > 0)
    //     partially_received → completed          (all items fully received)
    // -------------------------------------------------------------------------
    public function create(array $data)
    {
        $destinationFarmId = Auth::user()->farm_id;

        $transferOut = StockTransferOut::findOrFail($data['stock_transfer_out_id']);

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

        $transferIn = StockTransferIn::create([
            'document_no'           => $documentNo,
            'stock_transfer_out_id' => $transferOut->id,
            'destination_farm_id'   => $destinationFarmId,
            'received_date'         => $data['received_date'],
            'remarks'               => $data['remarks'] ?? null,
            'user_id'               => Auth::id(),
        ]);

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

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

            $transferOutItem = StockTransferOutItem::where('stock_transfer_out_id', $transferOut->id)
                ->where('item_id', $item->id)
                ->firstOrFail();

            StockTransferInItem::create([
                'stock_transfer_in_id' => $transferIn->id,
                'item_id'              => $item->id,
                'quantity'             => $row['quantity'],
                'item_code_snapshot'   => $item->code,
                'item_name_snapshot'   => $item->name,
            ]);

            // 🔥 STOCK IN — destination farm SOH credited
            $this->inventoryService->inTransfer([
                'destination_farm_id' => $destinationFarmId,
                'item_id'             => $item->id,
                'quantity'            => $row['quantity'],
                'unit_cost'           => 0,
                'reference_id'        => $transferIn->id,
                'remarks'             => $data['remarks'] ?? null,
                'user_id'             => Auth::id(),
            ]);

            // Update Transfer Out item received/remaining quantities.
            $transferOutItem->update([
                'received_qty'  => $transferOutItem->received_qty + $row['quantity'],
                'remaining_qty' => $transferOutItem->remaining_qty - $row['quantity'],
            ]);
        }

        // Recalculate Transfer Out status after all items are processed.
        $this->stockTransferOutService->syncStatusAfterReceiving($transferOut);

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

        return new StockTransferInResource(
            $transferIn->load(['items.item', 'transferOut.sourceFarm', 'destinationFarm', 'creator'])
        );
    }
}
