<?php

namespace App\Http\Controllers\Warehouse;

use App\Http\Controllers\Controller;
use App\Models\Warehouse\OutgoingTransaction;
use App\Models\Warehouse\OutgoingItem;
use App\Models\Warehouse\OutgoingFulfillment;
use App\Models\Warehouse\Project;
use App\Models\Warehouse\ProjectDivision;
use App\Models\Warehouse\ProjectInventory;
use App\Models\Warehouse\Supplier;
use App\Models\Warehouse\Inventory;
use App\Models\DirectDelivery;
use App\Models\DirectDeliveryItem;
use App\Models\Warehouse\MaterialTransferRequest;
use App\Models\Warehouse\MaterialTransferRequestItem;
use App\Models\Warehouse\StockMovement;
use App\Models\Warehouse\IndirectGoods\IndirectGoodsRequest;
use App\Models\DamagedItem;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class MaterialIssueController extends Controller
{
    /**
     * Display the material issue decision page
     */
    public function index(Request $request)
    {
        Gate::authorize('viewAny', \App\Models\Warehouse\Inventory::class);

        $viewMode = $request->get('view_mode', 'pending');

        if ($viewMode === 'completed') {
            // Show completed/fully issued requests
            $query = OutgoingTransaction::with(['project', 'division', 'requester', 'items.item'])
                                       ->where(function($q) {
                                           $q->whereIn('status', ['successful', 'completed', 'closed'])
                                             ->orWhere(function($q2) {
                                                 // Also include requests where all items have zero balance (fully fulfilled)
                                                 $q2->whereDoesntHave('items', function($q3) {
                                                     $q3->where('quantity_balance', '>', 0);
                                                 })->whereHas('items'); // must have at least one item
                                             });
                                       })
                                       ->latest('updated_at');

            $indirectQuery = IndirectGoodsRequest::with(['project', 'division', 'requester', 'items.indirectGood'])
                ->where('status', 'issued')
                ->latest('updated_at');
        } else {
            // Show pending material requests that need issue decisions
            // Only show requests that have at least one item with remaining balance
            $query = OutgoingTransaction::with(['project', 'division', 'requester', 'items.item'])
                                       ->whereNotIn('status', ['successful', 'cancelled', 'rejected', 'completed', 'closed'])
                                       ->whereHas('items', function($q) {
                                           $q->where('quantity_balance', '>', 0);
                                       })
                                       ->latest('created_at');

            $indirectQuery = IndirectGoodsRequest::with(['project', 'division', 'requester', 'items.indirectGood'])
                ->whereIn('status', ['approved', 'partially_issued'])
                ->whereHas('items', function($q) {
                    $q->where('quantity_balance', '>', 0);
                })
                ->latest('created_at');
        }

        // Apply filters
        if ($request->filled('project_id')) {
            $query->where('project_id', $request->project_id);
            $indirectQuery->where('project_id', $request->project_id);
        }

        if ($request->filled('date_from')) {
            $query->where('transaction_date', '>=', $request->date_from);
            $indirectQuery->where('request_date', '>=', $request->date_from);
        }

        if ($request->filled('date_to')) {
            $query->where('transaction_date', '<=', $request->date_to);
            $indirectQuery->where('request_date', '<=', $request->date_to);
        }

        $directRequests = $query->get()->map(function ($request) {
            $totalRequested = $request->items->sum('quantity_requested');
            $totalFulfilled = OutgoingFulfillment::where('outgoing_transaction_id', $request->id)
                ->sum('quantity_fulfilled');

            if (in_array($request->status, ['canceled', 'cancelled']) || $totalFulfilled == 0) {
                $dispatchStatus = 'pending';
                $dispatchClass = 'badge-light';
                $dispatchIcon = 'hourglass_empty';
                $dispatchLabel = 'Pending';
            } elseif ($totalFulfilled >= $totalRequested) {
                $dispatchStatus = 'fully_dispatched';
                $dispatchClass = 'badge-success';
                $dispatchIcon = 'check_circle';
                $dispatchLabel = 'Fully Dispatched';
            } else {
                $dispatchStatus = 'partially_dispatched';
                $dispatchClass = 'badge-warning';
                $dispatchIcon = 'schedule';
                $dispatchLabel = 'Partially Dispatched';
            }

            return (object) [
                'id' => $request->id,
                'source_type' => 'direct',
                'grouping_key' => $this->materialIssueGroupingKey(
                    $request->material_request_number ?: 'MR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT),
                    $request->project_id,
                    $request->requested_by
                ),
                'display_number_base' => $this->normalizeMaterialRequestNumber(
                    $request->material_request_number ?: 'MR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT)
                ),
                'goods_type_label' => 'Direct Goods',
                'goods_type_class' => 'primary',
                'display_number' => $request->material_request_number ?: 'MR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT),
                'display_date' => $request->transaction_date,
                'project' => $request->project,
                'project_id' => $request->project_id,
                'division' => $request->division,
                'requester' => $request->requester,
                'requested_by_id' => $request->requested_by,
                'items_count' => $request->items->count(),
                'updated_at_sort' => optional($request->updated_at)->timestamp ?: optional($request->created_at)->timestamp ?: 0,
                'dispatch_status' => $dispatchStatus,
                'dispatch_class' => $dispatchClass,
                'dispatch_icon' => $dispatchIcon,
                'dispatch_label' => $dispatchLabel,
                'process_url' => route('warehouse.material-issue.show', $request->id),
                'view_url' => route('warehouse.inventory.material-requests.view', $request->id),
                'print_url' => route('warehouse.inventory.material-issued.print', $request->id),
                'issue_url' => null,
            ];
        });

        $indirectRequests = $indirectQuery->get()->map(function ($request) {
            $isFullyIssued = $request->status === 'issued' || $request->items->sum('quantity_balance') <= 0;

            return (object) [
                'id' => $request->id,
                'source_type' => 'indirect',
                'grouping_key' => $this->materialIssueGroupingKey(
                    $request->request_number ?: 'IGMR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT),
                    $request->project_id,
                    $request->requested_by
                ),
                'display_number_base' => $this->normalizeMaterialRequestNumber(
                    $request->request_number ?: 'IGMR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT)
                ),
                'goods_type_label' => 'Indirect Goods',
                'goods_type_class' => 'warning',
                'display_number' => $request->request_number ?: 'IGMR-' . str_pad($request->id, 6, '0', STR_PAD_LEFT),
                'display_date' => $request->request_date,
                'project' => $request->project,
                'project_id' => $request->project_id,
                'division' => $request->division,
                'requester' => $request->requester,
                'requested_by_id' => $request->requested_by,
                'items_count' => $request->items->count(),
                'updated_at_sort' => optional($request->updated_at)->timestamp ?: optional($request->created_at)->timestamp ?: 0,
                'dispatch_status' => $isFullyIssued ? 'fully_dispatched' : ($request->status === 'partially_issued' ? 'partially_dispatched' : 'pending'),
                'dispatch_class' => $isFullyIssued ? 'badge-success' : ($request->status === 'partially_issued' ? 'badge-warning' : 'badge-light'),
                'dispatch_icon' => $isFullyIssued ? 'check_circle' : ($request->status === 'partially_issued' ? 'schedule' : 'hourglass_empty'),
                'dispatch_label' => $isFullyIssued ? 'Issued' : ($request->status === 'partially_issued' ? 'Partially Issued' : 'Ready to Issue'),
                'process_url' => null,
                'view_url' => route('warehouse.indirect-goods.requests.show', $request->id),
                'print_url' => route('warehouse.indirect-goods.requests.print', $request->id),
                'issue_url' => route('warehouse.indirect-goods.requests.issue', $request->id),
            ];
        });

        $pendingRequests = $directRequests
            ->concat($indirectRequests)
            ->groupBy('grouping_key')
            ->map(function ($rows) {
                return $this->combineMaterialIssueRows($rows);
            })
            ->sortByDesc('updated_at_sort')
            ->values();

        if ($viewMode !== 'completed') {
            // Additional filter to remove requests where ALL items have zero balance
            $pendingRequests = $pendingRequests->filter(function($request) {
                return $request->dispatch_status !== 'fully_dispatched';
            });
        }

        // Manual pagination of filtered results
        $page = request()->get('page', 1);
        $perPage = 15;
        $pendingRequests = new \Illuminate\Pagination\LengthAwarePaginator(
            $pendingRequests->forPage($page, $perPage),
            $pendingRequests->count(),
            $perPage,
            $page,
            ['path' => request()->url(), 'query' => request()->query()]
        );

        // Debug: Log what we found
        \Log::info('Material Issue Index - Pending Requests', [
            'count' => $pendingRequests->count(),
            'status_check' => OutgoingTransaction::select('id', 'status', 'material_request_number')->get()->toArray()
        ]);

        // Get filter options
        $projects = Project::all();

        // Get statistics
        $stats = [
            'pending_decisions' => OutgoingTransaction::whereNotIn('status', ['successful', 'cancelled', 'rejected', 'completed', 'closed'])
                                    ->whereHas('items', function($q) {
                                        $q->where('quantity_balance', '>', 0);
                                    })->count()
                                    + IndirectGoodsRequest::whereIn('status', ['approved', 'partially_issued'])
                                        ->whereHas('items', function($q) {
                                            $q->where('quantity_balance', '>', 0);
                                        })->count(),
            'inventory_issues' => OutgoingTransaction::where('status', 'successful')->count()
                + IndirectGoodsRequest::where('status', 'issued')->count(),
            'direct_deliveries' => \App\Models\DirectDelivery::whereIn('status', ['pending', 'delivered'])->count(),
            'project_transfers' => \App\Models\Warehouse\MaterialTransferRequest::whereIn('status', ['approved', 'partially_approved'])->count()
        ];

        return view('warehouse.material-issue.index', compact(
            'pendingRequests', 'projects', 'stats'
        ));
    }

    private function normalizeMaterialRequestNumber(?string $requestNumber): string
    {
        $requestNumber = trim((string) $requestNumber);

        return preg_replace('/-IG(?:-\d{6})?$/', '', $requestNumber) ?: $requestNumber;
    }

    private function materialIssueGroupingKey(?string $requestNumber, $projectId, $requestedBy): string
    {
        return implode('|', [
            $this->normalizeMaterialRequestNumber($requestNumber),
            $projectId ?: 'no-project',
            $requestedBy ?: 'no-requester',
        ]);
    }

    private function findMatchingIndirectRequest(OutgoingTransaction $transaction): ?IndirectGoodsRequest
    {
        $baseNumber = $this->normalizeMaterialRequestNumber(
            $transaction->material_request_number ?: 'MR-' . str_pad($transaction->id, 6, '0', STR_PAD_LEFT)
        );

        return IndirectGoodsRequest::with(['items.indirectGood'])
            ->where('project_id', $transaction->project_id)
            ->where('requested_by', $transaction->requested_by)
            ->where(function ($query) use ($baseNumber) {
                $query->where('request_number', $baseNumber . '-IG')
                    ->orWhere('request_number', 'LIKE', $baseNumber . '-IG-%');
            })
            ->latest('updated_at')
            ->first();
    }

    private function findMatchingDirectRequest(IndirectGoodsRequest $indirectRequest): ?OutgoingTransaction
    {
        $baseNumber = $this->normalizeMaterialRequestNumber(
            $indirectRequest->request_number ?: 'IGMR-' . str_pad($indirectRequest->id, 6, '0', STR_PAD_LEFT)
        );

        return OutgoingTransaction::with(['project', 'division', 'requester', 'items.item'])
            ->where('project_id', $indirectRequest->project_id)
            ->where('requested_by', $indirectRequest->requested_by)
            ->where(function ($query) use ($baseNumber) {
                $query->where('material_request_number', $baseNumber)
                    ->orWhere('material_request_number', 'LIKE', $baseNumber . '-%');
            })
            ->latest('updated_at')
            ->first();
    }

    private function combineMaterialIssueRows($rows): object
    {
        $rows = collect($rows)->sortBy(function ($row) {
            return $row->source_type === 'direct' ? 0 : 1;
        })->values();

        if ($rows->count() === 1) {
            $row = $rows->first();
            $row->goods_types = collect([(object) [
                'label' => $row->goods_type_label,
                'class' => $row->goods_type_class,
            ]]);
            $row->source_rows = $rows;

            return $row;
        }

        $first = $rows->first();
        $hasPending = $rows->contains(fn ($row) => $row->dispatch_status === 'pending');
        $hasPartial = $rows->contains(fn ($row) => $row->dispatch_status === 'partially_dispatched');
        $allDone = $rows->every(fn ($row) => $row->dispatch_status === 'fully_dispatched');
        $allPending = $rows->every(fn ($row) => $row->dispatch_status === 'pending');

        if ($allDone) {
            $dispatchStatus = 'fully_dispatched';
            $dispatchClass = 'badge-success';
            $dispatchIcon = 'check_circle';
            $dispatchLabel = 'Issued';
        } elseif ($allPending) {
            $dispatchStatus = 'pending';
            $dispatchClass = 'badge-light';
            $dispatchIcon = 'hourglass_empty';
            $dispatchLabel = 'Pending';
        } elseif ($hasPartial || $hasPending) {
            $dispatchStatus = 'partially_dispatched';
            $dispatchClass = 'badge-warning';
            $dispatchIcon = 'schedule';
            $dispatchLabel = 'Partially Issued';
        } else {
            $dispatchStatus = $first->dispatch_status;
            $dispatchClass = $first->dispatch_class;
            $dispatchIcon = $first->dispatch_icon;
            $dispatchLabel = $first->dispatch_label;
        }

        return (object) [
            'id' => $first->id,
            'source_type' => 'combined',
            'source_rows' => $rows,
            'goods_types' => $rows->map(fn ($row) => (object) [
                'label' => $row->goods_type_label,
                'class' => $row->goods_type_class,
            ])->unique('label')->values(),
            'display_number' => $first->display_number_base,
            'display_number_base' => $first->display_number_base,
            'display_date' => $rows->pluck('display_date')->filter()->sort()->first(),
            'project' => $first->project,
            'project_id' => $first->project_id,
            'division' => $first->division,
            'requester' => $first->requester,
            'requested_by_id' => $first->requested_by_id,
            'items_count' => $rows->sum('items_count'),
            'updated_at_sort' => $rows->max('updated_at_sort'),
            'dispatch_status' => $dispatchStatus,
            'dispatch_class' => $dispatchClass,
            'dispatch_icon' => $dispatchIcon,
            'dispatch_label' => $dispatchLabel,
            'process_url' => null,
            'view_url' => null,
            'print_url' => null,
            'issue_url' => null,
        ];
    }

    /**
     * Show a unified material issued detail page for direct and indirect goods.
     */
    public function showIssueDetails(Request $request, $id)
    {
        Gate::authorize('viewAny', \App\Models\Warehouse\Inventory::class);

        $directRequest = null;
        $indirectRequest = null;

        if ($request->query('source') === 'indirect') {
            $indirectRequest = IndirectGoodsRequest::with([
                'project',
                'division',
                'requester',
                'issuedBy',
                'items.indirectGood',
            ])->findOrFail($id);
            $directRequest = $this->findMatchingDirectRequest($indirectRequest);
        } else {
            $directRequest = OutgoingTransaction::with([
                'project',
                'division',
                'requester',
                'items.item',
                'fulfillments',
            ])->findOrFail($id);
            $indirectRequest = $this->findMatchingIndirectRequest($directRequest);
        }

        if ($indirectRequest) {
            $indirectRequest->loadMissing([
                'project',
                'division',
                'requester',
                'issuedBy',
                'items.indirectGood',
            ]);
        }

        $displayNumber = $directRequest
            ? $this->normalizeMaterialRequestNumber(
                $directRequest->material_request_number ?: 'MR-' . str_pad($directRequest->id, 6, '0', STR_PAD_LEFT)
            )
            : $this->normalizeMaterialRequestNumber(
                $indirectRequest->request_number ?: 'IGMR-' . str_pad($indirectRequest->id, 6, '0', STR_PAD_LEFT)
            );

        $project = $directRequest?->project ?? $indirectRequest?->project;
        $division = $directRequest?->division ?? $indirectRequest?->division;
        $requester = $directRequest?->requester ?? $indirectRequest?->requester;
        $requestDate = $directRequest?->transaction_date ?? $indirectRequest?->request_date;
        $status = $this->combinedIssueDetailStatus($directRequest, $indirectRequest);

        return view('warehouse.material-issue.issued-details', compact(
            'directRequest',
            'indirectRequest',
            'displayNumber',
            'project',
            'division',
            'requester',
            'requestDate',
            'status'
        ));
    }

    private function combinedIssueDetailStatus(?OutgoingTransaction $directRequest, ?IndirectGoodsRequest $indirectRequest): object
    {
        $statuses = collect([
            $directRequest?->status,
            $indirectRequest?->status,
        ])->filter()->values();

        $allIssued = $statuses->isNotEmpty() && $statuses->every(function ($status) {
            return in_array($status, ['successful', 'completed', 'closed', 'issued']);
        });

        $hasPartial = $statuses->contains(function ($status) {
            return in_array($status, ['partially_issued', 'partially_dispatched']);
        });

        return (object) [
            'label' => $allIssued ? 'Issued' : ($hasPartial ? 'Partially Issued' : 'Pending'),
            'class' => $allIssued ? 'success' : ($hasPartial ? 'warning' : 'secondary'),
        ];
    }

    /**
     * Print a unified material issued note for direct and indirect goods.
     */
    public function printIssueDetails(Request $request, $id)
    {
        Gate::authorize('viewAny', \App\Models\Warehouse\Inventory::class);

        $directRequest = null;
        $indirectRequest = null;

        if ($request->query('source') === 'indirect') {
            $indirectRequest = IndirectGoodsRequest::with([
                'project',
                'division',
                'requester',
                'approvedBy',
                'issuedBy',
                'items.indirectGood',
            ])->findOrFail($id);
            $directRequest = $this->findMatchingDirectRequest($indirectRequest);
        } else {
            $directRequest = OutgoingTransaction::with([
                'project',
                'division',
                'requester',
                'approver',
                'items.item',
            ])->findOrFail($id);
            $indirectRequest = $this->findMatchingIndirectRequest($directRequest);
        }

        if ($indirectRequest) {
            $indirectRequest->loadMissing([
                'project',
                'division',
                'requester',
                'approvedBy',
                'issuedBy',
                'items.indirectGood',
            ]);
        }

        if ($directRequest) {
            $directRequest->loadMissing(['project', 'requester', 'approver', 'items.item']);
        }

        $displayNumber = $directRequest
            ? $this->normalizeMaterialRequestNumber(
                $directRequest->material_request_number ?: 'MR-' . str_pad($directRequest->id, 6, '0', STR_PAD_LEFT)
            )
            : $this->normalizeMaterialRequestNumber(
                $indirectRequest->request_number ?: 'IGMR-' . str_pad($indirectRequest->id, 6, '0', STR_PAD_LEFT)
            );

        $project = $directRequest?->project ?? $indirectRequest?->project;
        $requester = $directRequest?->requester ?? $indirectRequest?->requester;
        $approver = $directRequest?->approver ?? $indirectRequest?->approvedBy ?? $indirectRequest?->issuedBy;
        $issueDate = $directRequest?->updated_at ?? $indirectRequest?->issued_at ?? $indirectRequest?->updated_at;

        $items = collect();

        if ($directRequest) {
            $items = $items->concat($directRequest->items->map(function ($item) {
                return [
                    'item_code' => $item->item->item_code ?? 'N/A',
                    'description' => $item->item->item_description ?? 'Unknown Item',
                    'unit' => $item->item->unit_of_measure ?? 'pcs',
                    'quantity_delivered' => (float) $item->quantity_released,
                    'inventory_qty' => 0,
                    'foc_qty' => 0,
                    'direct_delivery_qty' => 0,
                    'project_transfer_qty' => 0,
                    'fulfillment_breakdown' => [],
                    'remarks' => 'Direct',
                ];
            }));
        }

        if ($indirectRequest) {
            $items = $items->concat($indirectRequest->items->map(function ($item) {
                return [
                    'item_code' => $item->indirectGood->ig_code ?? 'N/A',
                    'description' => $item->indirectGood->ig_description ?? 'Unknown Item',
                    'unit' => $item->indirectGood->unit_of_measure ?? 'pcs',
                    'quantity_delivered' => (float) $item->quantity_released,
                    'inventory_qty' => 0,
                    'foc_qty' => 0,
                    'direct_delivery_qty' => 0,
                    'project_transfer_qty' => 0,
                    'fulfillment_breakdown' => [],
                    'remarks' => 'Indirect' . ($item->invoice_number ? ' - ' . $item->invoice_number : ''),
                ];
            }));
        }

        $materialIssued = [
            'id' => $directRequest?->id ?? $indirectRequest?->id,
            'issue_number' => $displayNumber,
            'issue_date' => $issueDate ? $issueDate->format('M d, Y') : now()->format('M d, Y'),
            'project' => $project ? (($project->project_number ? $project->project_number . ' - ' : '') . $project->project_name) : 'N/A',
            'project_name' => $project->project_name ?? 'N/A',
            'project_number' => $project->project_number ?? '',
            'issued_to' => $requester->name ?? 'N/A',
            'approved_by' => $approver->name ?? 'System',
            'status' => $this->combinedIssueDetailStatus($directRequest, $indirectRequest)->label,
            'total_items' => $items->count(),
            'notes' => trim(collect([$directRequest?->notes, $indirectRequest?->notes])->filter()->implode("\n")),
            'items' => $items->toArray(),
            'total_delivered' => $items->sum('quantity_delivered'),
        ];

        return view('warehouse.inventory.material-issued.print', compact('materialIssued'));
    }

    /**
     * Show the issue decision form for a specific material request
     */
    public function show(OutgoingTransaction $transaction)
    {
        Gate::authorize('view', $transaction);

        $transaction->load(['project', 'division', 'requester', 'items.item']);

        // Add debug logging for transaction 44
        if ($transaction->id == 44) {
            \Log::info('DEBUG: Loading transaction 44 for material issue', [
                'transaction_id' => $transaction->id,
                'material_request' => $transaction->material_request_number,
                'items_count' => $transaction->items->count()
            ]);
        }

        // Get issue history
        $fulfillments = OutgoingFulfillment::where('outgoing_transaction_id', $transaction->id)
            ->get()
            ->groupBy('item_id');

        // Get all item IDs for this transaction
        $itemIds = $transaction->items->pluck('item_id')->toArray();

        // FOC: quantity_available IS the available quantity
        $focQuantities = \App\Models\FocInventory::getAvailableStockByItem()
            ->filter(function($qty, $itemId) use ($itemIds) {
                return in_array($itemId, $itemIds);
            });

        // Calculate remaining quantities for each item (ensure all fulfillment types are included)
        foreach ($transaction->items as $item) {
            $issuedQty = 0;
            if (isset($fulfillments[$item->item_id])) {
                $issuedQty = $fulfillments[$item->item_id]->sum('quantity_fulfilled');
            }
            $item->quantity_fulfilled = $issuedQty; // Dynamic property for view
            $item->quantity_remaining = max(0, $item->quantity_requested - $issuedQty);

            // Set FOC available quantity from the bulk query result
            $focAvailable = $focQuantities[$item->item_id] ?? 0;
            $item->foc_available = $focAvailable;

            // Also set it using setAttribute to ensure it's properly set
            $item->setAttribute('foc_available', $focAvailable);

            // Debug logging for transaction 44 / item 2109
            if ($transaction->id == 44 && $item->item_id == 2109) {
                \Log::info('DEBUG: Item 2109 in transaction 44', [
                    'item_id' => $item->item_id,
                    'item_code' => $item->item->item_code ?? 'N/A',
                    'foc_available_set' => $item->foc_available,
                    'quantity_requested' => $item->quantity_requested,
                    'quantity_remaining' => $item->quantity_remaining
                ]);
            }
        }

        // Get options for different issue types
        $projects = Project::where('id', '!=', $transaction->project_id)->get();
        $suppliers = Supplier::where('status', 'active')->get();
        // Use ProjectDivision for divisions since inventory references project_divisions table
        $divisions = \App\Models\Warehouse\ProjectDivision::where('status', 'active')->orderBy('division_name')->get();

        // Get all divisions that have any FOC stock
        $focDivisionIds = \App\Models\FocInventory::where('quantity_available', '>', 0)
            ->distinct()
            ->pluck('division_id')
            ->filter()
            ->toArray();
        $focDivisions = \App\Models\Warehouse\ProjectDivision::whereIn('id', $focDivisionIds)
            ->where('status', 'active')
            ->orderBy('division_name')
            ->get();

        $indirectRequest = $this->findMatchingIndirectRequest($transaction);

        // Use multi-source view for better flexibility
        return view('warehouse.material-issue.decision-multi', compact(
            'transaction', 'projects', 'suppliers', 'divisions', 'focDivisions', 'indirectRequest'
        ));
    }

    /**
     * Process the issue decision
     */
    public function processDecision(Request $request, OutgoingTransaction $transaction)
    {
        $request->validate([
            'issue_type' => 'required|in:inventory_dispatch,direct_delivery,project_transfer,foc_transfer',
            'notes' => 'nullable|string',
        ]);

        $issueType = $request->issue_type;

        switch ($issueType) {
            case 'inventory_dispatch':
                return $this->processInventoryDispatch($request, $transaction);

            case 'direct_delivery':
                return $this->processDirectDelivery($request, $transaction);

            case 'project_transfer':
                return $this->processProjectTransfer($request, $transaction);

            default:
                return back()->with('error', 'Invalid issue type selected.');
        }
    }

    /**
     * Process inventory dispatch decision
     */
    private function processInventoryDispatch(Request $request, OutgoingTransaction $transaction)
    {
        $request->validate([
            'dispatch_date' => 'required|date|after_or_equal:today',
            'receiver_name' => 'required|string|max:255',
            'items' => 'required|array',
            'items.*.quantity_to_issue' => 'required|numeric|min:0.01',
        ]);

        // Update transaction items with quantities to issue
        foreach ($request->items as $itemId => $itemData) {
            $outgoingItem = $transaction->items()->where('item_id', $itemId)->first();
            if ($outgoingItem) {
                $outgoingItem->update([
                    'quantity_released' => $itemData['quantity_to_issue']
                ]);
            }
        }

        // Update transaction status and dispatch
        $transaction->update([
            'status' => 'processing',
            'receiver_name' => $request->receiver_name,
            'notes' => $request->notes
        ]);

        // Process the dispatch
        $transaction->approveAndDispatch(auth()->id());

        return redirect()->route('warehouse.material-issue.index')
            ->with('success', 'Material request processed for inventory dispatch successfully.');
    }

    /**
     * Process direct delivery decision
     */
    private function processDirectDelivery(Request $request, OutgoingTransaction $transaction)
    {
        $request->validate([
            'supplier_id' => 'nullable|exists:suppliers,id',
            'delivery_date' => 'required|date',
            'lpo_number' => 'nullable|string|max:255',
            'delivery_note_number' => 'nullable|string|max:255',
        ]);

        // Create Direct Delivery based on the material request
        $directDelivery = \App\Models\DirectDelivery::create([
            'delivery_date' => $request->delivery_date,
            'project_id' => $transaction->project_id,
            'project_division_id' => $transaction->division_id,
            'supplier_id' => $request->supplier_id,
            'purchase_order_number' => $request->lpo_number,
            'operation_type' => 'supplier_delivery',
            'delivery_type' => 'purchase_order',
            'workflow_status' => 'pending_supplier',
            'status' => 'pending',
            'material_request_id' => null,
            'currency' => 'AED',
            'exchange_rate' => 1.0000,
            'vat_rate' => 5.00,
        ]);

        // Create corresponding Incoming Transaction for dual tracking
        $incomingTransaction = \App\Models\Warehouse\IncomingTransaction::create([
            'transaction_date' => $request->delivery_date,
            'transaction_type' => 'direct_delivery',
            'supplier_id' => $request->supplier_id,
            'project_id' => $transaction->project_id,
            'project_number' => $transaction->project->project_number ?? null,
            'type_of_goods' => 'Material Request - Direct Delivery',
            'lpo_number' => $request->lpo_number,
            'delivery_note_number' => $request->delivery_note_number,
            'division_id' => \App\Models\Department::first()->id ?? 1, // Use first available department ID
            'total_amount' => 0, // Will be calculated from items
            'received_by' => auth()->id(),
            'received_by_name' => auth()->user()->name,
            'status' => 'pending',
            'notes' => "Direct delivery for material request: {$transaction->material_request_number}. " . $request->notes
        ]);

        $totalAmount = 0;

        // Create direct delivery items and corresponding incoming items
        foreach ($transaction->items as $outgoingItem) {
            $itemTotal = $outgoingItem->quantity_requested * ($outgoingItem->unit_price ?: 0);
            $totalAmount += $itemTotal;

            // Create direct delivery item
            \App\Models\DirectDeliveryItem::create([
                'direct_delivery_id' => $directDelivery->id,
                'item_id' => $outgoingItem->item_id,
                'quantity_ordered' => $outgoingItem->quantity_requested,
                'ordered_quantity' => $outgoingItem->quantity_requested,
                'unit_price' => $outgoingItem->unit_price ?: 0,
                'unit_price_aed' => $outgoingItem->unit_price ?: 0,
                'currency' => 'AED',
                'status' => 'pending',
            ]);

            // Create corresponding incoming item for dual tracking
            \App\Models\Warehouse\IncomingItem::create([
                'incoming_transaction_id' => $incomingTransaction->id,
                'item_id' => $outgoingItem->item_id,
                'quantity_received' => $outgoingItem->quantity_requested,
                'unit_price' => $outgoingItem->unit_price ?: 0,
                'total_price' => $itemTotal,
                'stock_status' => 'pending_delivery'
            ]);
        }

        // Update incoming transaction total amount
        $incomingTransaction->update(['total_amount' => $totalAmount]);

        // Update original transaction status
        $transaction->update([
            'status' => 'converted_to_direct_delivery',
            'notes' => $request->notes
        ]);

        return redirect()->route('warehouse.direct-deliveries.show', $directDelivery->id)
            ->with('success', 'Material request converted to direct delivery. Please update supplier and delivery details.');
    }

    /**
     * Process project transfer decision
     */
    private function processProjectTransfer(Request $request, OutgoingTransaction $transaction)
    {
        $request->validate([
            'source_project_id' => 'required|exists:projects,id|different:' . $transaction->project_id,
            'transfer_reason' => 'required|string|max:255',
            'required_date' => 'required|date|after:today',
            'priority' => 'required|in:low,medium,high,urgent',
        ]);

        // Create Material Transfer Request
        $transferRequest = \App\Models\Warehouse\MaterialTransferRequest::create([
            'request_date' => now(),
            'transferrer_project_id' => $request->source_project_id,
            'receiver_project_id' => $transaction->project_id,
            'transfer_reason' => $request->transfer_reason,
            'transfer_notes' => $request->notes,
            'priority' => $request->priority,
            'required_date' => $request->required_date,
            'requested_by' => auth()->id(),
            'status' => 'pending_transferrer_approval'
        ]);

        // Create transfer request items
        foreach ($transaction->items as $outgoingItem) {
            // Check available quantity in source project
            $projectInventory = \App\Models\Warehouse\ProjectInventory::where('project_id', $request->source_project_id)
                ->where('item_id', $outgoingItem->item_id)
                ->first();

            $availableQuantity = $projectInventory ? $projectInventory->available_for_transfer : 0;
            $estimatedUnitPrice = $projectInventory ? $projectInventory->unit_price : ($outgoingItem->unit_price ?: 0);

            \App\Models\Warehouse\MaterialTransferRequestItem::create([
                'transfer_request_id' => $transferRequest->id,
                'item_id' => $outgoingItem->item_id,
                'quantity_requested' => $outgoingItem->quantity_requested,
                'quantity_available' => $availableQuantity,
                'estimated_unit_price' => $estimatedUnitPrice,
                'transfer_notes' => "Generated from material request: {$transaction->material_request_number}"
            ]);
        }

        // Update original transaction status
        $transaction->update([
            'status' => 'converted_to_transfer',
            'notes' => $request->notes
        ]);

        return redirect()->route('warehouse.transfer-requests.show', $transferRequest->id)
            ->with('success', 'Material request converted to project transfer. Awaiting source project approval.');
    }

    /**
     * Process multi-source material issue decision
     */
    public function processMultiSource(Request $request, OutgoingTransaction $transaction)
    {
        // Debug: Check if method is being called
        if ($request->has('debug')) {
            return response()->json([
                'message' => 'Method reached successfully',
                'transaction_id' => $transaction->id,
                'request_data' => $request->all()
            ]);
        }

        \Log::info('processMultiSource called', [
            'transaction_id' => $transaction->id,
            'request_data' => $request->all()
        ]);

        // Build validation rules dynamically based on enabled sections
        $validationRules = [
            'enable_inventory' => 'required|in:0,1',
            'enable_delivery' => 'required|in:0,1',
            'enable_foc' => 'required|in:0,1',
            'inventory' => 'nullable|array',
            'delivery' => 'nullable|array',
            'foc' => 'nullable|array',
            'inventory_indirect' => 'nullable|array',
            'delivery_indirect' => 'nullable|array',
            'foc_indirect' => 'nullable|array',
            'inventory.*' => 'nullable|numeric|min:0',
            'delivery.*' => 'nullable|numeric|min:0',
            'foc.*' => 'nullable|numeric|min:0',
            'inventory_indirect.*' => 'nullable|numeric|min:0',
            'delivery_indirect.*' => 'nullable|numeric|min:0',
            'foc_indirect.*' => 'nullable|numeric|min:0',
            'inventory_division' => 'nullable|array',
            'inventory_division.*' => 'nullable|exists:project_divisions,id',
            'delivery_division' => 'nullable|array',
            'delivery_division.*' => 'nullable|exists:project_divisions,id',
            'inventory_indirect_division' => 'nullable|array',
            'inventory_indirect_division.*' => 'nullable|exists:project_divisions,id',
            'delivery_indirect_division' => 'nullable|array',
            'delivery_indirect_division.*' => 'nullable|exists:project_divisions,id',
            'foc_indirect_division' => 'nullable|array',
            'foc_indirect_division.*' => 'nullable|exists:project_divisions,id',
            'inventory_file' => 'nullable|file|max:10240|mimes:pdf,doc,docx,jpg,jpeg,png',
            'delivery_file' => 'nullable|file|max:10240|mimes:pdf,doc,docx,jpg,jpeg,png',
            'delivery_supplier_id' => 'nullable|required_if:enable_delivery,1|exists:suppliers,id',
            // FOC doesn't require reference selection - it works like inventory dispatch
            'foc_transfer_date' => 'required_if:enable_foc,1|date',
        ];

        // Add unit price and division validation when direct delivery is enabled
        if ($request->enable_delivery == '1') {
            // Get delivery items to validate unit prices and divisions for items with quantities
            $deliveryItems = $request->input('delivery', []);
            foreach ($deliveryItems as $itemId => $quantity) {
                if ($quantity > 0) {
                    $validationRules["delivery_unit_price.{$itemId}"] = 'required|numeric|min:0';
                    $validationRules["delivery_division.{$itemId}"] = 'required|exists:project_divisions,id';
                }
            }
        }

        foreach ([
            'inventory_indirect' => 'inventory_indirect_division',
            'delivery_indirect' => 'delivery_indirect_division',
            'foc_indirect' => 'foc_indirect_division',
        ] as $quantityField => $divisionField) {
            foreach ($request->input($quantityField, []) as $itemId => $quantity) {
                if ((float) $quantity > 0) {
                    $validationRules["{$divisionField}.{$itemId}"] = 'required|exists:project_divisions,id';
                }
            }
        }

        $request->validate($validationRules);

        \Log::info('Validation passed');

        // Handle file uploads
        $inventoryFile = null;
        $deliveryFile = null;

        if ($request->hasFile('inventory_file')) {
            $file = $request->file('inventory_file');
            $filename = 'inventory_' . time() . '_' . $file->getClientOriginalName();
            $uploadPath = 'uploads/material-issue/inventory';

            // Create directory if it doesn't exist
            $fullPath = public_path($uploadPath);
            if (!file_exists($fullPath)) {
                mkdir($fullPath, 0755, true);
            }

            // Move file to public directory
            $file->move($fullPath, $filename);
            $inventoryFile = $uploadPath . '/' . $filename;
        }

        if ($request->hasFile('delivery_file')) {
            $file = $request->file('delivery_file');
            $filename = 'delivery_' . time() . '_' . $file->getClientOriginalName();
            $uploadPath = 'uploads/material-issue/delivery';

            // Create directory if it doesn't exist
            $fullPath = public_path($uploadPath);
            if (!file_exists($fullPath)) {
                mkdir($fullPath, 0755, true);
            }

            // Move file to public directory
            $file->move($fullPath, $filename);
            $deliveryFile = $uploadPath . '/' . $filename;
        }


        // Convert string values to boolean
        $enableInventory = (bool) $request->input('enable_inventory');
        $enableDelivery = (bool) $request->input('enable_delivery');
        $enableFoc = (bool) $request->input('enable_foc');

        // Ensure at least one issue method is enabled
        if (!$enableInventory && !$enableDelivery && !$enableFoc) {
            return back()->with('error', 'Please enable at least one issue method.');
        }

        \Log::info('Multi-source form data:', [
            'enable_inventory' => $request->input('enable_inventory'),
            'enable_delivery' => $request->input('enable_delivery'),
            'enable_foc' => $request->input('enable_foc'),
            'converted_booleans' => [$enableInventory, $enableDelivery, $enableFoc],
            'inventory_data' => $request->inventory,
            'delivery_data' => $request->delivery,
            'foc_data' => $request->foc,
            'inventory_indirect_data' => $request->input('inventory_indirect', []),
            'delivery_indirect_data' => $request->input('delivery_indirect', []),
            'foc_indirect_data' => $request->input('foc_indirect', []),
        ]);

        try {
            \DB::beginTransaction();

            $results = [];
            $inventoryTotal = 0;
            $deliveryTotal = 0;
            $focTotal = 0;
            $indirectTotal = 0;

            // Initialize arrays to track what's being fulfilled
            $inventoryItems = [];
            $deliveryItems = [];
            $transferItems = [];

        // Process Inventory Dispatch if enabled
        if ($enableInventory && !empty($request->inventory)) {
            $inventoryItems = array_filter($request->inventory, function($qty) { return $qty > 0; });
            if (!empty($inventoryItems)) {
                $inventoryDivisions = $request->inventory_division ?: [];
                $inventoryResult = $this->processInventoryPortion($request, $transaction, $inventoryItems, $inventoryDivisions);
                $results[] = $inventoryResult;
                $inventoryTotal = array_sum($inventoryItems);
            }
        }

        // Process Direct Delivery if enabled
        if ($enableDelivery && !empty($request->delivery)) {
            $deliveryItems = array_filter($request->delivery, function($qty) { return $qty > 0; });
            if (!empty($deliveryItems)) {
                $deliveryResult = $this->processDirectDeliveryPortion($request, $transaction, $deliveryItems);
                $results[] = $deliveryResult;
                $deliveryTotal = array_sum($deliveryItems);
            }
        }


        // Process FOC Transfer if enabled
        if ($enableFoc && !empty($request->foc)) {
            $focItems = array_filter($request->foc, function($qty) { return $qty > 0; });
            if (!empty($focItems)) {
                $focDivisions = $request->foc_division ?: [];
                $focResult = $this->processFocTransferPortion($request, $transaction, $focItems, $focDivisions);
                $results[] = $focResult;
                $focTotal = array_sum($focItems);
            }
        }

        $indirectItems = [];
        $indirectDivisions = [];
        $indirectInputsByMethod = [
            'inventory' => $enableInventory ? $request->input('inventory_indirect', []) : [],
            'delivery' => $enableDelivery ? $request->input('delivery_indirect', []) : [],
            'foc' => $enableFoc ? $request->input('foc_indirect', []) : [],
        ];
        $indirectDivisionsByMethod = [
            'inventory' => $enableInventory ? $request->input('inventory_indirect_division', []) : [],
            'delivery' => $enableDelivery ? $request->input('delivery_indirect_division', []) : [],
            'foc' => $enableFoc ? $request->input('foc_indirect_division', []) : [],
        ];

        foreach ($indirectInputsByMethod as $method => $methodItems) {
            foreach ($methodItems as $itemId => $quantity) {
                $quantity = (float) $quantity;
                if ($quantity > 0) {
                    $indirectItems[$itemId] = ($indirectItems[$itemId] ?? 0) + $quantity;
                    $indirectDivisions[$itemId] = $indirectDivisionsByMethod[$method][$itemId] ?? ($indirectDivisions[$itemId] ?? null);
                }
            }
        }

        if (!empty($indirectItems)) {
            $indirectRequest = $this->findMatchingIndirectRequest($transaction);

            if (!$indirectRequest) {
                throw new \Exception('Matching indirect goods request was not found for this material request.');
            }

            $indirectReleasedBefore = $indirectRequest->items->sum('quantity_released');

            foreach ($indirectRequest->items as $item) {
                $requestedQty = (float) ($indirectItems[$item->id] ?? 0);
                if ($requestedQty > (float) $item->quantity_balance) {
                    throw new \Exception('Indirect goods quantity for ' . ($item->indirectGood->ig_code ?? 'item #' . $item->id) . ' exceeds the remaining balance.');
                }
            }

            if (!$indirectRequest->issueQuantities($indirectItems, auth()->id(), $indirectDivisions)) {
                throw new \Exception('Cannot issue indirect goods for request ' . $indirectRequest->request_number . '. Current status: ' . $indirectRequest->status);
            }

            $indirectRequest->refresh();
            $indirectRequest->load('items');
            $indirectTotal = max(0, $indirectRequest->items->sum('quantity_released') - $indirectReleasedBefore);

            $results[] = 'Indirect Goods: ' . $indirectRequest->request_number;
        }

        if ($inventoryTotal <= 0 && $deliveryTotal <= 0 && $focTotal <= 0 && $indirectTotal <= 0) {
            throw new \Exception('Please allocate quantities for at least one item before submitting.');
        }

        // Check if all items are fully fulfilled (using cumulative data from database)
        $fullyFulfilled = true;
        foreach ($transaction->items as $item) {
            // Get cumulative total from all fulfillments in database (including this request)
            $totalFulfilled = \App\Models\Warehouse\OutgoingFulfillment::where('outgoing_transaction_id', $transaction->id)
                ->where('item_id', $item->item_id)
                ->sum('quantity_fulfilled');

            // Check if this item is fully fulfilled
            if ($totalFulfilled < $item->quantity_requested) {
                $fullyFulfilled = false;
                break;
            }
        }

        // Update original transaction status based on issue progress
        if ($fullyFulfilled) {
            $transaction->update([
                'status' => 'processed_multi_source',
                'notes' => "Fully fulfilled via multi-source: Inventory({$inventoryTotal}), Delivery({$deliveryTotal})"
            ]);
        } else {
            // Keep as pending if partially fulfilled
            $existingNotes = $transaction->notes ?? '';
            $newNote = "Partially issued: Inventory({$inventoryTotal}), Delivery({$deliveryTotal})";
            $transaction->update([
                'status' => 'pending',
                'notes' => $existingNotes . "\n" . date('Y-m-d H:i') . " - " . $newNote
            ]);
        }

        // NOTE: Both inventory items and direct delivery items are already handled:
        // - Inventory items: handled by OutgoingTransaction->approveAndDispatch()->updateProjectInventory()
        // - Direct delivery items: handled by processDirectDeliveryPortion() lines 797-817
        // Passing either here would cause DOUBLE entry in project_inventory
        $this->updateProjectInventoryForMaterialIssue($transaction, [], [], []);

        // Store file records
        if ($inventoryFile && $enableInventory) {
            \App\Models\Warehouse\MaterialIssueFile::create([
                'outgoing_transaction_id' => $transaction->id,
                'issue_type' => 'inventory',
                'file_path' => $inventoryFile,
                'original_filename' => $request->file('inventory_file')->getClientOriginalName(),
                'uploaded_by' => auth()->id()
            ]);
        }

        if ($deliveryFile && $enableDelivery) {
            \App\Models\Warehouse\MaterialIssueFile::create([
                'outgoing_transaction_id' => $transaction->id,
                'issue_type' => 'delivery',
                'file_path' => $deliveryFile,
                'original_filename' => $request->file('delivery_file')->getClientOriginalName(),
                'uploaded_by' => auth()->id()
            ]);
        }


            // Create summary message
            $messages = [];
            if ($inventoryTotal > 0) $messages[] = "Inventory Dispatch: {$inventoryTotal} units processed";
            if ($deliveryTotal > 0) $messages[] = "Direct Delivery: {$deliveryTotal} units ordered";
            if ($focTotal > 0) $messages[] = "FOC Transfer: {$focTotal} units processed";
            if ($indirectTotal > 0) $messages[] = "Indirect Goods: {$indirectTotal} units issued";

            \DB::commit();

            \Log::info('Multi-source material issue completed successfully', [
                'transaction_id' => $transaction->id,
                'inventory_total' => $inventoryTotal,
                'delivery_total' => $deliveryTotal
            ]);

            return redirect()->route('warehouse.material-issue.index')
                ->with('success', 'Multi-source material issue processed successfully! ' . implode(', ', $messages));

        } catch (\Exception $e) {
            \DB::rollback();
            \Log::error('Multi-source material issue failed', [
                'transaction_id' => $transaction->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return back()
                ->with('error', 'Failed to process multi-source material issue: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * Process inventory portion of multi-source material issue
     */
    private function processInventoryPortion(Request $request, OutgoingTransaction $originalTransaction, array $inventoryItems, array $inventoryDivisions = [])
    {
        // Create a new outgoing transaction for inventory portion
        $inventoryTransaction = OutgoingTransaction::create([
            'transaction_date' => $request->inventory_dispatch_date ?: now(),
            'project_id' => $originalTransaction->project_id,
            'division_id' => $originalTransaction->division_id,
            'material_request_number' => $originalTransaction->material_request_number . '-INV',
            'type_of_goods' => 'Material Request - Inventory',
            'requested_by' => $originalTransaction->requested_by,
            'receiver_name' => $request->inventory_receiver_name,
            'status' => 'processing',
            'notes' => $request->inventory_notes ?: 'Multi-source: Inventory portion'
        ]);

        // Create inventory transaction items
        // Note: unit_price will be set correctly during approveAndDispatch() -> updateInventory()
        // based on actual FIFO deduction from inventory batches
        foreach ($inventoryItems as $itemId => $quantity) {
            if ($quantity > 0) {
                $originalItem = $originalTransaction->items()->where('item_id', $itemId)->first();
                $divisionId = $inventoryDivisions[$itemId] ?? null;

                OutgoingItem::create([
                    'outgoing_transaction_id' => $inventoryTransaction->id,
                    'item_id' => $itemId,
                    'division_id' => $divisionId,
                    'quantity_requested' => $quantity,
                    'quantity_released' => $quantity,
                    'unit_price' => 0, // Will be updated by updateInventory() with actual FIFO price
                ]);
            }
        }

        // Process the dispatch immediately
        $inventoryTransaction->approveAndDispatch(auth()->id());

        // Record issue records and update quantity_released on original transaction items
        foreach ($inventoryItems as $itemId => $quantity) {
            if ($quantity > 0) {
                OutgoingFulfillment::create([
                    'outgoing_transaction_id' => $originalTransaction->id,
                    'item_id' => $itemId,
                    'quantity_fulfilled' => $quantity,
                    'fulfillment_type' => 'inventory',
                    'reference_id' => $inventoryTransaction->id,
                    'reference_type' => 'OutgoingTransaction',
                    'notes' => 'Inventory dispatch'
                ]);

                // Update quantity_released on the original transaction item
                $outgoingItem = OutgoingItem::where('outgoing_transaction_id', $originalTransaction->id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($outgoingItem) {
                    $outgoingItem->quantity_released += $quantity;
                    $outgoingItem->save();
                }
            }
        }

        return ['type' => 'inventory', 'id' => $inventoryTransaction->id, 'total' => array_sum($inventoryItems)];
    }

    /**
     * Process direct delivery portion of multi-source material issue
     */
    private function processDirectDeliveryPortion(Request $request, OutgoingTransaction $originalTransaction, array $deliveryItems)
    {
        // Validate that supplier is selected for delivery
        if (empty($request->delivery_supplier_id)) {
            throw new \InvalidArgumentException('Supplier must be selected for direct delivery.');
        }

        // Get the first division from delivery items (use the division selected in the form)
        $selectedDivisionId = null;
        foreach ($deliveryItems as $itemId => $quantity) {
            if ($quantity > 0 && $request->input("delivery_division.{$itemId}")) {
                $selectedDivisionId = $request->input("delivery_division.{$itemId}");
                break;
            }
        }

        // Create Direct Delivery (marked as delivered since supplier delivers directly to site)
        $directDelivery = DirectDelivery::create([
            'delivery_date' => $request->delivery_date ?: now(),
            'project_id' => $originalTransaction->project_id,
            'project_division_id' => $selectedDivisionId ?: $originalTransaction->division_id,
            'supplier_id' => $request->delivery_supplier_id,
            'purchase_order_number' => $request->delivery_lpo_number,
            'operation_type' => 'supplier_delivery',
            'delivery_type' => 'purchase_order',
            'workflow_status' => 'completed',
            'status' => 'delivered',
            'material_request_id' => null,
            'material_request_number' => $originalTransaction->material_request_number,
            'outgoing_transaction_id' => $originalTransaction->id,
            'currency' => 'AED',
            'exchange_rate' => 1.0000,
            'vat_rate' => 5.00,
            'received_at' => now(),
            'received_by' => auth()->id(),
            'project_inventory_updated' => true, // Mark as true since we update PI below in this method
        ]);

        // Create corresponding Incoming Transaction for proper dual tracking
        $incomingTransaction = \App\Models\Warehouse\IncomingTransaction::create([
            'transaction_date' => $request->delivery_date ?: now()->addDays(7),
            'transaction_type' => 'direct_delivery',
            'supplier_id' => $request->delivery_supplier_id,
            'project_id' => $originalTransaction->project_id,
            'project_number' => $originalTransaction->project->project_number ?? null,
            'type_of_goods' => 'Material Request - Direct Delivery',
            'lpo_number' => $request->delivery_lpo_number,
            'delivery_note_number' => $request->delivery_note_number,
            'division_id' => $selectedDivisionId ?: (\App\Models\Department::first()->id ?? 1),
            'total_amount' => 0, // Will be calculated from items
            'received_by' => auth()->id(),
            'received_by_name' => auth()->user()->name,
            'status' => 'pending',
            'notes' => "Direct delivery for material request: {$originalTransaction->material_request_number}"
        ]);

        $totalAmount = 0;

        // Create direct delivery items and corresponding incoming items
        foreach ($deliveryItems as $itemId => $quantity) {
            if ($quantity > 0) {
                $unitPrice = $request->input("delivery_unit_price.{$itemId}", 0);
                $batchNumber = $request->input("delivery_batch.{$itemId}");
                $productionDate = $request->input("delivery_production_date.{$itemId}");
                $expiryDate = $request->input("delivery_expiry_date.{$itemId}");
                $divisionId = $request->input("delivery_division.{$itemId}");

                // Create direct delivery item (delivered to project site)
                DirectDeliveryItem::create([
                    'direct_delivery_id' => $directDelivery->id,
                    'item_id' => $itemId,
                    'quantity_ordered' => $quantity,
                    'ordered_quantity' => $quantity,
                    'delivered_quantity' => $quantity,
                    'unit_price' => $unitPrice,
                    'currency' => 'AED',
                    'status' => 'delivered',
                    'batch_number' => $batchNumber,
                    'production_date' => $productionDate ?: null,
                    'expiry_date' => $expiryDate ?: null,
                ]);

                // Create corresponding incoming item for dual tracking
                \App\Models\Warehouse\IncomingItem::create([
                    'incoming_transaction_id' => $incomingTransaction->id,
                    'item_id' => $itemId,
                    'quantity_received' => $quantity,
                    'unit_price' => $unitPrice,
                    'total_price' => $quantity * $unitPrice,
                    'production_date' => $productionDate ?: null,
                    'expiry_date' => $expiryDate ?: null,
                    'batch_number' => $batchNumber,
                    'stock_status' => 'in_stock'
                ]);

                // Create or update project inventory (direct delivery goes straight to project site)
                $existingProjectInventory = \App\Models\Warehouse\ProjectInventory::where('project_id', $originalTransaction->project_id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($existingProjectInventory) {
                    // Update existing project inventory
                    $newTotalQty = $existingProjectInventory->quantity_available + $quantity;
                    $newTotalValue = $existingProjectInventory->total_value + ($quantity * $unitPrice);
                    $newAvgPrice = $newTotalQty > 0 ? $newTotalValue / $newTotalQty : $unitPrice;

                    $existingProjectInventory->quantity_available += $quantity;
                    $existingProjectInventory->unit_price = $newAvgPrice;
                    $existingProjectInventory->total_value = $newTotalValue;
                    $existingProjectInventory->save();
                } else {
                    // Create new project inventory record
                    \App\Models\Warehouse\ProjectInventory::create([
                        'project_id' => $originalTransaction->project_id,
                        'item_id' => $itemId,
                        'quantity_available' => $quantity,
                        'allocated_quantity' => 0,
                        'unit_price' => $unitPrice,
                        'total_value' => $quantity * $unitPrice
                    ]);
                }

                $totalAmount += $quantity * $unitPrice;

                // Record division delivery tracking for direct deliveries
                if ($divisionId) {
                    $deliveryDate = $request->delivery_date ?: now();

                    $record = \App\Models\Warehouse\DivisionDelivery::firstOrNew([
                        'division_id' => $divisionId,
                        'item_id' => $itemId
                    ]);

                    if ($record->exists) {
                        $record->total_quantity_delivered += $quantity;
                        $record->total_quantity_issued += $quantity;
                        $record->total_value += ($quantity * $unitPrice);
                        $record->average_unit_price = $record->total_value / $record->total_quantity_delivered;
                        $record->last_delivery_date = $deliveryDate;
                    } else {
                        $record->total_quantity_delivered = $quantity;
                        $record->current_available_quantity = 0;
                        $record->total_quantity_issued = $quantity;
                        $record->average_unit_price = $unitPrice;
                        $record->total_value = $quantity * $unitPrice;
                        $record->first_delivery_date = $deliveryDate;
                        $record->last_delivery_date = $deliveryDate;
                    }

                    $record->last_updated = now();
                    $record->save();
                }

                // Create stock movements for direct delivery
                $projectName = $originalTransaction->project ? $originalTransaction->project->project_name : 'Unknown Project';
                $now = now();

                StockMovement::create([
                    'item_id' => $itemId,
                    'movement_type' => 'in',
                    'reference_type' => 'direct_delivery',
                    'reference_id' => $directDelivery->id,
                    'quantity_before' => 0,
                    'quantity_moved' => $quantity,
                    'quantity_after' => 0,
                    'division_id' => $divisionId ?: null,
                    'user_id' => auth()->id(),
                    'notes' => "Direct delivery from supplier to project: {$projectName} - MR: {$originalTransaction->material_request_number}",
                    'created_at' => $now,
                    'updated_at' => $now
                ]);

                StockMovement::create([
                    'item_id' => $itemId,
                    'movement_type' => 'out',
                    'reference_type' => 'direct_delivery',
                    'reference_id' => $directDelivery->id,
                    'quantity_before' => 0,
                    'quantity_moved' => $quantity,
                    'quantity_after' => 0,
                    'division_id' => $divisionId ?: null,
                    'user_id' => auth()->id(),
                    'notes' => "Direct delivery to project: {$projectName} - MR: {$originalTransaction->material_request_number}",
                    'created_at' => $now->copy()->addSecond(),
                    'updated_at' => $now->copy()->addSecond()
                ]);

                // Create fulfillment record
                OutgoingFulfillment::create([
                    'outgoing_transaction_id' => $originalTransaction->id,
                    'item_id' => $itemId,
                    'quantity_fulfilled' => $quantity,
                    'fulfillment_type' => 'direct_delivery',
                    'reference_id' => $directDelivery->id,
                    'reference_type' => 'DirectDelivery',
                    'notes' => 'Direct delivery issue'
                ]);

                // Update quantity_released on the original transaction item
                $outgoingItem = OutgoingItem::where('outgoing_transaction_id', $originalTransaction->id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($outgoingItem) {
                    $outgoingItem->quantity_released += $quantity;
                    $outgoingItem->save();
                }
            }
        }

        // Update incoming transaction total amount
        $incomingTransaction->update(['total_amount' => $totalAmount]);

        return ['type' => 'delivery', 'id' => $directDelivery->id, 'total' => array_sum($deliveryItems)];
    }

    /**
     * Process project transfer portion of multi-source material issue
     */
    private function processProjectTransferPortion(Request $request, OutgoingTransaction $originalTransaction, array $transferItems)
    {
        // Parse the selected reference to get type and ID
        $referenceData = $this->parseTransferReference($request->transfer_reference_id ?? null);

        // Create Material Transfer Request
        $transferRequest = MaterialTransferRequest::create([
            'request_date' => now(),
            'transferrer_project_id' => $request->transfer_source_project_id,
            'receiver_project_id' => $originalTransaction->project_id,
            'transfer_reason' => $request->transfer_reason ?: 'Multi-source material issue',
            'transfer_notes' => $request->transfer_notes ?: "Part of multi-source material request. Reference: " . ($request->transfer_reference_id ?: 'N/A'),
            'priority' => $request->transfer_priority ?: 'medium',
            'required_date' => $request->transfer_date ?: now()->addDays(3),
            'requested_by' => auth()->id(),
            'status' => 'approved' // Auto-approve for immediate transfer since quantities are verified
        ]);

        // Create transfer request items
        foreach ($transferItems as $itemId => $quantity) {
            if ($quantity > 0) {
                // Check available quantity in source project
                $projectInventory = ProjectInventory::where('project_id', $request->transfer_source_project_id)
                    ->where('item_id', $itemId)
                    ->first();

                $availableQuantity = $projectInventory ? $projectInventory->available_for_transfer : 0;
                $estimatedUnitPrice = $projectInventory ? $projectInventory->unit_price : 0;

                // Link to the original reference based on type
                $linkingFields = $this->getLinkingFieldsForReference($referenceData, $itemId);

                MaterialTransferRequestItem::create([
                    'transfer_request_id' => $transferRequest->id,
                    'item_id' => $itemId,
                    'quantity_requested' => $quantity,
                    'quantity_approved' => $quantity, // Auto-approve the full quantity
                    'quantity_available' => $availableQuantity,
                    'estimated_unit_price' => $estimatedUnitPrice,
                    'transfer_notes' => "Multi-source material issue portion",
                    'approval_status' => 'approved'
                ] + $linkingFields);

                // CRITICAL: Decrease source project inventory immediately
                $this->decreaseSourceProjectInventory($request->transfer_source_project_id, $itemId, $quantity);

                // Create issue record for project transfer
                OutgoingFulfillment::create([
                    'outgoing_transaction_id' => $originalTransaction->id,
                    'item_id' => $itemId,
                    'quantity_fulfilled' => $quantity,
                    'fulfillment_type' => 'project_transfer',
                    'reference_id' => $transferRequest->id,
                    'reference_type' => 'MaterialTransferRequest',
                    'notes' => 'Project transfer issue'
                ]);

                // Update quantity_released on the original transaction item
                $outgoingItem = OutgoingItem::where('outgoing_transaction_id', $originalTransaction->id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($outgoingItem) {
                    $outgoingItem->quantity_released += $quantity;
                    $outgoingItem->save();
                }
            }
        }

        return ['type' => 'transfer', 'id' => $transferRequest->id, 'total' => array_sum($transferItems)];
    }

    /**
     * Parse transfer reference ID to get type and ID
     */
    private function parseTransferReference($referenceId)
    {
        if (!$referenceId) {
            return ['type' => null, 'id' => null];
        }

        $parts = explode('_', $referenceId);
        if (count($parts) == 2) {
            return ['type' => $parts[0], 'id' => $parts[1]];
        }

        return ['type' => null, 'id' => null];
    }

    /**
     * Get linking fields for reference based on type
     */
    private function getLinkingFieldsForReference($referenceData, $itemId)
    {
        $fields = [];

        if (!$referenceData['type'] || !$referenceData['id']) {
            return $fields;
        }

        switch ($referenceData['type']) {
            case 'MR':
                // Link to Material Request (Outgoing Transaction)
                $outgoingItem = \App\Models\Warehouse\OutgoingItem::where('outgoing_transaction_id', $referenceData['id'])
                    ->where('item_id', $itemId)
                    ->first();
                if ($outgoingItem) {
                    $fields['outgoing_item_id'] = $outgoingItem->id;
                }
                break;

            case 'DD':
                // Link to Direct Delivery
                $deliveryItem = \App\Models\DirectDeliveryItem::where('direct_delivery_id', $referenceData['id'])
                    ->where('item_id', $itemId)
                    ->first();
                if ($deliveryItem) {
                    $fields['direct_delivery_item_id'] = $deliveryItem->id;
                }
                break;

            case 'MT':
                // Link to Material Transfer
                $transferItem = \App\Models\Warehouse\MaterialTransferRequestItem::where('transfer_request_id', $referenceData['id'])
                    ->where('item_id', $itemId)
                    ->first();
                if ($transferItem) {
                    $fields['material_transfer_item_id'] = $transferItem->id;
                }
                break;
        }

        return $fields;
    }

    /**
     * Decrease source project inventory
     */
    private function decreaseSourceProjectInventory($sourceProjectId, $itemId, $quantity)
    {
        $projectInventory = \App\Models\Warehouse\ProjectInventory::where('project_id', $sourceProjectId)
            ->where('item_id', $itemId)
            ->first();

        if ($projectInventory) {
            // Decrease available quantity
            $projectInventory->updateQuantity($quantity, 'subtract');

            \Log::info("Decreased source project inventory", [
                'project_id' => $sourceProjectId,
                'item_id' => $itemId,
                'quantity_decreased' => $quantity,
                'new_available' => $projectInventory->quantity_available
            ]);
        } else {
            \Log::warning("No project inventory found to decrease", [
                'project_id' => $sourceProjectId,
                'item_id' => $itemId,
                'quantity' => $quantity
            ]);
        }
    }

    /**
     * Update project inventory for all issued items across all issue methods
     */
    private function updateProjectInventoryForMaterialIssue(OutgoingTransaction $transaction, array $inventoryItems, array $deliveryItems, array $transferItems)
    {
        if (!$transaction->project_id) {
            return; // No project to update inventory for
        }

        // Combine all issued quantities by item
        $allIssuedItems = [];

        // Add inventory dispatch quantities
        foreach ($inventoryItems as $itemId => $quantity) {
            $allIssuedItems[$itemId] = ($allIssuedItems[$itemId] ?? 0) + $quantity;
        }

        // Add direct delivery quantities
        foreach ($deliveryItems as $itemId => $quantity) {
            $allIssuedItems[$itemId] = ($allIssuedItems[$itemId] ?? 0) + $quantity;
        }

        // Add project transfer quantities (these go to project inventory when transfer is completed)
        foreach ($transferItems as $itemId => $quantity) {
            $allIssuedItems[$itemId] = ($allIssuedItems[$itemId] ?? 0) + $quantity;
        }

        // Update project inventory for each issued item
        foreach ($allIssuedItems as $itemId => $totalIssued) {
            if ($totalIssued > 0) {
                $projectInventory = ProjectInventory::where('project_id', $transaction->project_id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($projectInventory) {
                    // Update existing record
                    $projectInventory->updateQuantity($totalIssued, 'add');
                } else {
                    // Create new record - get unit price from original request
                    $originalItem = $transaction->items()->where('item_id', $itemId)->first();
                    $unitPrice = $originalItem->unit_price ?? 0;

                    ProjectInventory::create([
                        'project_id' => $transaction->project_id,
                        'item_id' => $itemId,
                        'quantity_available' => $totalIssued,
                        'allocated_quantity' => 0,
                        'unit_price' => $unitPrice,
                        'total_value' => $totalIssued * $unitPrice
                    ]);
                }
            }
        }
    }

    /**
     * Get FOC items for specific item IDs
     */
    public function getFocItems(Request $request)
    {
        try {
            $itemIds = $request->input('item_ids', []);

            if (empty($itemIds)) {
                return response()->json([
                    'success' => false,
                    'message' => 'No item IDs provided'
                ]);
            }

            // Get approved FOC items (damaged items with approved status)
            $focItems = DamagedItem::with(['item'])
                ->where('status', 'approved')
                ->whereIn('item_id', $itemIds)
                ->where('quantity', '>', 0)
                ->get()
                ->map(function($focItem) {
                    return [
                        'id' => $focItem->id,
                        'item_id' => $focItem->item_id,
                        'item_code' => $focItem->item->item_code ?? 'N/A',
                        'item_description' => $focItem->item->item_description ?? 'N/A',
                        'available_quantity' => $focItem->quantity,
                        'damage_description' => $focItem->damage_description,
                        'damage_severity' => $focItem->damage_severity,
                        'source_reference' => $focItem->source_reference ?? 'FOC-' . str_pad($focItem->id, 6, '0', STR_PAD_LEFT),
                        'unit_cost' => 0, // FOC items have no cost
                        'total_cost' => 0
                    ];
                })
                ->groupBy('item_id')
                ->map(function($group) {
                    // Calculate total available quantity per item
                    $totalQuantity = $group->sum('available_quantity');
                    $references = $group->pluck('source_reference')->unique()->implode(', ');

                    return [
                        'item_id' => $group->first()['item_id'],
                        'item_code' => $group->first()['item_code'],
                        'item_description' => $group->first()['item_description'],
                        'total_available' => $totalQuantity,
                        'references' => $references,
                        'foc_items' => $group->toArray()
                    ];
                });

            return response()->json([
                'success' => true,
                'data' => $focItems->values()
            ]);

        } catch (\Exception $e) {
            Log::error('Error fetching FOC items: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error fetching FOC items: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get available FOC references for dropdown (DEPRECATED - FOC should bypass reference selection)
     */
    public function getFocReferences(Request $request)
    {
        try {
            // FOC items should be treated like inventory dispatch - no reference selection needed
            // Return empty array to indicate no references required
            return response()->json([
                'success' => true,
                'references' => [],
                'message' => 'FOC items do not require reference selection'
            ]);

        } catch (\Exception $e) {
            Log::error('Error fetching FOC references: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error fetching FOC references'
            ]);
        }
    }

    /**
     * Get available FOC quantities for items (like inventory dispatch)
     */
    public function getFocAvailableQuantities(Request $request)
    {
        try {
            $itemIds = $request->input('item_ids', []);

            if (empty($itemIds)) {
                return response()->json([
                    'success' => true,
                    'data' => []
                ]);
            }

            // FOC: quantity_available IS the available quantity
            $focQuantities = \App\Models\FocInventory::whereIn('item_id', $itemIds)
                ->selectRaw('item_id, SUM(quantity_available) as total_quantity')
                ->groupBy('item_id')
                ->get()
                ->map(function($focItem) {
                    return [
                        'item_id' => $focItem->item_id,
                        'total_available' => $focItem->total_quantity,
                        'source_type' => 'FOC Inventory'
                    ];
                });

            return response()->json([
                'success' => true,
                'data' => $focQuantities
            ]);

        } catch (\Exception $e) {
            Log::error('Error fetching FOC available quantities: ' . $e->getMessage());

            return response()->json([
                'success' => false,
                'message' => 'Error fetching FOC quantities'
            ]);
        }
    }

    /**
     * Get FOC available quantity for a specific item and division
     */
    public function getFocDivisionStock($itemId, $divisionId)
    {
        try {
            $available = \App\Models\FocInventory::forItem($itemId)
                ->where('division_id', $divisionId)
                ->sum('quantity_available');

            return response()->json([
                'available_quantity' => (float) $available,
                'item_id' => (int) $itemId,
                'division_id' => (int) $divisionId,
            ]);
        } catch (\Exception $e) {
            Log::error('Error fetching FOC division stock: ' . $e->getMessage());
            return response()->json([
                'available_quantity' => 0,
                'item_id' => (int) $itemId,
                'division_id' => (int) $divisionId,
            ]);
        }
    }

    /**
     * Get indirect goods available quantity for a specific goods item and division.
     */
    public function getIndirectDivisionStock($indirectGoodId, $divisionId)
    {
        try {
            $available = \App\Models\Warehouse\IndirectGoods\IndirectGoodsInventory::where('indirect_good_id', $indirectGoodId)
                ->where('division_id', $divisionId)
                ->where('quantity_available', '>', 0)
                ->sum('quantity_available');

            return response()->json([
                'available_quantity' => (float) $available,
                'indirect_good_id' => (int) $indirectGoodId,
                'division_id' => (int) $divisionId,
            ]);
        } catch (\Exception $e) {
            Log::error('Error fetching indirect division stock: ' . $e->getMessage());

            return response()->json([
                'available_quantity' => 0,
                'indirect_good_id' => (int) $indirectGoodId,
                'division_id' => (int) $divisionId,
            ]);
        }
    }

    /**
     * Process FOC transfer portion of multi-source fulfillment
     */
    private function processFocTransferPortion(Request $request, OutgoingTransaction $transaction, array $focItems, array $focDivisions = [])
    {
        try {
            $transferDate = $request->input('foc_transfer_date', now());
            $transferReason = $request->input('foc_transfer_reason', 'FOC material transfer for project requirement');
            $transferNotes = $request->input('foc_notes', '');

            $processedItems = [];

            foreach ($focItems as $itemId => $quantityToTransfer) {
                if ($quantityToTransfer <= 0) continue;

                // Build FOC inventory query, filtered by division if selected
                $divisionId = $focDivisions[$itemId] ?? null;
                $focQuery = \App\Models\FocInventory::forItem($itemId)->available();
                if ($divisionId) {
                    $focQuery->where('division_id', $divisionId);
                }

                $totalAvailable = (clone $focQuery)->sum('quantity_available');

                if ($totalAvailable < $quantityToTransfer) {
                    $divisionInfo = $divisionId ? " in selected division" : "";
                    throw new \Exception("Insufficient FOC quantity for item ID {$itemId}{$divisionInfo}. Available: {$totalAvailable}, Requested: {$quantityToTransfer}");
                }

                $focInventoryItems = $focQuery
                    ->orderBy('received_at')
                    ->orderBy('created_at')
                    ->get();

                $remainingToTransfer = $quantityToTransfer;

                foreach ($focInventoryItems as $focInventoryItem) {
                    if ($remainingToTransfer <= 0) break;

                    $qtyFromThisItem = min($remainingToTransfer, $focInventoryItem->quantity_available);
                    $remainingToTransfer -= $qtyFromThisItem;

                    // Create fulfillment record for this portion
                    $fulfillment = OutgoingFulfillment::create([
                        'outgoing_transaction_id' => $transaction->id,
                        'item_id' => $itemId,
                        'fulfillment_type' => 'foc_transfer',
                        'quantity_fulfilled' => $qtyFromThisItem,
                        'unit_cost' => 0, // FOC items have no cost
                        'total_cost' => 0,
                        'supplier_id' => null,
                        'source_reference' => $focInventoryItem->source_reference ?? 'FOC-' . str_pad($focInventoryItem->id, 6, '0', STR_PAD_LEFT),
                        'notes' => $transferNotes,
                        'fulfillment_date' => $transferDate,
                        'created_by' => auth()->id(),
                        'metadata' => json_encode([
                            'foc_inventory_id' => $focInventoryItem->id,
                            'condition' => $focInventoryItem->condition,
                            'damage_severity' => $focInventoryItem->damage_severity,
                            'transfer_reason' => $transferReason,
                            'source_damaged_item_id' => $focInventoryItem->source_damaged_item_id
                        ])
                    ]);

                    // Dispatch FOC inventory using the new method with proper tracking
                    $focInventoryItem->dispatch(
                        $qtyFromThisItem,
                        "FOC dispatch for material issue - " . $transaction->material_request_number,
                        'material_issue',
                        $transaction->id,
                        $transaction->material_request_number
                    );

                    // Create stock movement for FOC dispatch (out from FOC to project)
                    $projectName = $transaction->project ? $transaction->project->project_name : 'Unknown Project';
                    StockMovement::create([
                        'item_id' => $itemId,
                        'movement_type' => 'out',
                        'reference_type' => 'foc_dispatch',
                        'reference_id' => $transaction->id,
                        'quantity_before' => 0,
                        'quantity_moved' => $qtyFromThisItem,
                        'quantity_after' => 0,
                        'division_id' => $focInventoryItem->division_id ?? null,
                        'user_id' => auth()->id(),
                        'notes' => "FOC dispatch to project: {$projectName} - MR: {$transaction->material_request_number}",
                    ]);

                    $processedItems[] = [
                        'item_id' => $itemId,
                        'quantity' => $qtyFromThisItem,
                        'source_reference' => $focInventoryItem->source_reference ?? 'FOC-' . str_pad($focInventoryItem->id, 6, '0', STR_PAD_LEFT),
                        'fulfillment_id' => $fulfillment->id,
                        'foc_inventory_id' => $focInventoryItem->id
                    ];
                }

                // Update outgoing item quantities
                $outgoingItem = OutgoingItem::where('outgoing_transaction_id', $transaction->id)
                    ->where('item_id', $itemId)
                    ->first();

                if ($outgoingItem) {
                    $outgoingItem->quantity_released += $quantityToTransfer;
                    $outgoingItem->save(); // quantity_balance is auto-calculated in the model's boot method
                }

                // Add to project inventory at zero cost (FOC)
                $this->updateProjectInventoryWithZeroCost($transaction->project_id, $itemId, $quantityToTransfer);

                Log::info("FOC Transfer processed", [
                    'transaction_id' => $transaction->id,
                    'item_id' => $itemId,
                    'quantity' => $quantityToTransfer,
                    'processed_items' => count($processedItems)
                ]);
            }

            return [
                'success' => true,
                'type' => 'foc_transfer',
                'items_processed' => count($processedItems),
                'total_quantity' => array_sum(array_column($processedItems, 'quantity')),
                'message' => 'FOC transfer completed successfully',
                'details' => $processedItems
            ];

        } catch (\Exception $e) {
            Log::error("FOC Transfer failed", [
                'transaction_id' => $transaction->id,
                'error' => $e->getMessage(),
                'foc_items' => $focItems
            ]);

            throw $e;
        }
    }

    /**
     * Debug method to inspect FOC inventory data
     */
    public function debugFocInventory(Request $request)
    {
        $itemId = $request->input('item_id');

        // Get all FOC inventory records for debugging
        $query = \App\Models\FocInventory::with(['item']);

        if ($itemId) {
            $query->where('item_id', $itemId);
        }

        $allRecords = $query->get();

        $availableRecords = \App\Models\FocInventory::available()
            ->when($itemId, fn($q) => $q->where('item_id', $itemId))
            ->get();

        $summary = [
            'total_records' => $allRecords->count(),
            'available_records' => $availableRecords->count(),
            'status_breakdown' => $allRecords->groupBy('status')->map->count(),
            'quality_status_breakdown' => $allRecords->groupBy('quality_status')->map->count(),
            'records_with_quantity' => $allRecords->where('quantity_available', '>', 0)->count(),
            'all_records' => $allRecords->toArray(),
            'available_records_details' => $availableRecords->toArray()
        ];

        return response()->json($summary);
    }

    /**
     * Update project inventory with zero cost for FOC items
     */
    private function updateProjectInventoryWithZeroCost($projectId, $itemId, $quantity)
    {
        $existingProjectInventory = ProjectInventory::where('project_id', $projectId)
            ->where('item_id', $itemId)
            ->first();

        if ($existingProjectInventory) {
            // Add to existing inventory at zero cost impact
            $existingProjectInventory->quantity_available += $quantity;
            $existingProjectInventory->save();
        } else {
            // Create new project inventory with zero cost
            ProjectInventory::create([
                'project_id' => $projectId,
                'item_id' => $itemId,
                'quantity_available' => $quantity,
                'allocated_quantity' => 0,
                'unit_price' => 0, // FOC items have zero cost
                'total_value' => 0
            ]);
        }
    }
}
