package eu.mulk.mulkcms2.benki.newsletter;

import static java.util.stream.Collectors.partitioningBy;
import static java.util.stream.Collectors.toList;

import eu.mulk.mulkcms2.benki.bookmarks.Bookmark;
import eu.mulk.mulkcms2.benki.lazychat.LazychatMessage;
import eu.mulk.mulkcms2.benki.posts.Post;
import io.quarkus.mailer.MailTemplate.MailTemplateInstance;
import io.quarkus.panache.common.Sort;
import io.quarkus.qute.CheckedTemplate;
import io.quarkus.qute.TemplateExtension;
import io.quarkus.scheduler.Scheduled;
import jakarta.enterprise.context.Dependent;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.CheckForNull;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.hibernate.Session;

@Dependent
public class NewsletterSender {

  private static final DateTimeFormatter humanDateFormatter =
      DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);

  @ConfigProperty(name = "mulkcms.newsletter.time-zone")
  ZoneId newsletterTimeZone;

  @ConfigProperty(name = "quarkus.mailer.from")
  String senderAddress;

  @PersistenceContext EntityManager em;

  @CheckedTemplate
  static class Templates {
    public static native MailTemplateInstance newsletter(
        Newsletter newsletter, List<Bookmark> bookmarks, List<LazychatMessage> lazychatMessages);
  }

  @Scheduled(cron = "0 0 0 ? * Mon")
  @Transactional
  void run() throws InterruptedException, TimeoutException, ExecutionException {
    var session = em.unwrap(Session.class);

    List<Post> posts =
        Post.find(
                """
                SELECT DISTINCT p FROM Post p
                  JOIN p.targets r
                  JOIN r.tags tag
                 WHERE p.newsletter IS NULL
                   AND p.scope = 'top_level'
                   AND tag = 'world'
                """,
                Sort.ascending("date"))
            .list();
    Post.fetchTexts(posts);

    if (posts.isEmpty()) {
      return;
    }

    var postsByClass = posts.stream().collect(partitioningBy(Post::isBookmark));
    var bookmarks =
        postsByClass.getOrDefault(Boolean.TRUE, List.of()).stream()
            .map(x -> (Bookmark) x)
            .collect(toList());
    var lazychatMessages =
        postsByClass.getOrDefault(Boolean.FALSE, List.of()).stream()
            .map(x -> (LazychatMessage) x)
            .collect(toList());

    var date = OffsetDateTime.now(newsletterTimeZone);
    var newsletterNumber =
        (int)
            session
                .createQuery("SELECT max(id) FROM Newsletter", Integer.class)
                .uniqueResultOptional()
                .map(x -> x + 1)
                .orElse(1);

    var newsletter = new Newsletter();
    newsletter.id = newsletterNumber;
    newsletter.date = date;
    newsletter.persist();

    posts.forEach(post -> post.newsletter = newsletter);

    var subscriberEmails =
        NewsletterSubscription.<NewsletterSubscription>stream("registrationKey IS NULL")
            .map(x -> x.email)
            .toArray(String[]::new);

    var mailText = Templates.newsletter(newsletter, bookmarks, lazychatMessages);
    var sendJob =
        mailText
            .subject(String.format("MulkCMS newsletter #%d", newsletterNumber))
            .to(senderAddress)
            .bcc(subscriberEmails)
            .send();
    sendJob.subscribe().asCompletionStage().get(10000, TimeUnit.SECONDS);
  }

  @TemplateExtension
  @CheckForNull
  static String humanDate(@CheckForNull LocalDate x) {
    if (x == null) {
      return null;
    }
    return humanDateFormatter.format(x);
  }

  @TemplateExtension
  @CheckForNull
  static String humanDate(@CheckForNull OffsetDateTime x) {
    if (x == null) {
      return null;
    }
    return humanDateFormatter.format(x);
  }
}
