package com.ffii.fhsmsc.modules.common.mail.pojo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;

public class MailRequest {
  public final static int PRIORITY_HIGHEST = 1;
  public final static int PRIORITY_HIGH = 2;
  public final static int PRIORITY_NORMAL = 3;
  public final static int PRIORITY_LOW = 4;
  public final static int PRIORITY_LOWEST = 5;

  private InternetAddress from;
  private List<InternetAddress> to;

  private String subject;

  private String template;
  private String templateContent;
  private Map<String, ?> args;

  private Integer priority;

  private InternetAddress replyTo;
  private List<InternetAddress> cc;
  private List<InternetAddress> bcc;

  private Map<String, byte[]> attachments;

  public MailRequest() {
  }

  public static Builder builder() {
    return new Builder();
  }

  public void addAttachment(String attachmentFilename, byte[] byteArray) {
    if (this.attachments == null) this.attachments = new HashMap<>();
    this.attachments.put(attachmentFilename, byteArray);
  }

  public void addTo(InternetAddress to) {
    if (this.to == null) this.to = new ArrayList<>();
    this.to.add(to);
  }

  public void addCc(InternetAddress cc) {
    if (this.cc == null) this.cc = new ArrayList<>();
    this.cc.add(cc);
  }

  public void addBcc(InternetAddress bcc) {
    if (this.bcc == null) this.bcc = new ArrayList<>();
    this.bcc.add(bcc);
  }

  // getter setter

  public InternetAddress getFrom() {
    return from;
  }

  public void setFrom(InternetAddress from) {
    this.from = from;
  }

  public List<InternetAddress> getTo() {
    return to;
  }

  public void setTo(List<InternetAddress> to) {
    this.to = to;
  }

  public void setTo(String[] to) throws AddressException {
    if (to == null) {
      this.to = null;
    } else {
      for (String a : to) {
        this.addTo(new InternetAddress(a));
      }
    }
  }

  public void setStringListTo(List<String> to) throws AddressException {
    if (to == null) {
      this.to = null;
    } else {
      for (String a : to) {
        this.addTo(new InternetAddress(a));
      }
    }
  }

  public String getSubject() {
    return subject;
  }

  public void setSubject(String subject) {
    this.subject = subject;
  }

  public String getTemplate() {
    return template;
  }

  public void setTemplate(String template) {
    this.template = template;
  }

  public String getTemplateContent() {
    return this.templateContent;
  }

  public void setTemplateContent(String templateContent) {
    this.templateContent = templateContent;
  }

  public Map<String, ?> getArgs() {
    return args;
  }

  public void setArgs(Map<String, ?> args) {
    this.args = args;
  }

  public InternetAddress getReplyTo() {
    return replyTo;
  }

  public void setReplyTo(InternetAddress replyTo) {
    this.replyTo = replyTo;
  }

  public List<InternetAddress> getCc() {
    return cc;
  }

  public void setCc(List<InternetAddress> cc) {
    this.cc = cc;
  }

  public void setCc(String[] cc) throws AddressException {
    if (cc == null) {
      this.cc = null;
    } else {
      for (String a : cc) {
        this.addCc(new InternetAddress(a));
      }
    }
  }

  public void setStringListCc(List<String> cc) throws AddressException {
    if (cc == null) {
      this.cc = null;
    } else {
      for (String a : cc) {
        this.addCc(new InternetAddress(a));
      }
    }
  }

  public List<InternetAddress> getBcc() {
    return bcc;
  }

  public void setBcc(List<InternetAddress> bcc) {
    this.bcc = bcc;
  }

  public void setBcc(String[] bcc) throws AddressException {
    if (bcc == null) {
      this.bcc = null;
    } else {
      for (String a : bcc) {
        this.addBcc(new InternetAddress(a));
      }
    }
  }

  public void setStringListBcc(List<String> bcc) throws AddressException {
    if (bcc == null) {
      this.bcc = null;
    } else {
      for (String a : bcc) {
        this.addBcc(new InternetAddress(a));
      }
    }
  }

  public Map<String, byte[]> getAttachments() {
    return attachments;
  }

  public void setAttachments(Map<String, byte[]> attachments) {
    this.attachments = attachments;
  }

  public Integer getPriority() {
    return priority;
  }

  public void setPriority(Integer priority) {
    this.priority = priority;
  }

  // classes

  public static class Builder {
    private MailRequest mailRequest;

    private Builder() {
      this.mailRequest = new MailRequest();
    }

    public MailRequest build() {
      return this.mailRequest;
    }

    public Builder addAttachment(String attachmentFilename, byte[] byteArray) {
      this.mailRequest.addAttachment(attachmentFilename, byteArray);
      return this;
    }

    public Builder addTo(InternetAddress to) {
      this.mailRequest.addTo(to);
      return this;
    }

    public Builder addCc(InternetAddress cc) {
      this.mailRequest.addCc(cc);
      return this;
    }

    public Builder addBcc(InternetAddress bcc) {
      this.mailRequest.addBcc(bcc);
      return this;
    }

    public Builder from(InternetAddress from) {
      this.mailRequest.setFrom(from);
      return this;
    }

    public Builder to(List<InternetAddress> to) {
      this.mailRequest.setTo(to);
      return this;
    }

    public Builder to(String[] to) throws AddressException {
      if (to == null) {
        this.mailRequest.setTo((List<InternetAddress>) null);
      } else {
        for (String a : to) {
          this.addTo(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder stringListTo(List<String> to) throws AddressException {
      if (to == null) {
        this.mailRequest.setTo((List<InternetAddress>) null);
      } else {
        for (String a : to) {
          this.addTo(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder subject(String subject) {
      this.mailRequest.setSubject(subject);
      return this;
    }

    public Builder template(String template) {
      this.mailRequest.setTemplate(template);
      return this;
    }

    public Builder templateContent(String templateContent) {
      this.mailRequest.setTemplateContent(templateContent);
      return this;
    }

    public Builder args(Map<String, ?> args) {
      this.mailRequest.setArgs(args);
      return this;
    }

    public Builder replyTo(InternetAddress replyTo) {
      this.mailRequest.setReplyTo(replyTo);
      return this;
    }

    public Builder cc(List<InternetAddress> cc) {
      this.mailRequest.setCc(cc);
      return this;
    }

    public Builder cc(String[] cc) throws AddressException {
      if (cc == null) {
        this.mailRequest.setCc((List<InternetAddress>) null);
      } else {
        for (String a : cc) {
          this.addCc(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder stringListCc(List<String> cc) throws AddressException {
      if (cc == null) {
        this.mailRequest.setCc((List<InternetAddress>) null);
      } else {
        for (String a : cc) {
          this.addCc(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder bcc(List<InternetAddress> bcc) {
      this.mailRequest.setBcc(bcc);
      return this;
    }

    public Builder bcc(String[] bcc) throws AddressException {
      if (bcc == null) {
        this.mailRequest.setBcc((List<InternetAddress>) null);
      } else {
        for (String a : bcc) {
          this.addCc(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder stringListBcc(List<String> bcc) throws AddressException {
      if (bcc == null) {
        this.mailRequest.setBcc((List<InternetAddress>) null);
      } else {
        for (String a : bcc) {
          this.addCc(new InternetAddress(a));
        }
      }
      return this;
    }

    public Builder attachments(Map<String, byte[]> attachments) {
      this.mailRequest.setAttachments(attachments);
      return this;
    }

    public Builder priority(Integer priority) {
      this.mailRequest.setPriority(priority);
      return this;
    }
  }
}
