#!/usr/bin/env python3
"""
Download alle e-mails van een IMAP-account naar lokale .eml-bestanden.
Gebruik: python download_mailbox.py

Resultaat: mailbox/<mapnaam>/<id>.eml
Het script is herstart-safe: al gedownloade mails worden overgeslagen.
"""

import imaplib
import os
import re
import sys
import getpass
from pathlib import Path
from imap_utils import list_folders, quote_mailbox

IMAP_HOST = "australius.nl"
IMAP_PORT = 993
LOCAL_DIR = Path(__file__).parent / "mailbox"


def safe_path(name: str) -> str:
    """Zet mapnaam om naar een veilige directorynaam."""
    return re.sub(r'[<>:"/\\|?*\x00-\x1f]', "_", name)


def download():
    username = input("E-mailadres: ").strip()
    password = getpass.getpass("Wachtwoord: ")

    print(f"\nVerbinden met {IMAP_HOST}:{IMAP_PORT} ...")
    try:
        mail = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT)
        mail.login(username, password)
    except Exception as exc:
        print(f"Mislukt: {exc}")
        sys.exit(1)

    print("Ingelogd.\n")

    folders = list_folders(mail)
    if not folders:
        print("Kan mappenlijst niet ophalen.")
        sys.exit(1)

    print(f"Gevonden mappen ({len(folders)}):")
    for f in folders:
        print(f"  {f}")
    print()

    total_new = total_skip = total_err = 0
    num_folders = len(folders)

    for folder_idx, folder in enumerate(folders, 1):
        folder_prefix = f"[map {folder_idx}/{num_folders}] {folder}"

        status, data = mail.select(quote_mailbox(folder), readonly=True)
        if status != "OK":
            print(f"{folder_prefix}: kan niet openen – overgeslagen.")
            continue

        num = int(data[0])
        local_dir = LOCAL_DIR / safe_path(folder)
        local_dir.mkdir(parents=True, exist_ok=True)

        if num == 0:
            print(f"{folder_prefix}: leeg.")
            continue

        status, data = mail.search(None, "ALL")
        if status != "OK":
            print(f"{folder_prefix}: zoeken mislukt – overgeslagen.")
            continue

        ids = data[0].split()
        num_to_fetch = sum(1 for uid in ids if not (local_dir / f"{uid.decode()}.eml").exists())
        new = skip = err = 0

        for msg_idx, uid in enumerate(ids, 1):
            path = local_dir / f"{uid.decode()}.eml"
            if path.exists():
                skip += 1
                continue
            done = new + err + 1
            print(f"\r{folder_prefix}: bericht {done}/{num_to_fetch}  ", end="", flush=True)
            try:
                status, msg_data = mail.fetch(uid, "(RFC822)")
                if status == "OK" and msg_data and msg_data[0]:
                    path.write_bytes(msg_data[0][1])
                    new += 1
                else:
                    err += 1
            except Exception:
                err += 1

        total_new += new
        total_skip += skip
        total_err += err
        parts = [f"{new} nieuw", f"{skip} al aanwezig"]
        if err:
            parts.append(f"{err} fout")
        print(f"\r{folder_prefix}: " + ", ".join(parts) + "          ")

    mail.logout()
    print(f"\nKlaar. {total_new} gedownload, {total_skip} overgeslagen", end="")
    if total_err:
        print(f", {total_err} fouten", end="")
    print(f".\nOpgeslagen in: {LOCAL_DIR.resolve()}")


if __name__ == "__main__":
    LOCAL_DIR.mkdir(exist_ok=True)
    download()
