package mappers

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

func InventoryMovementEntityToModel(entity *entities.InventoryMovement) *models.InventoryMovement {
	if entity == nil {
		return nil
	}

	return &models.InventoryMovement{
		ID:               entity.ID,
		OrganizationID:   entity.OrganizationID,
		OutletID:         entity.OutletID,
		ItemID:           entity.ItemID,
		ItemType:         entity.ItemType,
		MovementType:     models.InventoryMovementType(entity.MovementType),
		Quantity:         int(entity.Quantity),
		PreviousQuantity: int(entity.PreviousQuantity),
		NewQuantity:      int(entity.NewQuantity),
		UnitCost:         entity.UnitCost,
		TotalCost:        entity.TotalCost,
		ReferenceType:    (*models.InventoryMovementReferenceType)(entity.ReferenceType),
		ReferenceID:      entity.ReferenceID,
		OrderID:          entity.OrderID,
		PaymentID:        entity.PaymentID,
		UserID:           entity.UserID,
		Reason:           entity.Reason,
		Notes:            entity.Notes,
		Metadata:         map[string]interface{}(entity.Metadata),
		CreatedAt:        entity.CreatedAt,
	}
}

func InventoryMovementModelToEntity(model *models.InventoryMovement) *entities.InventoryMovement {
	if model == nil {
		return nil
	}

	return &entities.InventoryMovement{
		ID:               model.ID,
		OrganizationID:   model.OrganizationID,
		OutletID:         model.OutletID,
		ItemID:           model.ItemID,
		ItemType:         model.ItemType,
		MovementType:     entities.InventoryMovementType(model.MovementType),
		Quantity:         float64(model.Quantity),
		PreviousQuantity: float64(model.PreviousQuantity),
		NewQuantity:      float64(model.NewQuantity),
		UnitCost:         model.UnitCost,
		TotalCost:        model.TotalCost,
		ReferenceType:    (*entities.InventoryMovementReferenceType)(model.ReferenceType),
		ReferenceID:      model.ReferenceID,
		OrderID:          model.OrderID,
		PaymentID:        model.PaymentID,
		UserID:           model.UserID,
		Reason:           model.Reason,
		Notes:            model.Notes,
		Metadata:         entities.Metadata(model.Metadata),
		CreatedAt:        model.CreatedAt,
	}
}

func InventoryMovementEntityToResponse(entity *entities.InventoryMovement) *models.InventoryMovementResponse {
	if entity == nil {
		return nil
	}

	return &models.InventoryMovementResponse{
		ID:                  entity.ID,
		OrganizationID:      entity.OrganizationID,
		OutletID:            entity.OutletID,
		ItemID:              entity.ItemID,
		ItemType:            entity.ItemType,
		MovementType:        models.InventoryMovementType(entity.MovementType),
		Quantity:            int(entity.Quantity),
		PreviousQuantity:    int(entity.PreviousQuantity),
		NewQuantity:         int(entity.NewQuantity),
		UnitCost:            entity.UnitCost,
		TotalCost:           entity.TotalCost,
		ReferenceType:       (*models.InventoryMovementReferenceType)(entity.ReferenceType),
		ReferenceID:         entity.ReferenceID,
		OrderID:             entity.OrderID,
		PaymentID:           entity.PaymentID,
		UserID:              entity.UserID,
		Reason:              entity.Reason,
		Notes:               entity.Notes,
		Metadata:            map[string]interface{}(entity.Metadata),
		CreatedAt:           entity.CreatedAt,
		MovementDescription: entity.GetMovementDescription(),
	}
}

func InventoryMovementEntitiesToResponses(entities []*entities.InventoryMovement) []models.InventoryMovementResponse {
	responses := make([]models.InventoryMovementResponse, len(entities))
	for i, entity := range entities {
		if response := InventoryMovementEntityToResponse(entity); response != nil {
			responses[i] = *response
		}
	}
	return responses
}

func InventoryMovementEntitiesToModels(entities []*entities.InventoryMovement) []*models.InventoryMovement {
	models := make([]*models.InventoryMovement, len(entities))
	for i, entity := range entities {
		models[i] = InventoryMovementEntityToModel(entity)
	}
	return models
}

func CreateInventoryMovementRequestToEntity(req *models.CreateInventoryMovementRequest, previousQuantity, newQuantity int) *entities.InventoryMovement {
	if req == nil {
		return nil
	}

	return &entities.InventoryMovement{
		OrganizationID:   req.OrganizationID,
		OutletID:         req.OutletID,
		ItemID:           req.ItemID,
		ItemType:         req.ItemType,
		MovementType:     entities.InventoryMovementType(req.MovementType),
		Quantity:         float64(req.Quantity),
		PreviousQuantity: float64(previousQuantity),
		NewQuantity:      float64(newQuantity),
		UnitCost:         req.UnitCost,
		TotalCost:        float64(req.Quantity) * req.UnitCost,
		ReferenceType:    (*entities.InventoryMovementReferenceType)(req.ReferenceType),
		ReferenceID:      req.ReferenceID,
		OrderID:          req.OrderID,
		PaymentID:        req.PaymentID,
		UserID:           req.UserID,
		Reason:           req.Reason,
		Notes:            req.Notes,
		Metadata:         entities.Metadata(req.Metadata),
	}
}
