package com.bytesw.bytebot.etl.batch.writer;

import com.bytesw.bytebot.etl.batch.beans.DeleteDataSensBean;
import com.bytesw.bytebot.etl.batch.beans.DeleteDataSensRegistryBean;
import com.bytesw.bytebot.etl.batch.beans.DynaBean;
import com.bytesw.bytebot.etl.dao.DeleteDataSensibleControlRepository;
import com.bytesw.bytebot.etl.dao.DeleteDataSensibleLogRepository;
import com.bytesw.bytebot.etl.dao.IntentRepository;
import com.bytesw.bytebot.etl.enums.EventTypeEnum;
import com.bytesw.bytebot.etl.model.DeleteDataSensibleControl;
import com.bytesw.bytebot.etl.model.DeleteDataSensibleLog;
import com.bytesw.bytebot.etl.model.Intent;
import com.bytesw.bytebot.etl.services.DeleteSensMessageService;
import com.bytesw.bytebot.etl.utils.JsonUtils;
import com.bytesw.xdf.exception.NotFoundException;
import com.bytesw.xdf.multitenant.core.ThreadLocalStorage;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.item.ItemWriter;

import javax.transaction.Transactional;
import java.sql.Timestamp;
import java.time.OffsetDateTime;
import java.util.*;


@Log4j2
public class DataSensibleJPAWriter implements ItemWriter<DynaBean>, StepExecutionListener {

    @Getter
    @Setter
    private DeleteDataSensibleControlRepository deleteDataSensibleControlRepository;

    @Getter
    @Setter
    private DeleteDataSensibleLogRepository deleteDataSensibleLogRepository;

    @Getter
    @Setter
    private IntentRepository intentRepository;

    @Getter
    @Setter
    private DeleteSensMessageService service;

    @Getter
    @Setter
    private List<String> intentByAgent;

    @Getter
    @Setter
    private DeleteDataSensBean agent;

    @Override
    @Transactional
    public void write(List<? extends DynaBean> list) throws Exception {
        Object numeros = JsonUtils.getFieldFromJson(agent.getChannelValue(), "$.telefono_despliegue");
        List<String> numerosAgentes = numbersAgent((List<Map>) numeros);
        for (DynaBean dynaBean : list) {
            Long id = Long.parseLong(dynaBean.get("id").toString());
            String json = (String) dynaBean.get("data");
            String event = (String) JsonUtils.getFieldFromJson(json, "$.event");
            String sender_id;
            boolean update_control = false;
            String presentDate = OffsetDateTime.now().toString().replace('T', ' ');
            String timeZone = presentDate.substring(presentDate.length() - 6);
            presentDate = presentDate.replace(timeZone, "");
            if (EventTypeEnum.USER.getName().equals(event)) {
                String toAgent = (String) JsonUtils.getFieldFromJson(json, "$.metadata.To");
                String agentNumber = new String();
                if (toAgent == null) {
                   continue;
                }
                if (!toAgent.isEmpty()) {
                    agentNumber = toAgent.split(":")[1];
                }
                if (numerosAgentes.contains(agentNumber)) {
                    String intent = (String) JsonUtils.getFieldFromJson(json, "$.parse_data.intent.name");
                    if (intentByAgent.contains(intent)) {
                        String SmSMessageSid = (String) JsonUtils.getFieldFromJson(json, "$.metadata.SmsMessageSid");

                        Optional<Intent> intenId = this.intentRepository.findIntenNameById(intent, agent.getAgenId());
                        if (!intenId.isPresent()) {
                            throw new Exception("Intent no esta presente");
                        }
                        try {
                            sender_id = (String) JsonUtils.getFieldFromJson(json, "$.sender_id");
                            log.info(sender_id);
                        } catch (Exception e) {
                            log.info(e.getMessage());
                            sender_id = (String) JsonUtils.getFieldFromJson(json, "$.metadata.sender_id");
                        }

                        List<DeleteDataSensRegistryBean> deleteSensibleBean = new ArrayList<>();

                        try {
                            deleteSensibleBean = service.deleteMessage(agent.getAgenId()
                                    , SmSMessageSid, intenId.get().getId(), sender_id);
                            update_control = true;
                        } catch (NotFoundException e) {
                            update_control = true;
                        } catch (Exception e) {
                            update_control = false;
                        }
                        for (DeleteDataSensRegistryBean registry : deleteSensibleBean) {
                            DeleteDataSensibleLog reg = new DeleteDataSensibleLog();
                            reg.setIntenId(registry.getInten_id());
                            reg.setMessageId(registry.getMessage_sid());
                            reg.setMultimediaId(registry.getMultimedia_sid());
                            reg.setSendId(registry.getSender_id());
                            reg.setDate(Timestamp.valueOf(presentDate));
                            deleteDataSensibleLogRepository.save(reg);
                        }
                    }
                }
            } else {
                update_control = true;
            }
            DeleteDataSensibleControl control = new DeleteDataSensibleControl();
            Optional<DeleteDataSensibleControl> controlBd = deleteDataSensibleControlRepository.findEventIdByAgentId(agent.getAgenId());
            if (update_control) {
                if (controlBd.isPresent()) {
                    // Update
                    control.setId(controlBd.get().getId());
                    control.setAgentId(agent.getAgenId());
                    control.setEventId(id);
                    control.setDate(Timestamp.valueOf(presentDate));
                    deleteDataSensibleControlRepository.save(control);
                } else {
                    // Create
                    control.setAgentId(agent.getAgenId());
                    control.setEventId(id);
                    control.setDate(Timestamp.valueOf(presentDate));
                    deleteDataSensibleControlRepository.save(control);
                }
            }
        }
    }

    private List<String> numbersAgent(List<Map> listNumber){
        List<String> result = new ArrayList<>();
        for (Map map : listNumber){
            String cod = (String) map.get("codigoInternacional");
            String number = (String) map.get("numero");
            String agent = "+" + cod + number;
            result.add(agent);
        }
        return result;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        String tenantId = stepExecution.getJobParameters().getString("tenantId");
        ThreadLocalStorage.setTenantName(tenantId);
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        return stepExecution.getExitStatus();
    }
}
