<?php

namespace App\Http\Controllers\Warehouse;

use App\Http\Controllers\Controller;
use App\Models\Warehouse\MaterialTransferRequest;
use App\Models\Warehouse\MaterialTransferRequestItem;
use App\Models\Warehouse\Project;
use App\Models\Warehouse\Item;
use App\Models\Warehouse\ProjectInventory;
use App\Models\Warehouse\StockMovement;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class MaterialTransferRequestController extends Controller
{
    /**
     * Display a listing of transfer requests.
     */
    public function index(Request $request)
    {
        $query = MaterialTransferRequest::with([
            'transferrerProject',
            'receiverProject',
            'requestedBy',
            'items.item'
        ])->latest('request_date');

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

        if ($request->filled('transferrer_project_id')) {
            $query->where('transferrer_project_id', $request->transferrer_project_id);
        }

        if ($request->filled('receiver_project_id')) {
            $query->where('receiver_project_id', $request->receiver_project_id);
        }

        if ($request->filled('priority')) {
            $query->where('priority', $request->priority);
        }

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

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

        $transferRequests = $query->paginate(15);

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

        return view('warehouse.transfer-requests.index', compact(
            'transferRequests', 'projects'
        ));
    }

    /**
     * Show the form for creating a new transfer request.
     */
    public function create()
    {
        $projects = Project::all();
        $items = Item::all();
        $users = \App\Models\User::all(); // Add users for the requested_by field

        return view('warehouse.transfer-requests.create', compact('projects', 'items', 'users'));
    }

    /**
     * Store a newly created transfer request.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'transferrer_project_id' => 'required|exists:projects,id',
            'receiver_project_id' => 'required|exists:projects,id|different:transferrer_project_id',
            'transfer_reason' => 'required|string|max:255',
            'transfer_notes' => 'nullable|string',
            'priority' => 'required|in:low,medium,high,urgent',
            'required_date' => 'nullable|date|after:today',
            'requested_by' => 'required|exists:users,id',
            'request_date' => 'required|date',

            // Items
            'items' => 'required|array|min:1',
            'items.*.item_id' => 'required|exists:items,id',
            'items.*.quantity_requested' => 'required|numeric|min:0.01',
            'items.*.transfer_notes' => 'nullable|string'
        ]);

        DB::transaction(function () use ($validated, $request) {
            // Create transfer request
            $transferRequest = MaterialTransferRequest::create([
                'request_date' => $validated['request_date'],
                'transferrer_project_id' => $validated['transferrer_project_id'],
                'receiver_project_id' => $validated['receiver_project_id'],
                'transfer_reason' => $validated['transfer_reason'],
                'transfer_notes' => $validated['transfer_notes'] ?? null,
                'priority' => $validated['priority'],
                'required_date' => $validated['required_date'] ?? null,
                'requested_by' => $validated['requested_by'],
                'status' => $request->input('action') === 'save_draft' ? 'draft' : 'pending_transferrer_approval'
            ]);

            // Create transfer request items
            foreach ($validated['items'] as $itemData) {
                // Check available quantity in transferrer project
                $projectInventory = ProjectInventory::where('project_id', $validated['transferrer_project_id'])
                    ->where('item_id', $itemData['item_id'])
                    ->first();

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

                // Get item for unit price
                $item = Item::find($itemData['item_id']);
                $estimatedUnitPrice = $projectInventory ? $projectInventory->unit_price : ($item ? $item->unit_cost : 0);

                MaterialTransferRequestItem::create([
                    'transfer_request_id' => $transferRequest->id,
                    'item_id' => $itemData['item_id'],
                    'quantity_requested' => $itemData['quantity_requested'],
                    'quantity_available' => $availableQuantity,
                    'estimated_unit_price' => $estimatedUnitPrice,
                    'transfer_notes' => $itemData['transfer_notes'] ?? null
                ]);
            }

            // Update totals
            $transferRequest->refresh();
            $transferRequest->save(); // Triggers recalculation
        });

        return redirect()->route('warehouse.transfer-requests.index')
            ->with('success', 'Material Transfer Request created successfully.');
    }

    /**
     * Display the specified transfer request.
     */
    public function show(MaterialTransferRequest $transferRequest)
    {
        $transferRequest->load([
            'transferrerProject',
            'receiverProject',
            'requestedBy',
            'transferrerApprovedBy',
            'receiverApprovedBy',
            'rejectedBy',
            'items.item',
            'transferIssue'
        ]);

        return view('warehouse.transfer-requests.show', compact('transferRequest'));
    }

    /**
     * Show the form for editing the transfer request.
     */
    public function edit(MaterialTransferRequest $transferRequest)
    {
        // Only allow editing if in draft status
        if ($transferRequest->status !== 'draft') {
            return redirect()->back()
                ->with('error', 'Cannot edit transfer request after submission.');
        }

        $projects = Project::all();
        $items = Item::all();
        $transferRequest->load('items.item');

        return view('warehouse.transfer-requests.edit', compact(
            'transferRequest', 'projects', 'items'
        ));
    }

    /**
     * Update the specified transfer request.
     */
    public function update(Request $request, MaterialTransferRequest $transferRequest)
    {
        // Only allow updating if in draft status
        if ($transferRequest->status !== 'draft') {
            return redirect()->back()
                ->with('error', 'Cannot update transfer request after submission.');
        }

        $validated = $request->validate([
            'transferrer_project_id' => 'required|exists:projects,id',
            'receiver_project_id' => 'required|exists:projects,id|different:transferrer_project_id',
            'transfer_reason' => 'required|string|max:255',
            'transfer_notes' => 'nullable|string',
            'priority' => 'required|in:low,medium,high,urgent',
            'required_date' => 'nullable|date|after:today',
            'items' => 'required|array|min:1',
            'items.*.item_id' => 'required|exists:items,id',
            'items.*.quantity_requested' => 'required|numeric|min:0.01',
            'items.*.transfer_notes' => 'nullable|string'
        ]);

        DB::transaction(function () use ($transferRequest, $validated) {
            // Update transfer request
            $transferRequest->update([
                'transferrer_project_id' => $validated['transferrer_project_id'],
                'receiver_project_id' => $validated['receiver_project_id'],
                'transfer_reason' => $validated['transfer_reason'],
                'transfer_notes' => $validated['transfer_notes'] ?? null,
                'priority' => $validated['priority'],
                'required_date' => $validated['required_date'] ?? null
            ]);

            // Delete existing items and recreate
            $transferRequest->items()->delete();

            // Create updated transfer request items
            foreach ($validated['items'] as $itemData) {
                $projectInventory = ProjectInventory::where('project_id', $validated['transferrer_project_id'])
                    ->where('item_id', $itemData['item_id'])
                    ->first();

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

                // Get item for unit price
                $item = Item::find($itemData['item_id']);
                $estimatedUnitPrice = $projectInventory ? $projectInventory->unit_price : ($item ? $item->unit_cost : 0);

                MaterialTransferRequestItem::create([
                    'transfer_request_id' => $transferRequest->id,
                    'item_id' => $itemData['item_id'],
                    'quantity_requested' => $itemData['quantity_requested'],
                    'quantity_available' => $availableQuantity,
                    'estimated_unit_price' => $estimatedUnitPrice,
                    'transfer_notes' => $itemData['transfer_notes'] ?? null
                ]);
            }
        });

        return redirect()->route('warehouse.transfer-requests.show', $transferRequest)
            ->with('success', 'Transfer request updated successfully.');
    }

    /**
     * Submit transfer request for approval.
     */
    public function submit(MaterialTransferRequest $transferRequest)
    {
        if ($transferRequest->status !== 'draft') {
            return redirect()->back()
                ->with('error', 'Transfer request has already been submitted.');
        }

        $transferRequest->submitForApproval();

        return redirect()->back()
            ->with('success', 'Transfer request submitted for approval.');
    }

    /**
     * Show approval form for transfer request
     */
    public function showApproval(MaterialTransferRequest $transferRequest)
    {
        if (!in_array($transferRequest->status, ['pending_transferrer_approval', 'partially_approved'])) {
            return redirect()->back()
                ->with('error', 'Transfer request cannot be approved at this stage.');
        }

        $transferRequest->load([
            'transferrerProject',
            'receiverProject',
            'requestedBy',
            'items.item',
            'items.outgoingItem.transaction',
            'items.directDeliveryItem.directDelivery'
        ]);

        // Add reference information to each item and collect source references
        $sourceReferences = collect();

        foreach ($transferRequest->items as $item) {
            // Get available quantity for this item in source project
            $projectInventory = \App\Models\Warehouse\ProjectInventory::where([
                'project_id' => $transferRequest->transferrer_project_id,
                'item_id' => $item->item_id
            ])->first();

            $item->available_quantity = $projectInventory ? $projectInventory->quantity_available : 0;

            // Calculate quantity returned to warehouse from this transfer item
            $directReturns = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                $query->where('operation_type', 'site_return')
                      ->where('status', 'completed');
            })
            ->where('material_transfer_item_id', $item->id)
            ->sum('quantity_delivered');

            // Also calculate returns from the source item that this transfer originated from
            $sourceItemReturns = 0;
            if ($item->material_transfer_item_id) {
                // This item came from another Material Transfer - check returns from that source
                $sourceItemReturns = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                    $query->where('operation_type', 'site_return')
                          ->where('status', 'completed');
                })
                ->where('material_transfer_item_id', $item->material_transfer_item_id)
                ->sum('quantity_delivered');
            } elseif ($item->outgoing_item_id) {
                // This item came from a Material Request - check returns from that source
                $sourceItemReturns = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                    $query->where('operation_type', 'site_return')
                          ->where('status', 'completed');
                })
                ->where('outgoing_item_id', $item->outgoing_item_id)
                ->sum('quantity_delivered');
            } elseif ($item->direct_delivery_item_id) {
                // This item came from a Direct Delivery - check returns from that source
                $sourceItemReturns = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                    $query->where('operation_type', 'site_return')
                          ->where('status', 'completed');
                })
                ->where('direct_delivery_item_id', $item->direct_delivery_item_id)
                ->sum('quantity_delivered');
            }

            // Show full source returns - not proportional
            // When materials are returned from the source, it affects all subsequent transfers from that source
            $item->returned_to_warehouse = $directReturns + $sourceItemReturns;

            // Calculate remaining quantity available from the source reference
            $item->remaining_from_source = 0;
            if ($item->material_transfer_item_id) {
                // Get the source Material Transfer item
                $sourceItem = \App\Models\Warehouse\MaterialTransferRequestItem::find($item->material_transfer_item_id);
                if ($sourceItem) {
                    $sourceTotal = $sourceItem->quantity_approved ?? 0;

                    // Calculate total already transferred from this source (including current transfer)
                    $totalTransferredFromSource = \App\Models\Warehouse\MaterialTransferRequestItem::where('material_transfer_item_id', $item->material_transfer_item_id)
                        ->whereHas('transferRequest', function($query) {
                            $query->whereIn('status', ['approved', 'partially_approved']);
                        })
                        ->sum('quantity_approved');

                    // Calculate total returned from the source
                    $totalReturnedFromSource = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                        $query->where('operation_type', 'site_return')
                              ->where('status', 'completed');
                    })
                    ->where('material_transfer_item_id', $item->material_transfer_item_id)
                    ->sum('quantity_delivered');

                    // Remaining = Source total - transferred - returned
                    $item->remaining_from_source = max(0, $sourceTotal - $totalTransferredFromSource - $totalReturnedFromSource);
                }
            } elseif ($item->outgoing_item_id) {
                // Calculate remaining from Material Request source
                $sourceItem = \App\Models\Warehouse\OutgoingItem::find($item->outgoing_item_id);
                if ($sourceItem) {
                    $sourceTotal = $sourceItem->quantity_released ?? 0;
                    $totalTransferred = \App\Models\Warehouse\MaterialTransferRequestItem::where('outgoing_item_id', $item->outgoing_item_id)
                        ->whereHas('transferRequest', function($query) {
                            $query->whereIn('status', ['approved', 'partially_approved']);
                        })
                        ->sum('quantity_approved');
                    $totalReturned = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                        $query->where('operation_type', 'site_return')->where('status', 'completed');
                    })->where('outgoing_item_id', $item->outgoing_item_id)->sum('quantity_delivered');

                    $item->remaining_from_source = max(0, $sourceTotal - $totalTransferred - $totalReturned);
                }
            } elseif ($item->direct_delivery_item_id) {
                // Calculate remaining from Direct Delivery source
                $sourceItem = \App\Models\DirectDeliveryItem::find($item->direct_delivery_item_id);
                if ($sourceItem) {
                    $sourceTotal = $sourceItem->delivered_quantity ?? 0;
                    $totalTransferred = \App\Models\Warehouse\MaterialTransferRequestItem::where('direct_delivery_item_id', $item->direct_delivery_item_id)
                        ->whereHas('transferRequest', function($query) {
                            $query->whereIn('status', ['approved', 'partially_approved']);
                        })
                        ->sum('quantity_approved');
                    $totalReturned = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                        $query->where('operation_type', 'site_return')->where('status', 'completed');
                    })->where('direct_delivery_item_id', $item->direct_delivery_item_id)->sum('quantity_delivered');

                    $item->remaining_from_source = max(0, $sourceTotal - $totalTransferred - $totalReturned);
                }
            }
            // Check if the item has reference relationships loaded
            try {
                if ($item->outgoing_item_id && $item->outgoingItem) {
                    $item->reference_type = 'Material Request';

                    $item->reference_number = $item->outgoingItem->transaction->material_request_number ?? 'N/A';
                    $item->reference_date = $item->outgoingItem->transaction->transaction_date ?? null;

                    // Collect unique source reference
                    $sourceReferences->push([
                        'type' => 'Material Request',
                        'number' => $item->reference_number,
                        'date' => $item->reference_date
                    ]);
                } elseif ($item->direct_delivery_item_id && $item->directDeliveryItem) {
                    $item->reference_type = 'Direct Delivery';
                    $item->reference_number = $item->directDeliveryItem->directDelivery->delivery_number ?? 'N/A';
                    $item->reference_date = $item->directDeliveryItem->directDelivery->delivery_date ?? null;

                    // Collect unique source reference
                    $sourceReferences->push([
                        'type' => 'Direct Delivery',
                        'number' => $item->reference_number,
                        'date' => $item->reference_date
                    ]);
                } else {
                    // For existing data without reference fields, show general transfer
                    $item->reference_type = 'General Transfer';
                    $item->reference_number = $transferRequest->transfer_request_number;
                    $item->reference_date = $transferRequest->request_date;

                    // Note: This is legacy data without proper reference linking
                    // New transfers will have proper Material Request or Direct Delivery references
                }
            } catch (\Exception $e) {
                // Fallback for items without proper relationships
                $item->reference_type = 'General Transfer';
                $item->reference_number = $transferRequest->transfer_request_number;
                $item->reference_date = $transferRequest->request_date;
            }
        }

        // Get unique source references
        $uniqueSourceReferences = $sourceReferences->unique(function ($ref) {
            return $ref['type'] . '-' . $ref['number'];
        });

        return view('warehouse.transfer-requests.approve', compact('transferRequest', 'uniqueSourceReferences'));
    }

    /**
     * Approve transfer request by transferrer project.
     */
    public function approveByTransferrer(Request $request, MaterialTransferRequest $transferRequest)
    {
        if (!$transferRequest->canBeApprovedByTransferrer()) {
            return redirect()->back()
                ->with('error', 'Transfer request cannot be approved at this stage.');
        }

        $validated = $request->validate([
            'approval_notes' => 'nullable|string',
            'item_approvals' => 'required|array',
            'item_approvals.*.quantity_approved' => 'required|numeric|min:0'
        ]);

        DB::transaction(function () use ($transferRequest, $validated) {
            // Update item approvals and handle inventory movements
            $allFullyApproved = true;
            $anyPartiallyApproved = false;

            foreach ($validated['item_approvals'] as $itemId => $approval) {
                $item = $transferRequest->items()->where('item_id', $itemId)->first();
                if ($item) {
                    $quantityApproved = $approval['quantity_approved'];

                    // Update item approval (add to existing approval)
                    $newTotalApproved = ($item->quantity_approved ?? 0) + $quantityApproved;
                    $item->update([
                        'quantity_approved' => $newTotalApproved,
                        'approval_status' => $newTotalApproved == 0 ? 'rejected' :
                                          ($newTotalApproved < $item->quantity_requested ? 'partial' : 'approved')
                    ]);

                    // Handle inventory movements if quantity approved > 0
                    if ($quantityApproved > 0) {
                        $this->processInventoryTransfer($transferRequest, $item, $quantityApproved);
                    }

                    if ($quantityApproved < $item->quantity_requested) {
                        $allFullyApproved = false;
                        if ($quantityApproved > 0) {
                            $anyPartiallyApproved = true;
                        }
                    }
                }
            }

            // Determine overall approval status
            if ($allFullyApproved) {
                $transferRequest->approveByTransferrer(Auth::id(), $validated['approval_notes']);
            } elseif ($anyPartiallyApproved) {
                $transferRequest->partiallyApproveByTransferrer(Auth::id(), $validated['approval_notes']);
            } else {
                return redirect()->back()->with('error', 'At least one item must have approved quantity > 0');
            }
        });

        return redirect()->back()
            ->with('success', 'Transfer request dispatched by transferrer project.');
    }

    /**
     * Process inventory transfer between projects
     */
    private function processInventoryTransfer(MaterialTransferRequest $transferRequest, $transferItem, $quantityApproved)
    {
        // Find or create project inventory for transferrer (source) project
        $sourceProjectInventory = ProjectInventory::firstOrCreate([
            'project_id' => $transferRequest->transferrer_project_id,
            'item_id' => $transferItem->item_id
        ], [
            'quantity_available' => 0,
            'allocated_quantity' => 0,
            'unit_price' => $transferItem->item->unit_cost ?? 0,
            'total_value' => 0
        ]);

        // Find or create project inventory for receiver (destination) project
        $destProjectInventory = ProjectInventory::firstOrCreate([
            'project_id' => $transferRequest->receiver_project_id,
            'item_id' => $transferItem->item_id
        ], [
            'quantity_available' => 0,
            'allocated_quantity' => 0,
            'unit_price' => $transferItem->item->unit_cost ?? 0,
            'total_value' => 0
        ]);

        // Store quantities before transfer for stock movement tracking
        $sourceQuantityBefore = $sourceProjectInventory->quantity_available;
        $destQuantityBefore = $destProjectInventory->quantity_available;

        // Validate sufficient quantity available in source project
        if ($sourceProjectInventory->quantity_available < $quantityApproved) {
            // Cap the quantity to what's available
            $actualQuantityTransferred = $sourceProjectInventory->quantity_available;

            // Update the transfer request item with the adjusted quantity
            $transferItem->update([
                'quantity_approved' => $actualQuantityTransferred,
                'approval_status' => $actualQuantityTransferred > 0 ? 'partially_approved' : 'not_approved'
            ]);

            $quantityApproved = $actualQuantityTransferred;

            // If no quantity available, skip this item
            if ($quantityApproved <= 0) {
                return;
            }
        }

        // Update source project inventory (deduct quantity)
        $sourceProjectInventory->updateQuantity($quantityApproved, 'subtract');

        // Update destination project inventory (add quantity)
        $destProjectInventory->updateQuantity($quantityApproved, 'add');

        // Create stock movement records for tracking
        StockMovement::create([
            'item_id' => $transferItem->item_id,
            'movement_type' => 'transfer_out',
            'reference_type' => MaterialTransferRequest::class,
            'reference_id' => $transferRequest->id,
            'quantity_before' => $sourceQuantityBefore,
            'quantity_moved' => $quantityApproved,
            'quantity_after' => $sourceProjectInventory->quantity_available,
            'division_id' => $transferRequest->transferrerProject->division_id ?? null,
            'user_id' => auth()->id(),
            'notes' => "Transfer out to {$transferRequest->receiverProject->project_name}"
        ]);

        StockMovement::create([
            'item_id' => $transferItem->item_id,
            'movement_type' => 'transfer_in',
            'reference_type' => MaterialTransferRequest::class,
            'reference_id' => $transferRequest->id,
            'quantity_before' => $destQuantityBefore,
            'quantity_moved' => $quantityApproved,
            'quantity_after' => $destProjectInventory->quantity_available,
            'division_id' => $transferRequest->receiverProject->division_id ?? null,
            'user_id' => auth()->id(),
            'notes' => "Transfer in from {$transferRequest->transferrerProject->project_name}"
        ]);

        // Update reference tallies if applicable
        $this->updateReferenceTallies($transferItem, $quantityApproved);
    }

    /**
     * Update reference tallies for material requests or direct deliveries
     */
    private function updateReferenceTallies($transferItem, $quantityApproved)
    {
        // If transfer item has reference to a material request (outgoing item)
        if ($transferItem->outgoing_item_id && $transferItem->outgoingItem) {
            $outgoingItem = $transferItem->outgoingItem;

            // Update quantity transferred in the outgoing item
            $outgoingItem->increment('quantity_transferred', $quantityApproved);

            // Update status if fully transferred
            if ($outgoingItem->quantity_transferred >= $outgoingItem->quantity_approved) {
                $outgoingItem->update(['status' => 'fully_transferred']);
            } else {
                $outgoingItem->update(['status' => 'partially_transferred']);
            }
        }

        // If transfer item has reference to a direct delivery
        if ($transferItem->direct_delivery_item_id && $transferItem->directDeliveryItem) {
            $directDeliveryItem = $transferItem->directDeliveryItem;

            // Update quantity transferred in the direct delivery item
            $directDeliveryItem->increment('quantity_transferred', $quantityApproved);

            // Update status if fully transferred
            $totalQuantity = $directDeliveryItem->received_quantity > 0
                ? $directDeliveryItem->received_quantity
                : $directDeliveryItem->delivered_quantity;

            if ($directDeliveryItem->quantity_transferred >= $totalQuantity) {
                $directDeliveryItem->update(['transfer_status' => 'fully_transferred']);
            } else {
                $directDeliveryItem->update(['transfer_status' => 'partially_transferred']);
            }
        }
    }


    /**
     * Reject transfer request.
     */
    public function reject(Request $request, MaterialTransferRequest $transferRequest)
    {
        if (!$transferRequest->isPending()) {
            return redirect()->back()
                ->with('error', 'Transfer request cannot be rejected at this stage.');
        }

        $validated = $request->validate([
            'rejection_reason' => 'required|string|max:500'
        ]);

        $transferRequest->reject(Auth::id(), $validated['rejection_reason']);

        return redirect()->back()
            ->with('success', 'Transfer request rejected.');
    }

    /**
     * Cancel transfer request.
     */
    public function cancel(Request $request, MaterialTransferRequest $transferRequest)
    {
        if (!in_array($transferRequest->status, ['draft', 'pending_transferrer_approval', 'pending_receiver_approval', 'partially_approved'])) {
            return redirect()->back()
                ->with('error', 'Cannot cancel approved or completed transfer request.');
        }

        // Check if this is a finalization of partial approval
        if ($request->has('finalize_partial_approval') && $request->finalize_partial_approval == '1') {
            return $this->finalizePartialApproval($transferRequest);
        }

        // Check if there are any partially transferred items
        $hasPartiallyTransferred = $transferRequest->items()
            ->where('approval_status', 'partial')
            ->exists();

        if ($hasPartiallyTransferred) {
            return redirect()->back()
                ->with('error', 'Cannot cancel transfer request with partially transferred items. Use "Dispatch Transfer" to finalize the transferred quantities.');
        }

        $transferRequest->update([
            'status' => 'cancelled',
            'rejected_by' => Auth::id(),
            'rejected_at' => now(),
            'rejection_reason' => 'Cancelled from approval page'
        ]);

        return redirect()->route('warehouse.transfer-requests.index')
            ->with('success', 'Transfer request cancelled.');
    }

    /**
     * Finalize partial transfer by adjusting requested quantities to match transferred quantities.
     */
    private function finalizePartialApproval(MaterialTransferRequest $transferRequest)
    {
        DB::transaction(function () use ($transferRequest) {
            // Get all items with partial transfers
            $partiallyTransferredItems = $transferRequest->items()
                ->where('approval_status', 'partial')
                ->get();

            foreach ($partiallyTransferredItems as $item) {
                // Adjust the requested quantity to match the transferred quantity
                $item->update([
                    'quantity_requested' => $item->quantity_approved,
                    'approval_status' => 'approved'
                ]);
            }

            // Update the transfer request status to transferred
            $transferRequest->update([
                'status' => 'approved',
                'approved_by' => Auth::id(),
                'approved_at' => now(),
                'approval_notes' => 'Finalized partial transfer - requested quantities adjusted to match transferred quantities'
            ]);
        });

        return redirect()->route('warehouse.transfer-requests.index')
            ->with('success', 'Transfer request completed with adjusted quantities. Requested quantities have been updated to match transferred amounts.');
    }

    /**
     * Get project inventory via AJAX.
     */
    public function getProjectInventory($projectId)
    {
        $inventory = ProjectInventory::where('project_id', $projectId)
            ->with('item')
            ->where('quantity_available', '>', 0)
            ->get()
            ->map(function ($item) {
                return [
                    'item_id' => $item->item_id,
                    'item_name' => $item->item->item_name,
                    'quantity_available' => $item->quantity_available,
                    'available_for_transfer' => $item->available_for_transfer,
                    'unit_price' => $item->unit_price
                ];
            });

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

    /**
     * Get direct delivery items for material transfer.
     */
    public function getDirectDeliveryItems($directDeliveryId)
    {
        try {
            $directDelivery = \App\Models\DirectDelivery::with([
                'project',
                'supplier',
                'items.item'
            ])->findOrFail($directDeliveryId);

            // Allow multiple statuses for transfers - expand the allowed statuses
            if (!in_array($directDelivery->status, ['pending', 'partially_delivered', 'delivered', 'received'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Direct delivery must have items available to be used for transfer.'
                ]);
            }

            $data = [
                'id' => $directDelivery->id,
                'delivery_number' => $directDelivery->delivery_number,
                'delivery_date' => $directDelivery->delivery_date->format('M d, Y'),
                'project_id' => $directDelivery->project_id,
                'project_name' => $directDelivery->project ? $directDelivery->project->project_name : 'Unknown Project',
                'supplier_name' => $directDelivery->supplier ? $directDelivery->supplier->name : 'No Supplier',
                'status' => ucfirst(str_replace('_', ' ', $directDelivery->status)),
                'items' => $directDelivery->items->map(function($item) use ($directDelivery) {
                    // For transfers, we use delivered_quantity or received_quantity
                    // Also try ordered_quantity as fallback if no delivered/received quantity
                    $deliveredQuantity = $item->received_quantity > 0 ? $item->received_quantity :
                                       ($item->delivered_quantity > 0 ? $item->delivered_quantity :
                                       ($item->ordered_quantity > 0 ? $item->ordered_quantity : 0));

                    // Calculate already returned quantity
                    $returnedQuantity = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                        $query->where('operation_type', 'site_return')
                              ->where('status', 'completed');
                    })
                    ->where('direct_delivery_item_id', $item->id)
                    ->sum('quantity_delivered');

                    // Calculate quantity already transferred to other projects
                    $transferredQuantity = \App\Models\Warehouse\MaterialTransferRequestItem::whereHas('transferRequest', function($query) {
                        $query->whereIn('status', ['approved', 'partially_approved']);
                    })
                    ->where('direct_delivery_item_id', $item->id)
                    ->sum('quantity_approved');

                    // Get actual project inventory available quantity for this item
                    $projectInventory = \App\Models\Warehouse\ProjectInventory::where('project_id', $directDelivery->project_id)
                        ->where('item_id', $item->item_id)
                        ->first();

                    $projectAvailableQuantity = $projectInventory ? $projectInventory->available_for_transfer : 0;

                    // Calculate net delivered quantity available for transfer
                    $netDeliveredAvailable = max(0, $deliveredQuantity - $returnedQuantity - $transferredQuantity);

                    // Debug logging
                    \Log::info("Direct Delivery Item Debug", [
                        'delivery_id' => $directDelivery->id,
                        'item_id' => $item->item_id,
                        'ordered_quantity' => $item->ordered_quantity,
                        'delivered_quantity_field' => $item->delivered_quantity,
                        'received_quantity_field' => $item->received_quantity,
                        'calculated_delivered_quantity' => $deliveredQuantity,
                        'returned_quantity' => $returnedQuantity,
                        'transferred_quantity' => $transferredQuantity,
                        'net_delivered_available' => $netDeliveredAvailable
                    ]);

                    return [
                        'id' => $item->id,
                        'item_id' => $item->item_id,
                        'item_code' => $item->item ? $item->item->item_code : 'N/A',
                        'item_description' => $item->item ? $item->item->item_description : 'Unknown Item',
                        'item_name' => $item->item ? $item->item->item_description : 'Unknown Item',
                        'unit_of_measure' => $item->item ? $item->item->unit_of_measure : 'PCS',
                        'delivered_quantity' => $deliveredQuantity,
                        'returned_quantity' => $returnedQuantity,
                        'transferred_quantity' => $transferredQuantity,
                        'net_available_quantity' => $netDeliveredAvailable,
                        'project_available_quantity' => $projectAvailableQuantity,
                        'unit_price' => $item->unit_price ?? 0,
                        'unit_price_aed' => $item->unit_price ?? 0, // Assuming AED
                        'batch_number' => $item->batch_number,
                        'expiry_date' => $item->expiry_date ? $item->expiry_date->format('M d, Y') : null,
                        'manufacturer' => $item->manufacturer,
                    ];
                })->filter(function($item) {
                    // For debugging: include all items that have any quantity > 0
                    return ($item['delivered_quantity'] > 0) ||
                           ($item['net_available_quantity'] > 0) ||
                           true; // Temporarily show ALL items for debugging
                })->values()
            ];

            return response()->json([
                'success' => true,
                'items' => $data['items'], // Extract items to match expected format
                'direct_delivery' => [
                    'id' => $data['id'],
                    'delivery_number' => $data['delivery_number'],
                    'delivery_date' => $data['delivery_date'],
                    'project_name' => $data['project_name'],
                    'supplier_name' => $data['supplier_name'],
                    'status' => $data['status']
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Error getting direct delivery items for transfer: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Error loading direct delivery items: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get combined references (Material Request, Direct Delivery, Material Transfer) for a project
     */
    public function getCombinedReferencesByProject($projectId)
    {
        try {
            $references = collect();

            // Get Material Requests (Outgoing Transactions) that are successful
            $materialRequests = \App\Models\Warehouse\OutgoingTransaction::with(['requester'])
                ->where('project_id', $projectId)
                ->where('status', 'successful')
                ->orderByDesc('transaction_date')
                ->get()
                ->map(function($mr) {
                    $referenceNumber = $mr->material_request_number ?? 'AUTO-' . str_pad($mr->id, 6, '0', STR_PAD_LEFT);
                    $date = $mr->transaction_date ? $mr->transaction_date->format('M d, Y') : 'N/A';
                    $time = $mr->transaction_date ? $mr->transaction_date->format('h:i A') : '';
                    $requester = $mr->requester ? $mr->requester->name : 'N/A';

                    // If reference number is common (like INV), add ID to make it unique
                    $displayRef = $referenceNumber;
                    if (in_array(strtoupper($referenceNumber), ['INV', 'INVENTORY', 'N/A'])) {
                        $displayRef = "{$referenceNumber}-{$mr->id}";
                    }

                    return [
                        'id' => 'MR_' . $mr->id,
                        'text' => "MR#{$mr->id}: {$displayRef} - {$requester} ({$date} {$time})",
                        'type' => 'material_request',
                        'reference_id' => $mr->id,
                        'date' => $mr->transaction_date ? $mr->transaction_date->format('Y-m-d') : null,
                    ];
                });

            // Get Direct Deliveries that have been at least partially delivered
            // Include pending deliveries that have items
            $directDeliveries = \App\Models\DirectDelivery::with(['supplier', 'items'])
                ->where('project_id', $projectId)
                ->where(function($query) {
                    $query->whereIn('status', ['pending', 'partially_delivered', 'delivered', 'received'])
                          ->orWhereHas('items', function($q) {
                              $q->where(function($sq) {
                                  $sq->where('delivered_quantity', '>', 0)
                                     ->orWhere('received_quantity', '>', 0);
                              });
                          });
                })
                ->orderByDesc('delivery_date')
                ->get()
                ->filter(function($dd) {
                    // Only include deliveries that have items
                    return $dd->items && $dd->items->count() > 0;
                })
                ->map(function($dd) {
                    $referenceNumber = $dd->delivery_number ?? $dd->reference_number ?? 'AUTO-' . str_pad($dd->id, 6, '0', STR_PAD_LEFT);
                    $date = $dd->delivery_date ? $dd->delivery_date->format('M d, Y') : 'N/A';
                    $time = $dd->delivery_date ? $dd->delivery_date->format('h:i A') : '';
                    $supplier = $dd->supplier ? $dd->supplier->name : 'Direct Supply';

                    // Make reference unique if it's a common value
                    $displayRef = $referenceNumber;
                    if (in_array(strtoupper($referenceNumber), ['DD', 'DELIVERY', 'N/A']) || strlen($referenceNumber) <= 3) {
                        $displayRef = "{$referenceNumber}-{$dd->id}";
                    }

                    return [
                        'id' => 'DD_' . $dd->id,
                        'text' => "DD#{$dd->id}: {$displayRef} - {$supplier} ({$date} {$time})",
                        'type' => 'direct_delivery',
                        'reference_id' => $dd->id,
                        'date' => $dd->delivery_date ? $dd->delivery_date->format('Y-m-d') : null,
                    ];
                });

            // Get Material Transfers where this project is the receiver and transfers are approved/partially approved
            $materialTransfers = \App\Models\Warehouse\MaterialTransferRequest::with(['transferrerProject', 'requestedBy'])
                ->where('receiver_project_id', $projectId)
                ->whereIn('status', ['approved', 'partially_approved'])
                ->orderByDesc('request_date')
                ->get()
                ->map(function($mt) {
                    $referenceNumber = $mt->transfer_request_number ?? 'AUTO-' . str_pad($mt->id, 6, '0', STR_PAD_LEFT);
                    $date = $mt->request_date ? $mt->request_date->format('M d, Y') : 'N/A';
                    $time = $mt->request_date ? $mt->request_date->format('h:i A') : '';
                    $fromProject = $mt->transferrerProject ? $mt->transferrerProject->project_name : 'Unknown Project';

                    // Make reference unique if needed
                    $displayRef = $referenceNumber;
                    if (in_array(strtoupper($referenceNumber), ['MT', 'TRANSFER', 'N/A']) || strlen($referenceNumber) <= 3) {
                        $displayRef = "{$referenceNumber}-{$mt->id}";
                    }

                    return [
                        'id' => 'MT_' . $mt->id,
                        'text' => "MT#{$mt->id}: {$displayRef} - from {$fromProject} ({$date} {$time})",
                        'type' => 'material_transfer',
                        'reference_id' => $mt->id,
                        'date' => $mt->request_date ? $mt->request_date->format('Y-m-d') : null,
                    ];
                });

            // Combine all references
            $references = $materialRequests->concat($directDeliveries)->concat($materialTransfers);

            // Sort by date in descending order
            $references = $references->sortByDesc(function($item) {
                return $item['date'] ?? '1970-01-01';
            })->values();

            // Log for debugging
            \Log::info('Combined References for Project ' . $projectId, [
                'material_requests_count' => $materialRequests->count(),
                'direct_deliveries_count' => $directDeliveries->count(),
                'material_transfers_count' => $materialTransfers->count(),
                'total_references' => $references->count()
            ]);

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

        } catch (\Exception $e) {
            \Log::error('Error getting combined references for project: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Error loading references: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get Material Request (Outgoing Transaction) items for transfer
     */
    public function getMaterialRequestItems($materialRequestId)
    {
        try {
            $materialRequest = \App\Models\Warehouse\OutgoingTransaction::with([
                'project',
                'requester',
                'items.item'
            ])->findOrFail($materialRequestId);

            // Only allow successful material requests for transfers
            if ($materialRequest->status !== 'successful') {
                return response()->json([
                    'success' => false,
                    'message' => 'Material request must be successful to be available for transfer.'
                ]);
            }

            $items = $materialRequest->items->map(function($item) {
                $remainingQty = $item->quantity_released - $item->quantity_returned - $item->quantity_transferred;

                return [
                    'item_id' => $item->item_id,
                    'item_name' => $item->item->item_name,
                    'item_code' => $item->item->item_code,
                    'unit' => $item->item->unit,
                    'quantity_requested' => $item->quantity_requested,
                    'quantity_released' => $item->quantity_released,
                    'quantity_returned' => $item->quantity_returned,
                    'quantity_transferred' => $item->quantity_transferred,
                    'quantity_remaining' => $remainingQty,
                    'quantity_balance' => $remainingQty, // alias for compatibility
                    'unit_cost' => $item->unit_cost,
                    'available_for_transfer' => $remainingQty > 0
                ];
            })->filter(function($item) {
                return $item['quantity_remaining'] > 0; // Only show items with remaining quantity
            });

            return response()->json([
                'success' => true,
                'items' => $items,
                'material_request' => [
                    'id' => $materialRequest->id,
                    'material_request_number' => $materialRequest->material_request_number,
                    'request_date' => $materialRequest->transaction_date->format('M d, Y'),
                    'requester' => $materialRequest->requester ? $materialRequest->requester->name : 'N/A',
                    'project' => $materialRequest->project ? $materialRequest->project->project_name : 'N/A'
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Error getting material request items: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Error loading material request items: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get Material Transfer items for transfer request
     */
    public function getMaterialTransfer($transferId)
    {
        try {
            $materialTransfer = MaterialTransferRequest::with([
                'transferrerProject',
                'receiverProject',
                'items.item'
            ])->findOrFail($transferId);

            // Only allow approved/partially approved transfers
            if (!in_array($materialTransfer->status, ['approved', 'partially_approved'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Material transfer must be approved to be available for transfer request.'
                ]);
            }

            $data = [
                'id' => $materialTransfer->id,
                'transfer_request_number' => $materialTransfer->transfer_request_number,
                'request_date' => $materialTransfer->request_date->format('M d, Y'),
                'transferrer_project_id' => $materialTransfer->transferrer_project_id,
                'transferrer_project_name' => $materialTransfer->transferrerProject ? $materialTransfer->transferrerProject->project_name : 'Unknown Project',
                'receiver_project_id' => $materialTransfer->receiver_project_id,
                'receiver_project_name' => $materialTransfer->receiverProject ? $materialTransfer->receiverProject->project_name : 'Unknown Project',
                'status' => ucwords(str_replace('_', ' ', $materialTransfer->status)),
                'priority' => ucfirst($materialTransfer->priority),
                'items' => $materialTransfer->items->map(function($item) use ($materialTransfer) {
                    // For material transfers, we use approved quantity
                    $approvedQuantity = $item->quantity_approved ?? 0;

                    // Skip items that weren't approved
                    if ($approvedQuantity <= 0) {
                        return null;
                    }

                    // Calculate already used quantity from subsequent transfers
                    $usedQuantity = MaterialTransferRequestItem::whereHas('transferRequest', function($query) {
                        $query->whereIn('status', ['approved', 'partially_approved']);
                    })->where('material_transfer_item_id', $item->id)->sum('quantity_approved');

                    // Calculate quantity returned to warehouse from this material transfer item
                    $returnedQuantity = \App\Models\Warehouse\IncomingOperationItem::whereHas('operation', function($query) {
                        $query->where('operation_type', 'site_return')
                              ->where('status', 'completed');
                    })->where('material_transfer_item_id', $item->id)->sum('quantity_delivered');

                    // Get project inventory for this item from the receiver project (where materials now are)
                    $projectInventory = \App\Models\Warehouse\ProjectInventory::where('project_id', $materialTransfer->receiver_project_id)
                        ->where('item_id', $item->item_id)
                        ->first();

                    $projectAvailableQuantity = $projectInventory ? $projectInventory->available_for_transfer : 0;

                    // Use the approved quantity as the base, subtract transfers and returns
                    $remainingTransferable = max(0, $approvedQuantity - $usedQuantity - $returnedQuantity);

                    // Also consider actual project inventory
                    $actualAvailable = min($remainingTransferable, $projectAvailableQuantity);

                    return [
                        'id' => $item->id,
                        'item_id' => $item->item_id,
                        'item_code' => $item->item ? $item->item->item_code : 'N/A',
                        'item_description' => $item->item ? $item->item->item_description : 'Unknown Item',
                        'item_name' => $item->item ? $item->item->item_description : 'Unknown Item',
                        'unit_of_measure' => $item->item ? $item->item->unit_of_measure : 'PCS',
                        'quantity_requested' => $item->quantity_requested,
                        'quantity_approved' => $approvedQuantity,
                        'previously_transferred' => $usedQuantity,
                        'returned_quantity' => $returnedQuantity,
                        'remaining_transferable' => $actualAvailable,
                        'project_available_quantity' => $projectAvailableQuantity,
                        'estimated_unit_price' => $item->estimated_unit_price ?? 0,
                        'approval_status' => $item->approval_status,
                    ];
                })->filter(function($item) {
                    // Only include items that are not null and have remaining transferable quantity
                    return $item !== null && $item['remaining_transferable'] > 0;
                })->values()
            ];

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

        } catch (\Exception $e) {
            \Log::error('Error getting material transfer for transfer request: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Error loading material transfer details: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Print transfer request document.
     */
    public function print(MaterialTransferRequest $transferRequest)
    {
        $transferRequest->load([
            'transferrerProject',
            'receiverProject',
            'requestedBy',
            'items.item'
        ]);

        // Create a delivery note object that matches our template structure
        $deliveryNote = (object) [
            'outgoingTransaction' => (object) [
                'mr_number' => $transferRequest->transfer_request_number,
            ],
            'delivered_to' => $transferRequest->receiverProject ?
                $transferRequest->receiverProject->project_name : 'N/A',
            'generated_date' => $transferRequest->request_date,
            'project' => $transferRequest->transferrerProject ? (object) [
                'project_number' => $transferRequest->transferrerProject->project_number ?:
                    $transferRequest->transferrerProject->project_name
            ] : null,
            'items' => $transferRequest->items->map(function($item) {
                return (object) [
                    'item' => (object) [
                        'item_name' => $item->item->item_description,
                        'unit' => $item->unit_of_measure ?: 'pcs'
                    ],
                    'quantity_released' => $item->quantity_approved ?: $item->quantity_requested,
                    'remarks' => $item->notes ?: ''
                ];
            })
        ];

        return view('warehouse.delivery-notes.template', compact('deliveryNote'));
    }
}