package dto

import (
	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
)

// === DTO Structs ===

type ProductionStandardRelationDTO struct {
	Id              uint                     `json:"id"`
	Name            string                   `json:"name"`
	ProjectCategory string                   `json:"project_category"`
	CreatedUser     *userDTO.UserRelationDTO `json:"created_user"`
}

type ProductionStandardDetailDTO struct {
	ProductionStandardRelationDTO
	Details []WeeklyProductionStandardDTO `json:"details"`
}

type GrowthStandardDetailDTO struct {
	Id            uint     `json:"id"`
	TargetMeanBW  *float64 `json:"target_mean_bw"`
	MaxDepletion  *float64 `json:"max_depletion"`
	MinUniformity float64  `json:"min_uniformity"`
	FeedIntake    *float64 `json:"feed_intake"`
}

type EggProductionStandardDetailDTO struct {
	Id                      uint     `json:"id"`
	TargetHenDayProduction   *float64 `json:"target_hen_day_production"`
	TargetHenHouseProduction *float64 `json:"target_hen_house_production"`
	TargetEggWeight          *float64 `json:"target_egg_weight"`
	TargetEggMass            *float64 `json:"target_egg_mass"`
	StandardFCR              *float64 `json:"standard_fcr"`
}

type WeeklyProductionStandardDTO struct {
	Week                          int                               `json:"week"`
	GrowthStandardDetail          GrowthStandardDetailDTO           `json:"growth_standard_detail"`
	EggProductionStandardDetailDTO *EggProductionStandardDetailDTO  `json:"egg_production_standard_detail,omitempty"`
}

// === Mapper Functions ===

func ToProductionStandardListDTO(e entity.ProductionStandard) ProductionStandardRelationDTO {
	var createdUser *userDTO.UserRelationDTO
	if e.CreatedUser.Id != 0 {
		mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
		createdUser = &mapped
	}

	return ProductionStandardRelationDTO{
		Id:              e.Id,
		Name:            e.Name,
		ProjectCategory: e.ProjectCategory,
		CreatedUser:     createdUser,
	}
}

func ToProductionStandardRelationDTO(e entity.ProductionStandard) ProductionStandardRelationDTO {
	return ProductionStandardRelationDTO{
		Id:              e.Id,
		Name:            e.Name,
		ProjectCategory: e.ProjectCategory,
	}
}

func ToProductionStandardListDTOs(e []entity.ProductionStandard) []ProductionStandardRelationDTO {
	result := make([]ProductionStandardRelationDTO, len(e))
	for i, r := range e {
		result[i] = ToProductionStandardListDTO(r)
	}
	return result
}

func ToWeeklyProductionStandardDTO(e entity.StandardGrowthDetail) WeeklyProductionStandardDTO {
	return WeeklyProductionStandardDTO{
		Week: e.Week,
		GrowthStandardDetail: GrowthStandardDetailDTO{
			Id:            e.Id,
			TargetMeanBW:  e.TargetMeanBw,
			MaxDepletion:  e.MaxDepletion,
			MinUniformity: e.MinUniformity,
			FeedIntake:    e.FeedIntake,
		},
		EggProductionStandardDetailDTO: nil, // GROWING category - no egg production details
	}
}

func ToWeeklyProductionStandardDTOWithDetails(growth entity.StandardGrowthDetail, detail entity.ProductionStandardDetail) WeeklyProductionStandardDTO {
	eggDetail := &EggProductionStandardDetailDTO{
		Id:                      detail.Id,
		TargetHenDayProduction:   detail.TargetHenDayProduction,
		TargetHenHouseProduction: detail.TargetHenHouseProduction,
		TargetEggWeight:          detail.TargetEggWeight,
		TargetEggMass:            detail.TargetEggMass,
		StandardFCR:              detail.StandardFCR,
	}

	return WeeklyProductionStandardDTO{
		Week:                          growth.Week,
		GrowthStandardDetail: GrowthStandardDetailDTO{
			Id:            growth.Id,
			TargetMeanBW:  growth.TargetMeanBw,
			MaxDepletion:  growth.MaxDepletion,
			MinUniformity: growth.MinUniformity,
			FeedIntake:    growth.FeedIntake,
		},
		EggProductionStandardDetailDTO: eggDetail, // LAYING category - with egg production details
	}
}

func ToWeeklyProductionStandardDTOs(e []entity.StandardGrowthDetail) []WeeklyProductionStandardDTO {
	result := make([]WeeklyProductionStandardDTO, len(e))
	for i, r := range e {
		result[i] = ToWeeklyProductionStandardDTO(r)
	}
	return result
}

func ToWeeklyProductionStandardDTOsWithDetails(
	growthDetails []entity.StandardGrowthDetail,
	productionStandardDetails []entity.ProductionStandardDetail,
) []WeeklyProductionStandardDTO {
	result := make([]WeeklyProductionStandardDTO, len(growthDetails))

	// Create map for production standard details by week
	prodDetailMap := make(map[int]entity.ProductionStandardDetail)
	for _, detail := range productionStandardDetails {
		prodDetailMap[detail.Week] = detail
	}

	// Map growth details and combine with production standard details
	for i, growth := range growthDetails {
		if prodDetail, exists := prodDetailMap[growth.Week]; exists {
			result[i] = ToWeeklyProductionStandardDTOWithDetails(growth, prodDetail)
		} else {
			result[i] = ToWeeklyProductionStandardDTO(growth)
		}
	}

	return result
}

func ToEggProductionStandardDetailDTO(e entity.ProductionStandardDetail) EggProductionStandardDetailDTO {
	return EggProductionStandardDetailDTO{
		TargetHenDayProduction:   e.TargetHenDayProduction,
		TargetHenHouseProduction: e.TargetHenHouseProduction,
		TargetEggWeight:          e.TargetEggWeight,
		TargetEggMass:            e.TargetEggMass,
		StandardFCR:              e.StandardFCR,
	}
}

func ToProductionStandardDetailDTO(
	standard entity.ProductionStandard,
	growthDetails []entity.StandardGrowthDetail,
	productionStandardDetails []entity.ProductionStandardDetail,
) ProductionStandardDetailDTO {
	return ProductionStandardDetailDTO{
		ProductionStandardRelationDTO: ToProductionStandardRelationDTO(standard),
		Details:                   ToWeeklyProductionStandardDTOsWithDetails(growthDetails, productionStandardDetails),
	}
}
