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

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.stream.Collectors;

import io.delphiplatform.api.v3.model.shazam.ShazamCity;
import io.delphiplatform.api.v3.rdb.entity.video.ShazamCityEntity;
import io.delphiplatform.api.v3.rdb.repository.ShazamCityRepository;
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.CITY_NAME;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.COUNTRY_CODE;
import static io.delphiplatform.api.v3.rdb.entity.CommonJpaPropertyNames.SHAZAM_CITY_ID;

@Service
@Transactional(readOnly = true)
public class ShazamCityService extends EntityService<ShazamCityEntity> {

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

    private final SpecificationProvider<ShazamCityEntity> specificationProvider;

    @Autowired
    public ShazamCityService(ShazamCityRepository repository,
        SpecificationProvider<ShazamCityEntity> specificationProvider) {
        super(repository, SORT_BY_TO_ENTITY_FIELD_MAP);
        this.specificationProvider = specificationProvider;
    }

    public List<ShazamCity> getShazamCities(Params params) {
        Specification<ShazamCityEntity> spec = and(Arrays.asList(
            specificationProvider.multiValueSpec(SHAZAM_CITY_ID, params.getCityCode()),
            specificationProvider.multiValueSpec(CITY_NAME, params.getCityName()),
            specificationProvider.multiValueSpec(COUNTRY_CODE, params.getCountryCode())
        ));

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

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

}
