package ru.micord.ervu.account_applications.component.service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import dao.container.FormDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.micord.ervu.account_applications.component.dao.AuditDao;
import ru.micord.ervu.account_applications.db_beans.public_.tables.UserApplicationList;
import ru.micord.ervu.account_applications.security.context.SecurityContext;
import ru.micord.ervu.account_applications.security.model.UserSession;
import utils.DateTimeUtil;

import ru.cg.webbpm.modules.database.api.bean.TableFieldData;
import ru.cg.webbpm.modules.database.bean.entity_graph.EntityColumn;

import static ru.micord.ervu.account_applications.enums.ApplicationStatus.CREATED;
import static ru.micord.ervu.account_applications.enums.ApplicationStatus.SENT;

/**
 * @author Eduard Tihomirov
 */
@Service
public class AuditFormDaoImpl extends FormDaoImpl {

  @Autowired
  private SecurityContext securityContext;
  @Autowired
  private AuditDao auditDao;

  @Override
  public List<TableFieldData> save(Map<EntityColumn, Object> map) {
    List<TableFieldData> tableFieldData = super.save(map);
    UserSession userSession = securityContext.getUserSession();
    Optional<String> status = map.entrySet().stream()
        .filter(entry -> entry.getKey().getName().equals("application_status"))
        .map(entry -> entry.getValue().toString())
        .findAny();

    Optional<Long> appListId = tableFieldData.stream()
        .filter(data -> data.getField().getName().equals("user_application_list_id"))
        .map(data -> (Long) data.getData())
        .findAny();

    if (status.isPresent() && appListId.isPresent() && !status.get().equals(SENT.name())) {
      Timestamp timestamp = status.get().equals(CREATED.name())
                            ? getStartDateByApplicationListId(appListId.get())
                            : Timestamp.valueOf(DateTimeUtil.dateToLocalDateTimeUtc(new Date()));

      auditDao.insert(appListId.get(), userSession.name(), userSession.userId(), status.get(), timestamp);
    }
    return tableFieldData;
  }

  private Timestamp getStartDateByApplicationListId(Long appListId) {
    return getDsl()
        .select(UserApplicationList.USER_APPLICATION_LIST.START_DATE)
        .from(UserApplicationList.USER_APPLICATION_LIST)
        .where(UserApplicationList.USER_APPLICATION_LIST.USER_APPLICATION_LIST_ID.eq(appListId))
        .fetchOne(UserApplicationList.USER_APPLICATION_LIST.START_DATE);
  }
}
