package mappers

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

	"github.com/google/uuid"
)

func MapOrderIngredientTransactionEntityToModel(entity *entities.OrderIngredientTransaction) *models.OrderIngredientTransaction {
	if entity == nil {
		return nil
	}

	return &models.OrderIngredientTransaction{
		ID:               entity.ID,
		OrganizationID:   entity.OrganizationID,
		OutletID:         entity.OutletID,
		OrderID:          entity.OrderID,
		OrderItemID:      entity.OrderItemID,
		ProductID:        entity.ProductID,
		ProductVariantID: entity.ProductVariantID,
		IngredientID:     entity.IngredientID,
		GrossQty:         entity.GrossQty,
		NetQty:           entity.NetQty,
		WasteQty:         entity.WasteQty,
		Unit:             entity.Unit,
		TransactionDate:  entity.TransactionDate,
		CreatedBy:        entity.CreatedBy,
		CreatedAt:        entity.CreatedAt,
		UpdatedAt:        entity.UpdatedAt,
		Organization:     nil,
		Outlet:           nil,
		Order:            nil,
		OrderItem:        nil,
		Product:          nil,
		ProductVariant:   nil,
		Ingredient:       nil,
		CreatedByUser:    nil,
	}
}

func MapOrderIngredientTransactionModelToEntity(model *models.OrderIngredientTransaction) *entities.OrderIngredientTransaction {
	if model == nil {
		return nil
	}

	return &entities.OrderIngredientTransaction{
		ID:               model.ID,
		OrganizationID:   model.OrganizationID,
		OutletID:         model.OutletID,
		OrderID:          model.OrderID,
		OrderItemID:      model.OrderItemID,
		ProductID:        model.ProductID,
		ProductVariantID: model.ProductVariantID,
		IngredientID:     model.IngredientID,
		GrossQty:         model.GrossQty,
		NetQty:           model.NetQty,
		WasteQty:         model.WasteQty,
		Unit:             model.Unit,
		TransactionDate:  model.TransactionDate,
		CreatedBy:        model.CreatedBy,
		CreatedAt:        model.CreatedAt,
		UpdatedAt:        model.UpdatedAt,
		Organization:     entities.Organization{},
		Outlet:           nil,
		Order:            entities.Order{},
		OrderItem:        nil,
		Product:          entities.Product{},
		ProductVariant:   nil,
		Ingredient:       entities.Ingredient{},
		CreatedByUser:    entities.User{},
	}
}

func MapOrderIngredientTransactionEntitiesToModels(entities []*entities.OrderIngredientTransaction) []*models.OrderIngredientTransaction {
	if entities == nil {
		return nil
	}

	models := make([]*models.OrderIngredientTransaction, len(entities))
	for i, entity := range entities {
		models[i] = MapOrderIngredientTransactionEntityToModel(entity)
	}

	return models
}

func MapOrderIngredientTransactionModelsToEntities(models []*models.OrderIngredientTransaction) []*entities.OrderIngredientTransaction {
	if models == nil {
		return nil
	}

	entities := make([]*entities.OrderIngredientTransaction, len(models))
	for i, model := range models {
		entities[i] = MapOrderIngredientTransactionModelToEntity(model)
	}

	return entities
}

func MapOrderIngredientTransactionEntityToResponse(entity *entities.OrderIngredientTransaction) *models.OrderIngredientTransactionResponse {
	if entity == nil {
		return nil
	}

	return &models.OrderIngredientTransactionResponse{
		ID:               entity.ID,
		OrganizationID:   entity.OrganizationID,
		OutletID:         entity.OutletID,
		OrderID:          entity.OrderID,
		OrderItemID:      entity.OrderItemID,
		ProductID:        entity.ProductID,
		ProductVariantID: entity.ProductVariantID,
		IngredientID:     entity.IngredientID,
		GrossQty:         entity.GrossQty,
		NetQty:           entity.NetQty,
		WasteQty:         entity.WasteQty,
		Unit:             entity.Unit,
		TransactionDate:  entity.TransactionDate,
		CreatedBy:        entity.CreatedBy,
		CreatedAt:        entity.CreatedAt,
		UpdatedAt:        entity.UpdatedAt,
		Organization:     nil,
		Outlet:           nil,
		Order:            nil,
		OrderItem:        nil,
		Product:          nil,
		ProductVariant:   nil,
		Ingredient:       nil,
		CreatedByUser:    nil,
	}
}

func MapOrderIngredientTransactionEntitiesToResponses(entities []*entities.OrderIngredientTransaction) []*models.OrderIngredientTransactionResponse {
	if entities == nil {
		return nil
	}

	responses := make([]*models.OrderIngredientTransactionResponse, len(entities))
	for i, entity := range entities {
		responses[i] = MapOrderIngredientTransactionEntityToResponse(entity)
	}

	return responses
}

func MapOrderIngredientTransactionSummary(transactions []*entities.OrderIngredientTransaction) []*models.OrderIngredientTransactionSummary {
	if transactions == nil || len(transactions) == 0 {
		return nil
	}

	// Group by ingredient ID
	ingredientMap := make(map[uuid.UUID]*models.OrderIngredientTransactionSummary)

	for _, transaction := range transactions {
		ingredientID := transaction.IngredientID

		if summary, exists := ingredientMap[ingredientID]; exists {
			summary.TotalGrossQty += transaction.GrossQty
			summary.TotalNetQty += transaction.NetQty
			summary.TotalWasteQty += transaction.WasteQty
		} else {
			ingredientMap[ingredientID] = &models.OrderIngredientTransactionSummary{
				IngredientID:   ingredientID,
				IngredientName: transaction.Ingredient.Name,
				TotalGrossQty:  transaction.GrossQty,
				TotalNetQty:    transaction.NetQty,
				TotalWasteQty:  transaction.WasteQty,
				Unit:           transaction.Unit,
			}
		}
	}

	// Convert map to slice and calculate waste percentage
	var summaries []*models.OrderIngredientTransactionSummary
	for _, summary := range ingredientMap {
		if summary.TotalGrossQty > 0 {
			summary.WastePercentage = (summary.TotalWasteQty / summary.TotalGrossQty) * 100
		}
		summaries = append(summaries, summary)
	}

	return summaries
}
