/* Mail: das eigene Postfach lesen und beantworten, Mail → Vorgang oder Kanal.
   Jeder Aufruf ist ein Blick in das Postfach beim Anbieter - kein Abgleich,
   kein Hintergrundlauf, Zähler „Stand des letzten Öffnens“. */
"use strict";

S.mail = { konto: null, ordner: [], offen: "INBOX", liste: [], ungelesen: 0, gelesen: null,
           fehlt: false };
OHNE_PROJEKT.push("mail");
TITEL.mail = "Mail";
UNTERTITEL.mail = "Dein Postfach – Mails werden zu Vorgängen oder Nachrichten";

/* -- Daten ------------------------------------------------------------------ */
async function mailLaden() {
  S.mail.fehlt = false;
  try { S.mail.konto = await api("/api/mail/konto"); }
  catch (e) { S.mail.konto = null; S.mail.fehlt = true; return; }
  const [ordner, liste] = await Promise.all([
    api("/api/mail/ordner").catch(() => []),
    api(`/api/mail?ordner=${encodeURIComponent(S.mail.offen)}`)]);
  S.mail.ordner = ordner;
  S.mail.liste = liste.nachrichten;
  S.mail.ungelesen = liste.ungelesen;
  navZahl("mail", S.mail.ungelesen, `${S.mail.ungelesen} ungelesene Mail(s) (Stand des letzten Öffnens)`);
}

async function ordnerOeffnen(name) {
  S.mail.offen = name;
  S.mail.gelesen = null;
  try {
    const liste = await api(`/api/mail?ordner=${encodeURIComponent(name)}`);
    S.mail.liste = liste.nachrichten;
    S.mail.ungelesen = liste.ungelesen;
  } catch (e) { meldung(e.message, true); return; }
  zeichnen();
}

async function mailOeffnen(uid) {
  try {
    S.mail.gelesen = await api(`/api/mail/${uid}?ordner=${encodeURIComponent(S.mail.offen)}`);
    const zeile = S.mail.liste.find((m) => m.uid === uid);
    if (zeile && !zeile.gelesen) { zeile.gelesen = true; S.mail.ungelesen = Math.max(0, S.mail.ungelesen - 1); }
  } catch (e) { meldung(e.message, true); return; }
  navZahl("mail", S.mail.ungelesen, `${S.mail.ungelesen} ungelesene Mail(s)`);
  zeichnen();
}

