package ervu.dao.okopf;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import ervu.model.okopf.OkopfModel;
import ervu_lkrp_ul.ervu_lkrp_ul.db_beans.public_.tables.records.OkopfRecordsRecord;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import static ervu_lkrp_ul.ervu_lkrp_ul.db_beans.public_.Tables.OKOPF_RECORDS;


/**
 * @author Artyom Hackimullin
 */
@Repository
public class OkopfDaoImpl implements OkopfDao {

  @Autowired
  private DSLContext dsl;

  @Override
  @Transactional
  public void saveOrUpdate(List<OkopfModel> okopfModels) {
    deleteNotActualOkopfRecords(okopfModels);
    dsl.batchMerge(okopfModels.stream()
        .map(this::mapOkopfModelToRecord)
        .toList())
        .execute();
  }

  @Override
  public String fetchTitleByLeg(String leg) {
    return dsl.select(OKOPF_RECORDS.NAME)
        .from(OKOPF_RECORDS)
        .where(OKOPF_RECORDS.OKOPF_RECORDS_ID.eq(leg))
        .fetchOne(OKOPF_RECORDS.NAME);
  }

  private void deleteNotActualOkopfRecords(List<OkopfModel> recordModels) {
    Set<String> ids = recordModels
        .stream()
        .map(OkopfModel::getCode)
        .collect(Collectors.toSet());

    dsl.deleteFrom(OKOPF_RECORDS)
        .where(OKOPF_RECORDS.OKOPF_RECORDS_ID.notIn(ids))
        .execute();
  }

  private OkopfRecordsRecord mapOkopfModelToRecord(OkopfModel model) {
    OkopfRecordsRecord record = dsl.newRecord(OKOPF_RECORDS);
    record.setValue(OKOPF_RECORDS.OKOPF_RECORDS_ID, model.getCode());
    record.setValue(OKOPF_RECORDS.NAME, model.getName());
    record.setValue(OKOPF_RECORDS.VERSION, model.getVersion());
    return record;
  }
}
