<?php

namespace Modules\Manufacturing\Utils;

use Modules\Manufacturing\Entities\MfgBoxAllocation;

class BoxAllocationUtil
{
    /**
     * Calculate box allocation for a given quantity
     *
     * @param float $total_quantity
     * @param string $unit
     * @param int $business_id
     * @return array
     */
    public static function calculateBoxAllocation($total_quantity, $unit, $business_id)
    {
        // Get active box allocations ordered by capacity (largest first)
        $box_allocations = MfgBoxAllocation::forBusiness($business_id)
            ->active()
            ->where('unit', $unit)
            ->orderBy('capacity', 'desc')
            ->get();

        $allocation_results = [];
        $remaining_quantity = $total_quantity;

        foreach ($box_allocations as $box) {
            $boxes_count = floor($remaining_quantity / $box->capacity);
            if ($boxes_count > 0) {
                $allocation_results[] = [
                    'box_id' => $box->id,
                    'box_name' => $box->name,
                    'box_size' => $box->size,
                    'box_capacity' => $box->capacity,
                    'boxes_count' => $boxes_count,
                    'total_capacity_used' => $boxes_count * $box->capacity,
                ];
                $remaining_quantity -= $boxes_count * $box->capacity;
            }
        }

        return [
            'allocation_results' => $allocation_results,
            'remaining_quantity' => $remaining_quantity,
            'total_quantity' => $total_quantity,
        ];
    }

    /**
     * Get box allocation summary for production
     *
     * @param float $total_quantity
     * @param string $unit
     * @param int $business_id
     * @return string
     */
    public static function getBoxAllocationSummary($total_quantity, $unit, $business_id)
    {
        $allocation = self::calculateBoxAllocation($total_quantity, $unit, $business_id);
        
        if (empty($allocation['allocation_results'])) {
            return "No boxes can be filled with {$total_quantity} {$unit}";
        }

        $summary = "Box Allocation for {$total_quantity} {$unit}:\n";
        foreach ($allocation['allocation_results'] as $result) {
            $summary .= "- {$result['boxes_count']} x {$result['box_name']} ({$result['box_size']})\n";
        }
        
        if ($allocation['remaining_quantity'] > 0) {
            $summary .= "Remaining: {$allocation['remaining_quantity']} {$unit}";
        }

        return $summary;
    }

    /**
     * Get available box sizes for dropdown
     *
     * @param int $business_id
     * @param string $unit
     * @return array
     */
    public static function getBoxSizesForDropdown($business_id, $unit = null)
    {
        $query = MfgBoxAllocation::forBusiness($business_id)->active();
        
        if ($unit) {
            $query->where('unit', $unit);
        }
        
        return $query->orderBy('capacity', 'desc')
            ->get()
            ->mapWithKeys(function ($box) {
                return [$box->id => $box->display_name];
            });
    }

    /**
     * Get box allocation statistics
     *
     * @param int $business_id
     * @return array
     */
    public static function getBoxAllocationStats($business_id)
    {
        $total_boxes = MfgBoxAllocation::forBusiness($business_id)->count();
        $active_boxes = MfgBoxAllocation::forBusiness($business_id)->active()->count();
        $predefined_boxes = MfgBoxAllocation::forBusiness($business_id)->predefined()->count();
        $custom_boxes = MfgBoxAllocation::forBusiness($business_id)->userCreated()->count();

        return [
            'total_boxes' => $total_boxes,
            'active_boxes' => $active_boxes,
            'predefined_boxes' => $predefined_boxes,
            'custom_boxes' => $custom_boxes,
        ];
    }
}
