<?php

namespace App\Helpers;

use App\Models\Warehouse\MaterialSiteTransferItem;
use App\Models\Warehouse\MaterialSiteTransferItemAllocation;
use App\Models\Warehouse\OutgoingItem;
use App\Models\Warehouse\IncomingOperationItem;
use App\Models\Warehouse\OutgoingFulfillment;
use App\Models\DirectDeliveryItem;

class AllocationDivisionResolver
{
    /**
     * Resolve division_id and is_foc from an allocation record.
     * Handles recursive chains for site_transfer_item and material_transfer_item source types.
     *
     * @param MaterialSiteTransferItemAllocation $allocation
     * @param int $maxDepth Safety limit for recursion
     * @return array ['division_id' => int|null, 'is_foc' => bool]
     */
    public static function resolve(MaterialSiteTransferItemAllocation $allocation, int $maxDepth = 10): array
    {
        if ($maxDepth <= 0) {
            return ['division_id' => null, 'is_foc' => false];
        }

        switch ($allocation->source_type) {
            case 'outgoing_item':
                $outgoingItem = OutgoingItem::find($allocation->source_id);
                if ($outgoingItem) {
                    return [
                        'division_id' => $outgoingItem->division_id,
                        'is_foc' => false,
                    ];
                }
                break;

            case 'direct_delivery_item':
                $ddItem = DirectDeliveryItem::find($allocation->source_id);
                if ($ddItem && $ddItem->directDelivery) {
                    return [
                        'division_id' => $ddItem->directDelivery->project_division_id,
                        'is_foc' => false,
                    ];
                }
                break;

            case 'supplier_delivery_item':
                $sdItem = IncomingOperationItem::find($allocation->source_id);
                if ($sdItem && $sdItem->operation) {
                    return [
                        'division_id' => $sdItem->operation->division_id,
                        'is_foc' => ($sdItem->operation->delivery_type === 'foc'),
                    ];
                }
                break;

            case 'foc_transfer_item':
                $divisionId = null;
                $fulfillment = OutgoingFulfillment::find($allocation->source_id);
                if ($fulfillment) {
                    // Try foc_inventory_id first (most direct link)
                    if ($fulfillment->foc_inventory_id) {
                        $focInventory = \App\Models\FocInventory::find($fulfillment->foc_inventory_id);
                        if ($focInventory) {
                            $divisionId = $focInventory->division_id;
                        }
                    }
                    // Fallback: trace through FocInventoryAdjustment (dispatch record)
                    if (!$divisionId) {
                        $focAdjustment = \App\Models\FocInventoryAdjustment::with('focInventory')
                            ->where('adjustment_type', 'dispatch')
                            ->where('item_id', $fulfillment->item_id)
                            ->where('reference_type', 'material_issue')
                            ->where('reference_id', $fulfillment->outgoing_transaction_id)
                            ->first();
                        if ($focAdjustment && $focAdjustment->focInventory) {
                            $divisionId = $focAdjustment->focInventory->division_id;
                        }
                    }
                    // Last fallback: OutgoingTransaction's items
                    if (!$divisionId) {
                        $transaction = $fulfillment->outgoingTransaction;
                        if ($transaction) {
                            $outgoingItem = OutgoingItem::where('outgoing_transaction_id', $transaction->id)
                                ->where('item_id', $fulfillment->item_id)
                                ->first();
                            if ($outgoingItem) {
                                $divisionId = $outgoingItem->division_id;
                            }
                        }
                    }
                }
                return [
                    'division_id' => $divisionId,
                    'is_foc' => true,
                ];

            case 'site_transfer_item':
            case 'material_transfer_item':
                $sourceTransferItem = MaterialSiteTransferItem::find($allocation->source_id);
                if ($sourceTransferItem) {
                    $nestedAllocations = MaterialSiteTransferItemAllocation
                        ::where('site_transfer_item_id', $sourceTransferItem->id)
                        ->get();

                    if ($nestedAllocations->count() === 1) {
                        return self::resolve($nestedAllocations->first(), $maxDepth - 1);
                    } elseif ($nestedAllocations->count() > 1) {
                        // Multiple nested allocations - resolve the first one as fallback
                        return self::resolve($nestedAllocations->first(), $maxDepth - 1);
                    }
                }
                break;
        }

        return ['division_id' => null, 'is_foc' => false];
    }
}
