package util

import (
	"apskel-pos-be/internal/entities"
	"apskel-pos-be/internal/models"
	"fmt"
	"time"

	"github.com/google/uuid"
)

// CalculateWasteQuantities calculates gross, net, and waste quantities for product ingredients
func CalculateWasteQuantities(productIngredients []*entities.ProductIngredient, quantity float64) ([]*models.CreateOrderIngredientTransactionRequest, error) {
	if len(productIngredients) == 0 {
		return []*models.CreateOrderIngredientTransactionRequest{}, nil
	}

	transactions := make([]*models.CreateOrderIngredientTransactionRequest, 0, len(productIngredients))

	for _, pi := range productIngredients {
		// Calculate net quantity (actual quantity needed for the product)
		netQty := pi.Quantity * quantity
		
		// Calculate gross quantity (including waste)
		wasteMultiplier := 1 + (pi.WastePercentage / 100)
		grossQty := netQty * wasteMultiplier
		
		// Calculate waste quantity
		wasteQty := grossQty - netQty

		// Get unit name from ingredient
		unitName := "unit" // default
		if pi.Ingredient != nil && pi.Ingredient.Unit != nil {
			unitName = pi.Ingredient.Unit.Name
		}

		transaction := &models.CreateOrderIngredientTransactionRequest{
			IngredientID: pi.IngredientID,
			GrossQty:     RoundToDecimalPlaces(grossQty, 3),
			NetQty:       RoundToDecimalPlaces(netQty, 3),
			WasteQty:     RoundToDecimalPlaces(wasteQty, 3),
			Unit:         unitName,
		}

		transactions = append(transactions, transaction)
	}

	return transactions, nil
}

// CreateOrderIngredientTransactionsFromProduct creates order ingredient transactions for a product
func CreateOrderIngredientTransactionsFromProduct(
	productID uuid.UUID,
	productVariantID *uuid.UUID,
	orderID uuid.UUID,
	orderItemID *uuid.UUID,
	quantity float64,
	productIngredients []*entities.ProductIngredient,
	organizationID, outletID, createdBy uuid.UUID,
) ([]*models.CreateOrderIngredientTransactionRequest, error) {
	// Calculate waste quantities
	wasteTransactions, err := CalculateWasteQuantities(productIngredients, quantity)
	if err != nil {
		return nil, fmt.Errorf("failed to calculate waste quantities: %w", err)
	}

	// Set common fields for all transactions
	for _, transaction := range wasteTransactions {
		transaction.OrderID = orderID
		transaction.OrderItemID = orderItemID
		transaction.ProductID = productID
		transaction.ProductVariantID = productVariantID
		transaction.TransactionDate = &time.Time{}
		*transaction.TransactionDate = time.Now()
	}

	return wasteTransactions, nil
}

// RoundToDecimalPlaces rounds a float64 to the specified number of decimal places
func RoundToDecimalPlaces(value float64, places int) float64 {
	multiplier := 1.0
	for i := 0; i < places; i++ {
		multiplier *= 10
	}
	return float64(int(value*multiplier+0.5)) / multiplier
}
