package de.effigenix.infrastructure.masterdata.persistence.mapper;

import de.effigenix.domain.masterdata.*;
import de.effigenix.infrastructure.masterdata.persistence.entity.ArticleEntity;
import de.effigenix.infrastructure.masterdata.persistence.entity.SalesUnitEntity;
import de.effigenix.shared.common.Money;
import org.springframework.stereotype.Component;

import java.util.Currency;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class ArticleMapper {

    public ArticleEntity toEntity(Article article) {
        var entity = new ArticleEntity(
                article.id().value(),
                article.name().value(),
                article.articleNumber().value(),
                article.categoryId().value(),
                article.status().name(),
                article.createdAt(),
                article.updatedAt()
        );

        List<SalesUnitEntity> salesUnitEntities = article.salesUnits().stream()
                .map(su -> toSalesUnitEntity(su, entity))
                .collect(Collectors.toList());
        entity.setSalesUnits(salesUnitEntities);

        Set<String> supplierIds = article.supplierReferences().stream()
                .map(SupplierId::value)
                .collect(Collectors.toSet());
        entity.setSupplierIds(supplierIds);

        return entity;
    }

    public Article toDomain(ArticleEntity entity) {
        List<SalesUnit> salesUnits = entity.getSalesUnits().stream()
                .map(this::toDomainSalesUnit)
                .collect(Collectors.toList());

        Set<SupplierId> supplierRefs = entity.getSupplierIds().stream()
                .map(SupplierId::of)
                .collect(Collectors.toSet());

        return Article.reconstitute(
                ArticleId.of(entity.getId()),
                new ArticleName(entity.getName()),
                new ArticleNumber(entity.getArticleNumber()),
                ProductCategoryId.of(entity.getCategoryId()),
                salesUnits,
                ArticleStatus.valueOf(entity.getStatus()),
                supplierRefs,
                entity.getCreatedAt(),
                entity.getUpdatedAt()
        );
    }

    private SalesUnitEntity toSalesUnitEntity(SalesUnit su, ArticleEntity article) {
        return new SalesUnitEntity(
                su.id().value(),
                article,
                su.unit().name(),
                su.priceModel().name(),
                su.price().amount(),
                su.price().currency().getCurrencyCode()
        );
    }

    private SalesUnit toDomainSalesUnit(SalesUnitEntity entity) {
        return SalesUnit.reconstitute(
                SalesUnitId.of(entity.getId()),
                Unit.valueOf(entity.getUnit()),
                PriceModel.valueOf(entity.getPriceModel()),
                new Money(entity.getPriceAmount(), Currency.getInstance(entity.getPriceCurrency()))
        );
    }
}
