package dto

import (
	"math"
	"time"

	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	productWarehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/dto"
)

// === DTO Structs ===

type MarketingProductDTO struct {
	Id                  uint                                          `json:"id"`
	MarketingType       string                                        `json:"marketing_type"`
	Qty                 float64                                       `json:"qty"`
	UnitPrice           float64                                       `json:"unit_price"`
	AvgWeight           float64                                       `json:"avg_weight"`
	TotalWeight         float64                                       `json:"total_weight"`
	TotalPrice          float64                                       `json:"total_price"`
	ConvertionUnit      *string                                       `json:"convertion_unit,omitempty"`
	WeightPerConvertion *float64                                      `json:"weight_per_convertion,omitempty"`
	TotalPeti           *float64                                      `json:"total_peti,omitempty"`
	Week                *int                                          `json:"week,omitempty"`
	ProductWarehouse    *productWarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse,omitempty"`
}

type SalesOrdersListDTO struct {
	Id         uint                  `json:"id"`
	SoNumber   string                `json:"so_number"`
	SoDate     time.Time             `json:"so_date"`
	Notes      string                `json:"notes,omitempty"`
	SalesOrder []MarketingProductDTO `json:"sales_order,omitempty"`
}

// === Mapper Functions ===

func ToMarketingProductDTO(e entity.MarketingProduct, marketingType string) MarketingProductDTO {
	var productWarehouse *productWarehouseDTO.ProductWarehousNestedDTO

	if e.ProductWarehouse.Id != 0 {
		mapped := productWarehouseDTO.ToProductWarehouseNestedDTO(e.ProductWarehouse)
		productWarehouse = &mapped
	}

	// Calculate total_peti only for TELUR marketing type
	var totalPeti *float64
	if marketingType == "TELUR" && e.ConvertionUnit != nil && *e.ConvertionUnit == "PETI" && e.WeightPerConvertion != nil && *e.WeightPerConvertion > 0 {
		calculated := math.Floor(e.TotalWeight / *e.WeightPerConvertion)
		totalPeti = &calculated
	}

	return MarketingProductDTO{
		Id:                  e.Id,
		MarketingType:       marketingType,
		Qty:                 e.Qty,
		UnitPrice:           e.UnitPrice,
		AvgWeight:           e.AvgWeight,
		TotalWeight:         e.TotalWeight,
		TotalPrice:          e.TotalPrice,
		ConvertionUnit:      e.ConvertionUnit,
		WeightPerConvertion: e.WeightPerConvertion,
		TotalPeti:           totalPeti,
		Week:                e.Week,
		ProductWarehouse:    productWarehouse,
	}
}

func ToSalesOrdersListDTO(e entity.Marketing) SalesOrdersListDTO {
	products := make([]MarketingProductDTO, len(e.Products))
	for i, p := range e.Products {
		products[i] = ToMarketingProductDTO(p, e.MarketingType)
	}

	return SalesOrdersListDTO{
		Id:         e.Id,
		SoNumber:   e.SoNumber,
		SoDate:     e.SoDate,
		Notes:      e.Notes,
		SalesOrder: products,
	}
}

func ToSalesOrdersListDTOFromMarketing(e entity.Marketing) SalesOrdersListDTO {
	var salesOrder []MarketingProductDTO
	if len(e.Products) > 0 {
		salesOrder = make([]MarketingProductDTO, len(e.Products))
		for i, product := range e.Products {
			salesOrder[i] = ToMarketingProductDTO(product, e.MarketingType)
		}
	}

	return SalesOrdersListDTO{
		Id:         e.Id,
		SoNumber:   e.SoNumber,
		SoDate:     e.SoDate,
		Notes:      e.Notes,
		SalesOrder: salesOrder,
	}
}

func ToSalesOrdersListDTOsFromMarketing(e []entity.Marketing) []SalesOrdersListDTO {
	result := make([]SalesOrdersListDTO, len(e))
	for i, r := range e {
		result[i] = ToSalesOrdersListDTOFromMarketing(r)
	}
	return result
}
