package com.bytesw.bytebot.etl.services;

import com.bytesw.bytebot.etl.beans.SessionBean;
import com.bytesw.bytebot.etl.dao.ActionRepository;
import com.bytesw.bytebot.etl.dao.SessionActionRepository;
import com.bytesw.bytebot.etl.dao.UserRepository;
import com.bytesw.bytebot.etl.jdbc.ETLSessionBotJDBCRepository;
import com.bytesw.bytebot.etl.model.Action;
import com.bytesw.bytebot.etl.model.SessionAction;
import com.bytesw.bytebot.etl.model.User;
import com.bytesw.bytebot.etl.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import java.util.Optional;

@Service
@Transactional
public class ActionMessageProcessed extends MessageProcessedSupport implements MessageProcessed {

    @Autowired
    private ETLSessionBotJDBCRepository ETLSessionBotJDBCRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ActionRepository actionRepository;

    @Autowired
    private SessionActionRepository sessionActionRepository;

    @Value("${application.etl.action.user-field:sender_id}")
    private String userIdentifierFieldName;

    @Value("${application.etl.action.event-field:name}")
    private String eventFieldName;

    @PostConstruct
    private void init() {
        this.fields.put(SENDER_ID_FIELD_NAME, "$.sender_id");
        this.fields.put(TIMESTAMP_FIELD_NAME, "$.timestamp");
        this.fields.put(ACTION_FIELD_NAME, "$.name");
    }

    @Override
    public boolean process(String json, String oldSenderId) {
        String senderId = oldSenderId != null ? oldSenderId : (String) JsonUtils.getFieldFromJson(json, this.fields.get(SENDER_ID_FIELD_NAME));
        if (senderId != null) {
            Optional<User> userFound = userRepository.findByIdentifier(senderId);
            if (!userFound.isPresent()) {
                return false;
            }

            SessionBean session = ETLSessionBotJDBCRepository.getLastSessionByUser(userFound.get().getId());
            String actionIdentifier = (String) JsonUtils.getFieldFromJson(json, this.fields.get(ACTION_FIELD_NAME));
            if (session != null && actionIdentifier != null && !actionIdentifier.isEmpty()) {
                Optional<Action> actionFound = actionRepository.findByIdentifier(actionIdentifier);
                if (!actionFound.isPresent()) {
                    return false;
                }

                Double timestamp = (Double) JsonUtils.getFieldFromJson(json, this.fields.get(TIMESTAMP_FIELD_NAME));
                SessionAction sessionAction = new SessionAction();
                sessionAction.setAction(actionFound.get());
                sessionAction.setSessionId(session.getId());
                sessionAction.setDate(getOffsetDateTimeFromTimestampPython(timestamp));

                sessionActionRepository.save(sessionAction);

                updateEventDate(session.getId(), sessionAction.getDate());
                return true;
            }
        }
        return false;
    }
}
