package dev.fyloz.trial.colorrecipesexplorer.service.model;

import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityAlreadyExistsException;
import dev.fyloz.trial.colorrecipesexplorer.exception.model.EntityNotFoundException;
import dev.fyloz.trial.colorrecipesexplorer.exception.model.ModelException;
import dev.fyloz.trial.colorrecipesexplorer.model.Material;
import dev.fyloz.trial.colorrecipesexplorer.model.MixType;
import dev.fyloz.trial.colorrecipesexplorer.model.MaterialType;
import dev.fyloz.trial.colorrecipesexplorer.service.AbstractJavaService;
import dev.fyloz.trial.colorrecipesexplorer.repository.MixTypeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.Optional;

@Service
public class MixTypeService extends AbstractJavaService<MixType, MixTypeRepository> {

    private MaterialJavaService materialService;

    public MixTypeService() {
        super(MixType.class);
    }

    @Autowired
    public void setMixTypeDao(MixTypeRepository mixTypeRepository) {
        this.repository = mixTypeRepository;
    }

    @Autowired
    public void setMaterialService(MaterialJavaService materialService) {
        this.materialService = materialService;
    }

    /**
     * Vérifie si un type de mélange correspondant à un nom existe.
     *
     * @param name Le nom du type de mélange
     * @return Si un type de mélange correspondant au nom existe
     */
    public boolean existsByName(String name) {
        return repository.existsByName(name);
    }

    /**
     * Récupère le type de mélange correspondant à un nom.
     *
     * @param name Le nom du type de mélange
     * @return Le type de mélange correspondant au nom
     */
    public MixType getByName(String name) {
        Optional<MixType> found = repository.findByName(name);
        if (found.isEmpty()) throw new EntityNotFoundException(type, ModelException.IdentifierType.NAME, name);

        return found.get();
    }

    /**
     * Récupère le type de mélange correspondant à un produit.
     *
     * @param material Le produit du type de mélange
     * @return Le type de mélange correspondant au produit
     */
    public MixType getByMaterial(Material material) {
        Optional<MixType> found = repository.findByMaterial(material);
        if (found.isEmpty())
            throw new EntityNotFoundException(type, ModelException.IdentifierType.OTHER, MixType.IDENTIFIER_MATERIAL_NAME, material);

        return found.get();
    }

    /**
     * Crée un type de mélange.
     *
     * @param name         Le nom du type de mélange
     * @param materialType Le type de produit du type de mélange
     * @return Le type de mélange créé
     */
    public MixType create(String name, MaterialType materialType) {
        Material mixTypeMaterial = new Material(name, 0f, true, materialType);
        return new MixType(name, mixTypeMaterial);
    }

    @Override
    public MixType save(@NotNull MixType entity) {
        if (materialService.existsByName(entity.getName()))
            throw new EntityAlreadyExistsException(type, ModelException.IdentifierType.OTHER, MixType.IDENTIFIER_MATERIAL_NAME, entity.getName());

        return super.save(entity);
    }

    @Override
    public MixType update(MixType mixType) {

        return super.update(mixType);
    }
}
