package com.bytesw.bytebot.service;

import com.bytesw.bytebot.etl.beans.GoalForActionsBean;
import com.bytesw.bytebot.etl.dao.ActionRepository;
import com.bytesw.bytebot.etl.model.Action;
import com.bytesw.bytebot.etl.model.GoalForActions;
import com.bytesw.bytebot.repository.GoalForActionsRepository;
import com.bytesw.bytebot.repository.GoalRepository;
import com.bytesw.xdf.exception.NotFoundException;
import com.bytesw.xdf.service.XDFService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
@Log4j2
public class GoalForActionService extends XDFService<GoalForActions, GoalForActionsBean, Long> {

    @Autowired
    private GoalRepository goalRepository;

    @Autowired
    private ActionRepository actionRepository;

    @Autowired
    private GoalForActionsRepository goalForActionsRepository;

    protected GoalForActionService(GoalForActionsRepository repository) {
        super(repository);
    }

    @Override
    protected GoalForActions toModel(GoalForActions model, GoalForActionsBean bean) {
        if (model == null) {
            model = new GoalForActions();
        }
        BeanUtils.copyProperties(bean, model);
        return model;
    }

    @Override
    protected GoalForActionsBean toBean(GoalForActions model) {
        GoalForActionsBean bean = new GoalForActionsBean();
        BeanUtils.copyProperties(model, bean);
        return bean;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void saveGoalForAction(Long idGoal, List<Object> actions) {
        if (!goalRepository.existsById(idGoal)) {
            throw new NotFoundException("Goal no registrado.");
        }
        Map<String, String> dataAction = new HashMap<String, String>();
        for(Object action : actions){
            GoalForActions goalForActions = new GoalForActions();
            goalForActions.setGoalId(idGoal);
            dataAction = (HashMap) action;
            if (!actionRepository.existsById(Long.valueOf(dataAction.get("IdAction").toString()))) {
                continue;
            }
            goalForActions.setActionId(Long.valueOf(dataAction.get("IdAction").toString()));
            goalForActions = goalForActionsRepository.save(goalForActions);
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteGoalForAction(Long goalId) {
        Optional<List<GoalForActions>> listGoalForActions = goalForActionsRepository.findGoalForActionsByGoalId(goalId);

        if (!listGoalForActions.isPresent()) {
            throw new NotFoundException("GoalForActions no econtrados.");
        }

        for (GoalForActions goalForActions: listGoalForActions.get()) {
            goalForActionsRepository.delete(goalForActions);
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateGoalForAction(Long idGoal, List<Object> actions) {
        Optional<List<GoalForActions>> listActual = goalForActionsRepository.findGoalForActionsByGoalId(idGoal);
        if (!listActual.isPresent()) {
            throw new NotFoundException("GoalForActions no encontrados.");
        }

        Map<String, String> dataAction = new HashMap<>();
        List<Long> idActions = new ArrayList<>();
        for (Object object: actions) {
            dataAction = (HashMap) object;
            idActions.add(Long.valueOf(dataAction.get("IdAction")));
        }

        for (GoalForActions goalForActions : listActual.get()) {
            if (!idActions.contains(goalForActions.getActionId())) {
                goalForActionsRepository.delete(goalForActions);
            } else {
                idActions.remove(goalForActions.getActionId());
            }
        }

        for (Long id: idActions) {
            GoalForActions newGoalForActions = new GoalForActions();
            newGoalForActions.setGoalId(idGoal);
            newGoalForActions.setActionId(id);
            goalForActionsRepository.save(newGoalForActions);
        }
    }

    public List<Map> getGoalForAction(Long id) {
        List<Map> list = new ArrayList<>();
        Optional<List<GoalForActions>> goalForActions = goalForActionsRepository.findGoalForActionsByGoalId(id);
        if (!goalForActions.isPresent()) {
            throw new NotFoundException("No se encontraron actions.");
        }

        for (GoalForActions actions : goalForActions.get()) {
            Action action = actionRepository.findById(actions.getActionId()).get();
            if (action == null) {
                log.debug("No se encontró la accion.");
                continue;
            }
            Map<String, String> map = new HashMap<>();
            map.put("IdAction", String.valueOf(action.getId()));
            list.add(map);
        }

        return list;
    }
}
