package io.delphiplatform.api.v3.rdb.service.amazon;

import com.google.common.collect.ImmutableMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import io.delphiplatform.api.v3.model.amazon.AmazonChart;
import io.delphiplatform.api.v3.rdb.entity.amazon.AmazonChartEntity;
import io.delphiplatform.api.v3.rdb.repository.amazon.AmazonChartRepository;
import io.delphiplatform.api.v3.rdb.service.EntityService;
import io.delphiplatform.api.v3.rdb.service.dto.JpaPropertyPath;
import io.delphiplatform.api.v3.rdb.service.specification.SpecificationProvider;
import io.delphiplatform.api.v3.view.util.Params;

import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.AMAZON_GENRE;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.AMAZON_GENRE_NAME;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.CHART_ID;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.COUNTRY_CODE;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.REGION;


@Service
@Transactional(readOnly = true)
public class AmazonChartService extends EntityService<AmazonChartEntity> {

    private static final ImmutableMap<String, String> SORT_BY_TO_ENTITY_FIELD_MAP =
        ImmutableMap.<String, String>builder()
            .put("genre", "genre_name")
            .build();

    private final SpecificationProvider<AmazonChartEntity> specificationProvider;

    @Autowired
    public AmazonChartService(
        AmazonChartRepository repository,
        SpecificationProvider<AmazonChartEntity> specificationProvider
    ) {
        super(repository, SORT_BY_TO_ENTITY_FIELD_MAP);
        this.specificationProvider = specificationProvider;
    }

    public List<AmazonChart> getAmazonCharts(Params params) {
        Set<JpaPropertyPath> fetches =
            Set.of(JpaPropertyPath.ofJoin(AMAZON_GENRE), JpaPropertyPath.ofJoin(REGION));

        Specification<AmazonChartEntity> spec = and(Arrays.asList(
            specificationProvider.multiValueSpec(CHART_ID, params.getChartId()),
            specificationProvider.multiValueSpec(List.of(REGION, COUNTRY_CODE), params.getCountryCode()),
            specificationProvider.multiTextIgnoreCaseValueSpec(List.of(AMAZON_GENRE, AMAZON_GENRE_NAME), params.getGenreName()),
            specificationProvider.fetchesSpecOfPaths(fetches)
        ));

        List<AmazonChartEntity> entities = find(spec, getPageRequestSortByToCamelCase(params));

        return entities.stream().map(AmazonChart::of).collect(Collectors.toList());
    }
}