/* -- Ansicht ---------------------------------------------------------------- */
function zeichneMail(ziel) {
  if (S.mail.fehlt) {
    const leer = el("div", "empty");
    leer.append(ico("envelope", "solid", "gross"), document.createTextNode(
      "Noch kein Postfach. In den Einstellungen unter „Postfach“ IMAP und SMTP deines "
      + "Anbieters eintragen – am besten mit einem App-Passwort."));
    const zu = knopf("btn btn--primary", "gear", "Zu den Einstellungen");
    zu.onclick = () => wechsle("einstellungen");
    leer.append(zu);
    ziel.append(leer);
    return;
  }
  const raster = el("div", "mail");
  const ordner = el("div", "mail__ordner");
  const neu = knopf("btn btn--primary", "pen", "Neue Mail");
  neu.style.width = "100%";
  neu.onclick = () => oeffneMailDialog(null);
  ordner.append(neu);
  (S.mail.ordner.length ? S.mail.ordner : [{ name: "INBOX", titel: "INBOX" }]).forEach((o) => {
    const z = el("div", "chat__kanal" + (o.name === S.mail.offen ? " is-active" : ""));
    z.append(ico(o.name === "INBOX" ? "inbox" : "folder"), el("span", "", o.titel));
    if (o.name === S.mail.offen && S.mail.ungelesen) z.append(el("span", "nav__zahl", String(S.mail.ungelesen)));
    z.onclick = () => ordnerOeffnen(o.name);
    ordner.append(bedienbar(z, o.titel));
  });
  raster.append(ordner);

  const liste = el("div", "mail__liste");
  if (!S.mail.liste.length) liste.append(el("div", "komm__leer", "Keine Mails in diesem Ordner."));
  S.mail.liste.forEach((m) => {
    const z = el("div", "mail__zeile" + (m.gelesen ? "" : " is-neu")
      + (S.mail.gelesen && S.mail.gelesen.uid === m.uid ? " is-active" : ""));
    z.append(el("div", "mail__betreff", m.betreff || "(ohne Betreff)"));
    const unten = el("div", "muted");
    unten.append(el("span", "", (m.von || "").replace(/<.*>/, "").trim() || m.von),
                 el("span", "", m.datum ? kurzDatum(m.datum.slice(0, 10)) : ""));
    z.append(unten);
    z.onclick = () => mailOeffnen(m.uid);
    liste.append(bedienbar(z, m.betreff));
  });
  if (S.mail.liste.length >= 30) {
    const mehr = knopf("btn btn--ghost", "angle-down", "Ältere laden");
    mehr.onclick = async () => {
      const aelteste = Math.min(...S.mail.liste.map((m) => m.uid));
      try {
        const r = await api(`/api/mail?ordner=${encodeURIComponent(S.mail.offen)}&vor=${aelteste}`);
        S.mail.liste = S.mail.liste.concat(r.nachrichten);
        zeichnen();
      } catch (e) { meldung(e.message, true); }
    };
    liste.append(mehr);
  }
  raster.append(liste);

  const lesen = el("div", "mail__lesen");
  const m = S.mail.gelesen;
  if (!m) {
    lesen.append(el("div", "empty", "Links eine Mail wählen."));
  } else {
    lesen.append(el("h3", "", m.betreff || "(ohne Betreff)"));
    lesen.append(el("div", "muted", `Von ${m.von} · an ${m.an} · ${m.datum ? new Date(m.datum).toLocaleString("de-DE") : ""}`));
    const kopf = el("div", "mail__kopf");
    kopf.style.marginTop = "8px";
    const antworten = knopf("btn", "reply", "Antworten");
    antworten.onclick = () => oeffneMailDialog(m);
    const vorgang = knopf("btn", "list-check", "→ Vorgang");
    vorgang.onclick = () => mailZuVorgang(m);
    const kanal = knopf("btn", "comments", "→ Kanal");
    kanal.onclick = () => mailZuKanal(m);
    kanal.hidden = !S.me.module.chat;
    const weg = knopf("btn btn--ghost", "trash", "Löschen");
    weg.onclick = async () => {
      if (!confirm("Mail als gelöscht markieren?")) return;
      try {
        await api(`/api/mail/${m.uid}?ordner=${encodeURIComponent(S.mail.offen)}`, { method: "DELETE" });
        S.mail.liste = S.mail.liste.filter((x) => x.uid !== m.uid);
        S.mail.gelesen = null;
        zeichnen();
      } catch (e) { meldung(e.message, true); }
    };
    kopf.append(antworten, vorgang, kanal, el("div", "spacer"), weg);
    lesen.append(kopf);
    if (m.anhaenge.length) {
      const anhang = el("div", "anhang");
      anhang.style.marginTop = "8px";
      m.anhaenge.forEach((a, i) => {
        const item = el("span", "anhang__item");
        const link = el("a", "", `${a.name} (${bytes(a.groesse)})`);
        link.href = `/api/mail/${m.uid}/anhang/${i}?ordner=${encodeURIComponent(S.mail.offen)}`;
        item.append(ico("paperclip"), link);
        anhang.append(item);
      });
      lesen.append(anhang);
    }
    lesen.append(el("pre", "mail__text", m.text || "(kein Text)"));
  }
  raster.append(lesen);
  ziel.append(raster);
}

/* -- Aktionen ---------------------------------------------------------------- */
async function mailZuVorgang(m) {
  const projekte = alleProjekte();
  if (!projekte.length) { meldung("Zuerst ein Projekt anlegen.", true); return; }
  const wahl = S.pid && projekte.some((p) => p.id === S.pid) ? S.pid
    : Number(prompt("In welches Projekt? Nummer eingeben:\n"
      + projekte.map((p) => `${p.id}: ${p.name}`).join("\n"), String(projekte[0].id)));
  if (!wahl || !projekte.some((p) => p.id === wahl)) return;
  try {
    const r = await jsonRuf(`/api/mail/${m.uid}/vorgang`, "POST", { project_id: wahl, ordner: S.mail.offen });
    meldung(`Vorgang ${r.key} angelegt${r.dokumente ? `, ${r.dokumente} Anhang/Anhänge als Dokumente` : ""}`
      + (r.nicht_uebernommen.length ? ` – zu groß: ${r.nicht_uebernommen.join(", ")}` : ""));
    await waehleProjekt(wahl);
    const t = S.daten && S.daten.tasks.find((x) => x.id === r.id);
    if (t) oeffneVorgang(t);
  } catch (e) { meldung(e.message, true); }
}

