package ru.yandex.webmaster3.storage.digest;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import org.joda.time.LocalDate;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.storage.util.ydb.AbstractYDao;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.DataMapper;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Field;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Fields;

@Repository
public class DigestAcceptanceYDao extends AbstractYDao {
    private static final String TABLE_NAME = "digest_acceptance";

    public DigestAcceptanceYDao() {
        super(PREFIX_INTERNAL, TABLE_NAME);
    }

    public void insert(DigestAcceptance acceptance) {
        upsert(F.DIGEST_DATE.value(acceptance.getDigestDate()),
                F.SENT.value(acceptance.getSent()),
                F.APPROVE.value(acceptance.getApprove()))
                .execute();
    }

    public Optional<DigestAcceptance> getAcceptanceByDate(LocalDate localDate) {
        return Optional.ofNullable(
                select(MAPPER)
                        .where(F.DIGEST_DATE.eq(localDate))
                        .queryOne()
        );
    }

    public void markAsApproved(LocalDate localDate) {
        update()
            .with(F.APPROVE.set(true))
            .where(F.DIGEST_DATE.eq(localDate))
            .execute();
    }

    public void markAsSent(LocalDate localDate) {
        update()
            .with(F.SENT.set(true))
            .where(F.DIGEST_DATE.eq(localDate))
            .execute();
    }

    public List<DigestAcceptance> listAll() {
        List<DigestAcceptance> res = new LinkedList<>();
        foreachRequest(res::add);
        return res;
    }

    public void foreachRequest(Consumer<DigestAcceptance> cons) {
        streamReader(MAPPER, cons);
    }

    private static final DataMapper<DigestAcceptance> MAPPER = DataMapper.create(
            F.DIGEST_DATE, F.SENT, F.APPROVE, DigestAcceptance::new
    );

    private static class F {
        static final Field<LocalDate> DIGEST_DATE = Fields.jodaDateField("digest_date");
        static final Field<Boolean> SENT = Fields.boolField("sent");
        static final Field<Boolean> APPROVE = Fields.boolField("approve");
    }
}
