package ru.kayashov.bar.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.mapper.IngredientMapper;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.BarIngredientStorage;
import ru.kayashov.bar.repository.BarIngredientStorageRepository;
import ru.kayashov.bar.model.entity.BarResident;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.TypeEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.TypeRepository;

import java.util.List;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class IngredientService {

    private final VisitorService visitorService;
    private final TypeRepository typeRepository;
    private final IngredientRepository repository;
    private final IngredientMapper mapper;
    private final BarIngredientStorageRepository barIngredientStorageRepository;

    public IngredientEntity findIngredientByName(String name) {
        return repository.findByEnNameIgnoreCase(name)
                .orElseThrow(() -> new RuntimeException("Не удалось найти ингредиент с названием " + name));
    }

    private TypeEntity findTypeByName(String name) {
        return typeRepository.findByName(name)
                .orElse(null);
    }

    /**
     * Запрос ингредиентов бара
     */
    public List<IngredientResponseDto> getAll() {
        List<IngredientEntity> ingredients = repository.findAll();
        return mapper.mapIngredientsToDtoList(ingredients);
    }

    public List<IngredientSimpleResponseDto> getAllSimple() {
        List<IngredientEntity> ingredients = repository.findAll();
        return mapper.mapIngredientsToSimpleDtoList(ingredients);
    }

    public IngredientEntity getIngredientById(Long id) {
        return repository.findById(id).orElseThrow();
    }

    public void changeBarIngredient(Long id, boolean isHave) {
        Visitor visitor = visitorService.getCurrentVisitor();
        BarEntity bar = visitor.getResidents()
                .stream()
                .filter(BarResident::getActive)
                .map(BarResident::getBar)
                .toList()
                .get(0);
        List<BarIngredientStorage> storage = bar.getIngredients();
        IngredientEntity ingredientEntity = getIngredientById(id);
        if (isHave) {
            BarIngredientStorage entity = new BarIngredientStorage();
            entity.setBar(bar);
            entity.setIngredient(ingredientEntity);
            //todo: прикрутить позже        entity.setMeasure();
            entity = barIngredientStorageRepository.save(entity);
            storage.add(entity);
        } else {
            storage.stream()
                    .filter(s -> Objects.equals(s.getIngredient().getId(), ingredientEntity.getId()))
                    .forEach(s -> barIngredientStorageRepository.deleteById(s.getId()));
        }
    }

    public boolean saveChange(IngredientResponseDto dto) {
        if (dto.getId() == null) {
            return false;
        }
        IngredientEntity entity = repository.findById(dto.getId())
                .orElse(null);
        if (entity == null) {
            return false;
        }

        entity.setName(dto.getName());
        entity.setDescription(dto.getDescription());
//        entity.setEnName(dto.getEnName());
//    entity.setIsHave(dto.isHave());
        entity.setAbv(dto.getAbv());
        entity.setAlcohol(dto.getAlcohol());

        TypeEntity type = findTypeByName(dto.getType());
        if (type == null) {
            return false;
        }
        entity.setType(type);
        repository.save(entity);
        return true;
    }
}
