package transformer

import (
	"apskel-pos-be/internal/appcontext"
	"apskel-pos-be/internal/constants"
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/models"
)

func CreateProductRequestToModel(apctx *appcontext.ContextInfo, req *contract.CreateProductRequest) *models.CreateProductRequest {
	cost := float64(0)
	if req.Cost != nil {
		cost = *req.Cost
	}

	businessType := constants.BusinessTypeRestaurant
	if req.BusinessType != nil {
		businessType = constants.BusinessType(*req.BusinessType)
	}

	var variants []models.CreateProductVariantRequest
	if req.Variants != nil {
		variants = make([]models.CreateProductVariantRequest, len(req.Variants))
		for i, variant := range req.Variants {
			variants[i] = models.CreateProductVariantRequest{
				ProductID:     variant.ProductID,
				Name:          variant.Name,
				PriceModifier: variant.PriceModifier,
				Cost:          variant.Cost,
				Metadata:      variant.Metadata,
			}
		}
	}

	metadata := req.Metadata
	if metadata == nil {
		metadata = make(map[string]interface{})
	}

	return &models.CreateProductRequest{
		OrganizationID: apctx.OrganizationID,
		CategoryID:     req.CategoryID,
		SKU:            req.SKU,
		Name:           req.Name,
		Description:    req.Description,
		Price:          req.Price,
		Cost:           cost,
		BusinessType:   businessType,
		ImageURL:       req.ImageURL,
		PrinterType:    req.PrinterType,
		Metadata:       metadata,
		Variants:       variants,
	}
}

func UpdateProductRequestToModel(req *contract.UpdateProductRequest) *models.UpdateProductRequest {
	metadata := req.Metadata
	if metadata == nil {
		metadata = make(map[string]interface{})
	}

	return &models.UpdateProductRequest{
		CategoryID:  req.CategoryID,
		SKU:         req.SKU,
		Name:        req.Name,
		Description: req.Description,
		Price:       req.Price,
		Cost:        req.Cost,
		ImageURL:    req.ImageURL,
		PrinterType: req.PrinterType,
		Metadata:    metadata,
		IsActive:    req.IsActive,
	}
}

// Model to Contract conversions
func ProductModelResponseToResponse(prod *models.ProductResponse) *contract.ProductResponse {
	if prod == nil {
		return nil
	}

	// Convert variants to contract responses
	var variantResponses []contract.ProductVariantResponse
	if prod.Variants != nil {
		variantResponses = make([]contract.ProductVariantResponse, len(prod.Variants))
		for i, variant := range prod.Variants {
			variantResponses[i] = contract.ProductVariantResponse{
				ID:            variant.ID,
				ProductID:     variant.ProductID,
				Name:          variant.Name,
				PriceModifier: variant.PriceModifier,
				Cost:          variant.Cost,
				Metadata:      variant.Metadata,
				CreatedAt:     variant.CreatedAt,
				UpdatedAt:     variant.UpdatedAt,
			}
		}
	}

	return &contract.ProductResponse{
		ID:             prod.ID,
		OrganizationID: prod.OrganizationID,
		CategoryID:     prod.CategoryID,
		SKU:            prod.SKU,
		Name:           prod.Name,
		Description:    prod.Description,
		Price:          prod.Price,
		Cost:           prod.Cost,
		BusinessType:   string(prod.BusinessType),
		ImageURL:       prod.ImageURL,
		PrinterType:    prod.PrinterType,
		Metadata:       prod.Metadata,
		IsActive:       prod.IsActive,
		CreatedAt:      prod.CreatedAt,
		UpdatedAt:      prod.UpdatedAt,
		Variants:       variantResponses,
	}
}

// Slice conversions
func ProductsToResponses(products []models.ProductResponse) []contract.ProductResponse {
	responses := make([]contract.ProductResponse, len(products))
	for i, prod := range products {
		response := ProductModelResponseToResponse(&prod)
		if response != nil {
			responses[i] = *response
		}
	}
	return responses
}

// Product Variant Transformers
func CreateProductVariantRequestToModel(req *contract.CreateProductVariantRequest) *models.CreateProductVariantRequest {
	if req == nil {
		return nil
	}

	return &models.CreateProductVariantRequest{
		ProductID:     req.ProductID,
		Name:          req.Name,
		PriceModifier: req.PriceModifier,
		Cost:          req.Cost,
		Metadata:      req.Metadata,
	}
}

func UpdateProductVariantRequestToModel(req *contract.UpdateProductVariantRequest) *models.UpdateProductVariantRequest {
	if req == nil {
		return nil
	}

	return &models.UpdateProductVariantRequest{
		Name:          req.Name,
		PriceModifier: req.PriceModifier,
		Cost:          req.Cost,
		Metadata:      req.Metadata,
	}
}

func ProductVariantModelResponseToResponse(variant *models.ProductVariantResponse) *contract.ProductVariantResponse {
	if variant == nil {
		return nil
	}

	return &contract.ProductVariantResponse{
		ID:            variant.ID,
		ProductID:     variant.ProductID,
		Name:          variant.Name,
		PriceModifier: variant.PriceModifier,
		Cost:          variant.Cost,
		Metadata:      variant.Metadata,
		CreatedAt:     variant.CreatedAt,
		UpdatedAt:     variant.UpdatedAt,
	}
}

func ProductVariantsToResponses(variants []models.ProductVariantResponse) []contract.ProductVariantResponse {
	responses := make([]contract.ProductVariantResponse, len(variants))
	for i, variant := range variants {
		response := ProductVariantModelResponseToResponse(&variant)
		if response != nil {
			responses[i] = *response
		}
	}
	return responses
}