async function mailZuKanal(m) {
  let kanaele = (S.chat && S.chat.kanaele) || [];
  if (!kanaele.length) { try { kanaele = await api("/api/chat/kanaele"); } catch (e) { meldung(e.message, true); return; } }
  if (!kanaele.length) { meldung("Kein Kanal vorhanden.", true); return; }
  const wahl = Number(prompt("In welchen Kanal? Nummer eingeben:\n"
    + kanaele.map((k) => `${k.id}: ${k.name}`).join("\n"), String(kanaele[0].id)));
  if (!wahl || !kanaele.some((k) => k.id === wahl)) return;
  try {
    await jsonRuf(`/api/mail/${m.uid}/nachricht`, "POST", { kanal_id: wahl, ordner: S.mail.offen });
    meldung("Auszug im Kanal veröffentlicht");
  } catch (e) { meldung(e.message, true); }
}

let mailAntwortAuf = null;

function oeffneMailDialog(m) {
  mailAntwortAuf = m ? { message_id: m.message_id, references: m.references } : null;
  titelSetzen("#mail-titel", m ? "reply" : "envelope", m ? "Antworten" : "Neue Mail");
  $("#ml-an").value = m ? (m.von.match(/<([^>]+)>/) || [null, m.von])[1] : "";
  $("#ml-betreff").value = m ? (m.betreff.startsWith("Re:") ? m.betreff : "Re: " + m.betreff) : "";
  $("#ml-text").value = m ? "\n\n" + m.text.split("\n").map((z) => "> " + z).join("\n") : "";
  $("#dlg-mail").showModal();
  $("#ml-text").focus();
  $("#ml-text").setSelectionRange(0, 0);
}

document.addEventListener("DOMContentLoaded", () => {
  $("#dlg-mail form").onsubmit = async (e) => {
    e.preventDefault();
    try {
      await jsonRuf("/api/mail/senden", "POST", { an: $("#ml-an").value.trim(),
        betreff: $("#ml-betreff").value.trim(), text: $("#ml-text").value, antwort_auf: mailAntwortAuf });
      $("#dlg-mail").close();
      meldung("Mail gesendet");
    } catch (err) { meldung(err.message, true); }
  };
});

