package premium_store.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import premium_store.controller.DTO.SupportTankDTO;
import premium_store.controller.DTO.TankDTO;
import premium_store.model.TankLevel;
import premium_store.model.Nation;
import premium_store.model.Tank;
import premium_store.repository.NationRepository;
import premium_store.repository.TankLevelRepository;
import premium_store.repository.TankRepository;
import premium_store.service.exception.TankNotFoundException;
import premium_store.util.validation.ValidatorUtil;

import java.util.List;
import java.util.Optional;

@Service
public class TankService {
    private final TankRepository tankRepository;
    private final NationRepository nationRepository;
    private final TankLevelRepository levelRepository;
    private final ValidatorUtil validatorUtil;

    public TankService(TankRepository tankRepository, NationRepository nationRepository, TankLevelRepository levelRepository, ValidatorUtil validatorUtil){
        this.tankRepository = tankRepository;
        this.nationRepository = nationRepository;
        this.levelRepository = levelRepository;
        this.validatorUtil = validatorUtil;
    }

    @Transactional
    public Tank addTank(String newName, Nation newNation, TankLevel newTankLevel, int newCost) {
        final Tank tank = new Tank(newName, newNation, newTankLevel, newCost);
        validatorUtil.validate(tank);

        return tankRepository.save(tank);
    }

    @Transactional
    public Tank addTank(SupportTankDTO tankDTO) {
        final Tank tank = new Tank(tankDTO.getName(), nationRepository.getById(tankDTO.getNationId()),
                levelRepository.getById(tankDTO.getLevelId()), tankDTO.getCost());
        validatorUtil.validate(tank);

        return tankRepository.save(tank);
    }

    @Transactional(readOnly = true)
    public Tank findTank(Long id) {
        final Optional<Tank> tank = tankRepository.findById(id);

        return tank.orElseThrow(() -> new TankNotFoundException(id));
    }

    @Transactional(readOnly = true)
    public List<Tank> findAllTanks() {
        return tankRepository.findAll();
    }

    @Transactional
    public Tank updateTank(Long id, String newName, Nation newNation,
                           TankLevel newLevel, int newCost) {
        if (id <= 0) {
            throw new IllegalArgumentException("Invalid id");
        }

        final Tank currentTank = findTank(id);

        if (StringUtils.hasText(newName)){
            currentTank.setName(newName);
        }

        if(newNation != null){
            currentTank.setNation(newNation);
        }

        if(newLevel != null){
            currentTank.setLevel(newLevel);
        }

        if(newCost > 0){
            currentTank.setCost(newCost);
        }

        return tankRepository.save(currentTank);
    }

    @Transactional
    public Tank updateTank(SupportTankDTO tankDTO) {
        if (tankDTO.getId() <= 0) {
            throw new IllegalArgumentException("Invalid id");
        }

        final Tank currentTank = findTank(tankDTO.getId());

        currentTank.setName(tankDTO.getName());
        currentTank.setNation(nationRepository.getById(tankDTO.getNationId()));
        currentTank.setLevel(levelRepository.getById(tankDTO.getLevelId()));
        currentTank.setCost(tankDTO.getCost());

        return tankRepository.save(currentTank);
    }

    @Transactional
    public Tank deleteTank(Long id) {
        final Tank currentTank = findTank(id);
        tankRepository.delete(currentTank);

        return currentTank;
    }

    //запрос на удаление всех записей в таблице
    @Transactional
    public void deleteAllTanks() {
        tankRepository.deleteAll();
    }

    @Transactional(readOnly = true)
    public List<Tank> findListTank(String nationName, int levelFirst, int levelSecond) {
        return tankRepository.checkNationAndLevel(nationName, levelFirst, levelSecond);
    }
}

