import sys
from config import DSN, MAILBOX
from model import StatusMeldung

from datetime import date, time, timedelta
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from imap_tools import MailBox, AND, MailMessage
import json


class MailImport:
    def open_mailbox(self) -> MailBox:
        return MailBox(MAILBOX["server"]).login(MAILBOX["user"], MAILBOX["password"], MAILBOX["folder"])

    def mail_import(self) -> int:
        with (
            Session(create_engine(DSN)) as db_session,
            self.open_mailbox() as mb,
        ):
            messages = mb.fetch(criteria=AND(seen=False), mark_seen=True, limit=500)
            imported = []

            for msg in messages:
                status = self.get_status_message(msg)
                if status is None:
                    mb.move([msg.uid], "Unbekannt")
                    continue

                db_session.add(status)
                try:
                    db_session.commit()
                    imported.append(msg.uid)
                except IntegrityError as e:
                    db_session.rollback()
                    print(e.args[0])

            mb.delete(imported)
            return len(imported)

    def get_status_message(self, msg: MailMessage) -> StatusMeldung:
        subject = msg.subject.split(";")
        attachments = dict([(att.filename, att.payload) for att in msg.attachments if att.size > 0])
        fehlerbericht_json = json.loads(attachments.get("fehlerbericht.json", "[]"))
        fehlerbericht_import = json.dumps(fehlerbericht_json)

        if len(subject) < 5 or len(attachments) == 0 or len(fehlerbericht_json) == 0:
            print(msg.subject)
            return None

        aufgabe = ""
        if len(subject) > 5:
            if subject[5][-4:] == ".bat":
                aufgabe = subject[5]
            elif ":" in subject[5]:
                aufgabe = "manuell"
        if ":" not in subject[1]:
            aufgabe = subject[1]
            subject[1] = "00:00"
        if aufgabe == "":
            files = [f["Name"] for f in fehlerbericht_json if ".bat" in f["Name"]]
            if len(files) > 0:
                aufgabe = files[0]

        return StatusMeldung(
            datum=date.fromisoformat(subject[3]),
            kunde=subject[0],
            aufgabe=aufgabe,
            start=time.fromisoformat(subject[1]),
            ende=time.fromisoformat(subject[2]),
            fehlerbericht_import=fehlerbericht_import,
            anzahl=int(subject[4]),
        )

    def cleanup(self):
        date_criteria = date.today() - timedelta(days=7)

        with self.open_mailbox() as mb:
            messages = mb.fetch(
                criteria=AND(date_lt=date_criteria, seen=True),
                limit=500,
            )
            selected = [msg.uid for msg in messages]
            mb.delete(selected)


def mail_import():
    mi = MailImport()
    res = mi.mail_import()
    mi.cleanup()
    return res


if __name__ == "__main__":
    if mail_import() == 0:
        sys.exit(1)