/* -- Einstellungen: Postfach ------------------------------------------------- */
document.addEventListener("einstellungen-gezeichnet", async (ev) => {
  if (!S.me.module.mail) return;
  let konto = null;
  try { konto = await api("/api/mail/konto"); } catch (e) { konto = null; }
  const karte = el("div", "karte");
  const kopf = kartenKopf("envelope", "Postfach");
  const pill = el("span", "pill pill--extern");
  pill.append(ico("cloud-arrow-up"), document.createTextNode(" sendet Daten nach außen"));
  pill.style.marginLeft = "8px";
  kopf.append(pill);
  karte.append(kopf, el("p", "muted", "Zugangsdaten und Mails gehen an deinen Anbieter. Bitte ein "
    + "App-Passwort verwenden, das sich einzeln zurückziehen lässt. Gmail nur mit App-Passwort, "
    + "Outlook.com geht nicht (kein IMAP-Passwort mehr)."));
  const form = el("form");
  const feld = (id, label, typ, wert) => {
    const l = el("label", "", label);
    l.htmlFor = id;
    const i = el("input");
    i.id = id; i.type = typ; i.value = wert === undefined || wert === null ? "" : wert;
    if (typ === "password") i.autocomplete = "new-password";
    form.append(l, i);
    return i;
  };
  const zeile = (a, b) => { const r = el("div", "row2"); r.append(a, b); form.append(r); return r; };
  const paar = (id1, l1, w1, id2, l2, w2, typ2 = "number") => {
    const a = el("div"), b = el("div");
    const la = el("label", "", l1); la.htmlFor = id1;
    const ia = el("input"); ia.id = id1; ia.type = "text"; ia.value = w1 || "";
    const lb = el("label", "", l2); lb.htmlFor = id2;
    const ib = el("input"); ib.id = id2; ib.type = typ2; ib.value = w2 === undefined ? "" : w2;
    a.append(la, ia); b.append(lb, ib); zeile(a, b);
    return [ia, ib];
  };
  const [imapHost, imapPort] = paar("mk-imap", "IMAP-Server", konto && konto.imap_host, "mk-imap-port", "Port", konto ? konto.imap_port : 993);
  const imapSsl = el("input"); imapSsl.type = "checkbox"; imapSsl.checked = konto ? konto.imap_ssl : true;
  const imapSslL = el("label"); imapSslL.append(imapSsl, document.createTextNode(" IMAP über TLS (aus = STARTTLS)")); form.append(imapSslL);
  const [smtpHost, smtpPort] = paar("mk-smtp", "SMTP-Server", konto && konto.smtp_host, "mk-smtp-port", "Port", konto ? konto.smtp_port : 587);
  const smtpSsl = el("input"); smtpSsl.type = "checkbox"; smtpSsl.checked = konto ? konto.smtp_ssl : false;
  const smtpSslL = el("label"); smtpSslL.append(smtpSsl, document.createTextNode(" SMTP über TLS (aus = STARTTLS)")); form.append(smtpSslL);
  const user = feld("mk-user", "Benutzername", "text", konto && konto.username);
  const pw = feld("mk-pw", "Passwort", "password", "");
  pw.placeholder = konto && konto.passwort_gesetzt ? "unverändert" : "";
  const adresse = feld("mk-adresse", "Absenderadresse", "email", konto ? konto.adresse : S.me.email);
  const signatur = feld("mk-signatur", "Signatur", "text", konto && konto.signatur);
  const digest = el("input"); digest.type = "checkbox"; digest.checked = Boolean(S.me.digest);
  digest.disabled = !S.me.smtp_plattform;
  const digestL = el("label");
  digestL.append(digest, document.createTextNode(" Tageszusammenfassung um 7 Uhr per Mail"
    + (S.me.smtp_plattform ? "" : " (kein Postausgang der Plattform eingerichtet: SMTP_URL)")));
  form.append(digestL);
  const speichern = knopf("btn btn--primary", "check", "Speichern (prüft die Verbindung)");
  speichern.type = "submit";
  speichern.style.marginTop = "14px";
  form.append(speichern);
  if (konto) {
    const weg = knopf("btn btn--ghost", "trash", "Postfach entfernen");
    weg.type = "button";
    weg.style.marginTop = "14px";
    weg.onclick = async () => {
      if (!confirm("Postfach aus Minerva entfernen? Beim Anbieter bleibt alles.")) return;
      try { await api("/api/mail/konto", { method: "DELETE" }); S.me = await api("/api/me"); zeichnen(); }
      catch (e) { meldung(e.message, true); }
    };
    form.append(document.createTextNode(" "), weg);
  }
  form.onsubmit = async (e) => {
    e.preventDefault();
    speichern.disabled = true;
    try {
      await api("/api/mail/konto", { method: "PUT", body: JSON.stringify({
        imap_host: imapHost.value.trim(), imap_port: Number(imapPort.value || 993), imap_ssl: imapSsl.checked,
        smtp_host: smtpHost.value.trim(), smtp_port: Number(smtpPort.value || 587), smtp_ssl: smtpSsl.checked,
        username: user.value.trim(), passwort: pw.value || null, adresse: adresse.value.trim(),
        signatur: signatur.value.trim(), digest: digest.checked }) });
      S.me = await api("/api/me");
      meldung("Postfach geprüft und gespeichert");
      zeichnen();
    } catch (err) { meldung(err.message, true); } finally { speichern.disabled = false; }
  };
  karte.append(form);
  ev.detail.ziel.append(karte);
});

/* -- Eintragen -------------------------------------------------------------- */
ZEICHNER.mail = zeichneMail;
LADER.mail = mailLaden;
