package com.bytesw.bytebot.etl.services;

import com.bytesw.bytebot.etl.beans.SessionBean;
import com.bytesw.bytebot.etl.dao.ResponseRepository;
import com.bytesw.bytebot.etl.dao.UserRepository;
import com.bytesw.bytebot.etl.jdbc.ETLResponseJDBCRepository;
import com.bytesw.bytebot.etl.jdbc.ETLSessionBotJDBCRepository;
import com.bytesw.bytebot.etl.model.Response;
import com.bytesw.bytebot.etl.model.Session;
import com.bytesw.bytebot.etl.model.User;
import com.bytesw.bytebot.etl.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

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

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ETLSessionBotJDBCRepository ETLSessionBotJDBCRepository;

    @Autowired
    private ETLResponseJDBCRepository responseJDBCRepository;

    @Autowired
    private ResponseRepository responseRepository;

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

    @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());
            if (session != null) {
                int correlative = responseJDBCRepository.getLastCorrelativeBySession(session.getId());
                String content = (String) JsonUtils.getFieldFromJson(json, this.fields.get(CONTENT_FIELD_NAME));
                Double timestamp = (Double) JsonUtils.getFieldFromJson(json, this.fields.get(TIMESTAMP_FIELD_NAME));
                if (content != null && timestamp != null) {
                    Response response = new Response();
                    response.setSessionId(session.getId());
                    response.setCorrelative(correlative++);
                    response.setContent(content);
                    response.setDate(getOffsetDateTimeFromTimestampPython(timestamp));

                    responseRepository.save(response);

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

    private void updateFirstResponse(SessionBean session, OffsetDateTime date) {
        if (session.getResponseDate() == null) {
            Optional<Session> sessionFond = sessionBotRepository.findById(session.getId());
            if (sessionFond.isPresent()) {
                Session sessionDB = sessionFond.get();
                sessionDB.setResponseDate(date);
                sessionBotRepository.save(sessionDB);
            }
        }
    }
}
