package relationers

// |@@| C

import (
	"context"
	"gardening/src/lib/relationer"
	"gardening/src/mdl"
	"gardening/src/srv/fetchers"
)

type PlantationRelationer struct {
	GardenFetcher     *fetchers.GardenFetcher
	GardenTaskFetcher *fetchers.GardenTaskFetcher
	PlantFetcher      *fetchers.PlantFetcher
	Relationer        *relationer.Relationer
}

func (this *PlantationRelationer) DistributeGardenTasks(ctx context.Context, set []*mdl.Plantation, setToMerge []*mdl.GardenTask) {
	for _, item := range set {
		for _, itemToMerge := range setToMerge {
			if item.Id == itemToMerge.PlantationId {
				item.GardenTasks = append(item.GardenTasks, itemToMerge)
			}
		}
	}
}
func (this *PlantationRelationer) HydrateGardenTasks(ctx context.Context, set []*mdl.Plantation, mod *relationer.RelationerMod) error {
	ids := this.Relationer.GetUniqueEntitiesIds(ctx, this.convertPlantationsToEntities(set))
	if len(ids) == 0 {
		return nil
	}
	setToMerge, err := this.GardenTaskFetcher.FindSetInPlantationIds(ctx, ids, this.Relationer.GetFetcherMod(mod))
	if err != nil {
		return err
	}
	this.DistributeGardenTasks(ctx, set, setToMerge)
	return nil
}
func (this *PlantationRelationer) convertPlantationsToEntities(entities []*mdl.Plantation) []relationer.Entity {
	var set []relationer.Entity
	for _, p := range entities {
		set = append(set, p)
	}
	return set
}
func (this *PlantationRelationer) DistributePlant(ctx context.Context, set []*mdl.Plantation, setToMerge []*mdl.Plant) {
	m := make(map[string]*mdl.Plant)
	for _, itemToMerge := range setToMerge {
		m[itemToMerge.Id] = itemToMerge
	}
	for _, item := range set {
		itemToMerge := m[item.PlantId]
		item.Plant = itemToMerge
	}
}
func (this *PlantationRelationer) HydratePlant(ctx context.Context, set []*mdl.Plantation, mod *relationer.RelationerMod) error {
	ids := this.GetPlantIds(ctx, set)
	if len(ids) == 0 {
		return nil
	}
	setToMerge, err := this.PlantFetcher.FindSetIn(ctx, ids, this.Relationer.GetFetcherMod(mod))
	if err != nil {
		return err
	}
	this.DistributePlant(ctx, set, setToMerge)
	return nil
}
func (this *PlantationRelationer) GetPlantIds(ctx context.Context, set []*mdl.Plantation) []string {
	return this.Relationer.GetUniqueIds(ctx, func() []string {
		var ids []string
		for _, item := range set {
			ids = append(ids, item.PlantId)
		}
		return ids
	})
}
func (this *PlantationRelationer) DistributeGarden(ctx context.Context, set []*mdl.Plantation, setToMerge []*mdl.Garden) {
	m := make(map[string]*mdl.Garden)
	for _, itemToMerge := range setToMerge {
		m[itemToMerge.Id] = itemToMerge
	}
	for _, item := range set {
		itemToMerge := m[item.GardenId]
		item.Garden = itemToMerge
	}
}
func (this *PlantationRelationer) HydrateGarden(ctx context.Context, set []*mdl.Plantation, mod *relationer.RelationerMod) error {
	ids := this.GetGardenIds(ctx, set)
	if len(ids) == 0 {
		return nil
	}
	setToMerge, err := this.GardenFetcher.FindSetIn(ctx, ids, this.Relationer.GetFetcherMod(mod))
	if err != nil {
		return err
	}
	this.DistributeGarden(ctx, set, setToMerge)
	return nil
}
func (this *PlantationRelationer) GetGardenIds(ctx context.Context, set []*mdl.Plantation) []string {
	return this.Relationer.GetUniqueIds(ctx, func() []string {
		var ids []string
		for _, item := range set {
			ids = append(ids, item.GardenId)
		}
		return ids
	})
}
