import html
from datetime import date, timedelta

import models
# 2026-10-04: az SMTP-adatokat (szerver, port, felhasználó, jelszó) már nem közvetlenül a config.py-ból
# (.env) olvassuk, hanem az email_beallitasok modulon át - az a rendszeradmin által a felületen
# beállított (adatbázisban, a jelszó titkosítva tárolt) értéket használja, és csak ennek hiányában
# esik vissza a .env-re. Az SMTP-kapcsolat felépítése (időtúllépés, TLS) is ott, egy helyen él.
#
# 2026-10-04 (B szelet): a levelek már NEM innen mennek ki azonnal - ez a modul csak összeállítja a
# levél tartalmát, és az email_sor modulon át a kimenő SORBA teszi. A tényleges küldést (sebesség-
# korláttal, újrapróbálással) az email_sor.kiurites() végzi percenként. Az ismétlődő hibák szűrése
# (első alkalommal levél, majd csak X nap után újra) szintén az email_sor-ban van.
import email_sor
import email_feliratkozas
from database import SessionLocal
from msz_constants import compute_vizsgalati_esedekesseg, get_vizsgalati_datum_kotelezo_mod
from berles_utils import berelt_gep_idk_a_ceghez
import email_beallitasok


def _e(ertek) -> str:
    """HTML-escape a levél TÖRZSÉBE kerülő, felhasználótól/adminisztrátortól származó szövegekhez
    (gépnév, gyári szám, felhasználónév, hibaleírás, cégnév stb.). Korábban ezek szűrés nélkül
    kerültek a HTML-be, így pl. egy gépnévbe írt <a href=...> a rendszeradminnak/ügyintézőnek küldött
    levélben megjelent volna (tartalom-injekció / adathalász-link). A fejlécekbe kerülő értékekhez
    továbbra is a _fejresor_biztonsagos() kell (CR/LF ellen) - a kettő más védelem."""
    return html.escape("" if ertek is None else str(ertek), quote=True)


def _fejresor_biztonsagos(ertek: str) -> str:
    """CRLF-injekció elleni védelem (2026-10-03-i biztonsági audit, 4. fázis): egy e-mail
    FEJLÉC-mezőbe (Subject/From/To) kerülő érték nem tartalmazhat CR/LF karaktert - ha
    tartalmazna, további fejléc-sorokat (pl. egy álcázott Bcc:) lehetne becsempészni. A
    gépnév, cégnév és e-mail cím mezők felhasználói/admin adatbevitelből származnak, ezért
    minden fejlécbe (nem a levél TÖRZSÉBE) kerülő értéket ezen át kell engedni."""
    return str(ertek).replace("\r", "").replace("\n", "")


def send_alert_email_task(cimek: list, gep_adatok: dict, hiba_leiras: str, is_critical: bool, bejelento: str):
    """Gép-riasztás levél összeállítása és SORBA állítása (a tényleges küldést az email_sor végzi).

    gep_adatok: nev, gyari_szam, tipus - és (2026-10-04-től) a hívók által megadott `gep_id` és
    `company_id`, amelyekkel az ismétlődő hibák szűrése azonosítja a gépet. Ha hiányoznak, a
    szűrés a gép nevére/gyári számára esik vissza.

    ISMÉTLŐDŐ HIBÁK: ugyanarról a hibáról (azonos gép + súlyosság + hibaszöveg) csak az első
    alkalommal megy levél, és csak `email_ismetles_nap` (alapból 7) nap után emlékeztetünk újra.
    A hibajegy lezárása nullázza a számlálót (l. email_sor.riasztas_allapot_torlese)."""
    cimek = email_sor.cimek_tisztitasa(cimek)  # érvénytelen/duplikált címek ki - nincs címzett, nincs teendő
    if not cimek:
        return

    # Tárgy és szín beállítása a súlyosságtól függően
    if is_critical:
        targy = f"🚨 KRITIKUS RIASZTÁS: Gép letiltva - {_fejresor_biztonsagos(gep_adatok['nev'])}"
        szin = "#dc3545"  # Piros
        stausz_szoveg = "A GÉP HASZNÁLATÁT AZONNALI HATÁLLYAL BETILTOTTÁK!"
    else:
        targy = f"⚠️ FIGYELMEZTETÉS: Hibajegy nyitva - {_fejresor_biztonsagos(gep_adatok['nev'])}"
        szin = "#ffc107"  # Sárga
        stausz_szoveg = "A gép üzemel, de karbantartói beavatkozást igényel."

    # A levél HTML kinézete (Profi, modern dizájn - beágyazva a Pythonba).
    # FONTOS: a felhasználótól származó mezők _e()-vel (html.escape) kerülnek a törzsbe.
    html_tartalom = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
                <div style="background-color: {szin}; color: {'#ffffff' if is_critical else '#000000'}; padding: 20px; text-align: center;">
                    <h2 style="margin: 0;">EmeLOG Ipar 4.0 - Automatikus Riasztás</h2>
                </div>
                <div style="padding: 20px;">
                    <h3 style="color: #333333; border-bottom: 2px solid #eeeeee; padding-bottom: 10px;">Érintett Emelőgép / Eszköz</h3>
                    <p><strong>Név:</strong> {_e(gep_adatok['nev'])}</p>
                    <p><strong>Gyári szám:</strong> {_e(gep_adatok['gyari_szam'])}</p>
                    <p><strong>Típus:</strong> {_e(gep_adatok['tipus'])}</p>

                    <h3 style="color: #333333; border-bottom: 2px solid #eeeeee; padding-bottom: 10px; margin-top: 30px;">Hiba részletei</h3>
                    <p><strong>Bejelentő:</strong> {_e(bejelento)}</p>
                    <p style="color: {szin}; font-weight: bold;">{stausz_szoveg}</p>
                    <div style="background-color: #f8f9fa; padding: 15px; border-left: 4px solid {szin}; margin-top: 10px;">
                        <pre style="margin: 0; white-space: pre-wrap; font-family: inherit;">{_e(hiba_leiras)}</pre>
                    </div>
                </div>
                <div style="background-color: #eeeeee; text-align: center; padding: 15px; font-size: 12px; color: #666666;">
                    Ezt a levelet az EmeLOG szoftver generálta automatikusan. Kérjük, ne válaszolj rá!
                </div>
            </div>
        </body>
    </html>
    """

    gep_id = gep_adatok.get("gep_id")
    company_id = gep_adatok.get("company_id")
    azonosito = gep_id if gep_id is not None else f"n:{gep_adatok.get('nev')}|{gep_adatok.get('gyari_szam')}"
    kulcs = email_sor.riasztas_kulcs(azonosito, is_critical, hiba_leiras)

    db = SessionLocal()
    try:
        korlat = email_sor.korlatok_betolt(db)
        if not email_sor.kikuldheto_e_es_rogzit(db, kulcs, company_id, korlat.ismetles_nap, date.today()):
            db.rollback()
            print(f"ℹ️ Ismétlődő riasztás - nem küldjük újra {korlat.ismetles_nap} napon belül: {gep_adatok['nev']}")
            return
        db_sor = email_sor.sorba_allit(
            cimek, targy, html_tartalom, kategoria="riasztas",
            prioritas=email_sor.PRIORITAS_SURGOS if is_critical else email_sor.PRIORITAS_NORMAL,
            company_id=company_id, db=db, dedup_kulcs=kulcs,
        )
        if db_sor == 0:
            db.rollback()  # nincs érvényes címzett - az ismétlés-szűrés állapotát sem rögzítjük
            return
        db.commit()
        print(f"📬 Riasztás sorba állítva: {db_sor} címzett.")
    except Exception as e:
        db.rollback()
        print(f"❌ Hiba a riasztás sorba állításakor: {type(e).__name__}: {e}")
    finally:
        db.close()


def send_summary_email_task(cimek: list, ceg_nev: str, lejart: list, hamarosan: list,
                            elnyomott: int = 0, ismetles_nap: int = 7, company_id=None, db=None):
    """A reggeli összesítő riport (HTML e-mail) összeállítása és SORBA állítása.

    lejart / hamarosan: kész HTML-tételek (a változó részek már escape-eltek).
    elnyomott: hány, korábban már jelzett és még fennálló tételt hagytunk ki ebből a levélből
    (a levél láblécében jelezzük, hogy ne tűnjön úgy, mintha megoldódtak volna).
    db: ha megadva, a sorba állítás ebben a session-ben történik és NEM commitolunk (a hívó
    commitol, az ismétlés-szűrés állapotával együtt egy tranzakcióban)."""
    if not cimek:
        return 0

    targy = f"📅 Napi EmeLOG Riport - {_fejresor_biztonsagos(ceg_nev)}"

    # Az alkalmazás nyilvános URL-je (a levélben lévő "Belépés" gombhoz)
    beall = email_beallitasok.betolt(db)

    # HTML táblázatok generálása a listákból
    lejart_html = ""
    if lejart:
        lejart_html = "<h3 style='color:#dc3545; border-bottom:2px solid #dc3545;'>🚨 Lejárt határidők (Azonnali teendő!)</h3><ul>"
        for item in lejart:
            lejart_html += f"<li style='margin-bottom:8px;'>{item}</li>"
        lejart_html += "</ul>"

    hamarosan_html = ""
    if hamarosan:
        hamarosan_html = "<h3 style='color:#ffc107; border-bottom:2px solid #ffc107;'>⚠️ Közeledő határidők (30 napon belül)</h3><ul>"
        for item in hamarosan:
            hamarosan_html += f"<li style='margin-bottom:8px;'>{item}</li>"
        hamarosan_html += "</ul>"

    # Ha minden rendben van (és nem azért üres a lista, mert az ismétlődő tételeket kihagytuk),
    # küldünk egy megnyugtató üzenetet is
    if not lejart and not hamarosan and not elnyomott:
        lejart_html = "<h3 style='color:#198754;'><br>✅ Minden rendben! Jelenleg nincs lejárt vagy 30 napon belül lejáró vizsgálat és HR dokumentum.</h3>"

    elnyomott_html = ""
    if elnyomott:
        elnyomott_html = (
            f"<p style='color:#666666; font-size:13px; margin-top:20px;'>ℹ️ További <b>{int(elnyomott)}</b> korábban már jelzett, "
            f"még fennálló tétel nem szerepel ebben a levélben - ezeket {int(ismetles_nap)} naponta ismételjük meg, "
            f"amíg a hiba fennáll.</p>"
        )

    html_tartalom = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f8f9fa; padding: 20px;">
            <div style="max-width: 650px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); overflow: hidden;">
                <div style="background-color: #0dcaf0; color: #000000; padding: 20px; text-align: center;">
                    <h2 style="margin: 0;">EmeLOG Ipar 4.0 - EHS Riport</h2>
                    <p style="margin: 5px 0 0 0; font-weight: bold;">{_e(ceg_nev)}</p>
                </div>
                <div style="padding: 20px 30px;">
                    <p>Kedves EHS Vezető / Admin!</p>
                    <p>Íme a legfrissebb gépészeti és személyi (HR) érvényességi összesítő a rendszerből:</p>

                    {lejart_html}
                    {hamarosan_html}
                    {elnyomott_html}

                    <p style="margin-top: 30px; text-align: center;">
                        <a href="{_e(beall.alkalmazas_url_vagy_alap)}" style="background-color: #0dcaf0; color: #000; padding: 10px 20px; text-decoration: none; border-radius: 5px; font-weight: bold;">Belépés a Vezérlőpultra</a>
                    </p>
                </div>
                <div style="background-color: #eeeeee; text-align: center; padding: 15px; font-size: 12px; color: #666666;">
                    Ezt a levelet az EmeLOG szoftver generálta automatikusan. Kérjük, ne válaszolj rá!
                </div>
            </div>
        </body>
    </html>
    """

    return email_sor.sorba_allit(
        cimek, targy, html_tartalom, kategoria="napi_riport",
        prioritas=email_sor.PRIORITAS_ALACSONY, company_id=company_id, db=db,
    )


def napi_riport_lekerdezes_es_kuldes(teszt: bool = False):
    """Ez a függvény fut le minden reggel, és átnézi a teljes adatbázist.

    ISMÉTLŐDŐ HIBÁK (2026-10-04): egy tétel (pl. egy gép lejárt vizsgálata) csak az első alkalommal
    kerül a riportba, utána `email_ismetles_nap` (alapból 7) napig kimarad, majd emlékeztetőként
    újra megjelenik, ha még fennáll. Ha egy cégnél csak ismétlődő tétel van, nem megy levél; ha
    egyáltalán nincs tétel, a megszokott "Minden rendben" levél megy.

    teszt=True (a /teszt-riport kézi indításnál): MINDEN tétel bekerül, és az ismétlés-szűrés
    állapotát nem olvassuk és nem módosítjuk - a teszt ne zavarja össze a valódi működést."""
    db = SessionLocal()
    try:
        mai_nap = date.today()
        figyelmezteto_hatar = mai_nap + timedelta(days=30)
        is_monday = (mai_nap.weekday() == 0)  # Hétfő = 0
        korlat = email_sor.korlatok_betolt(db)

        tipus_cimke = {
            "Szerkezeti vizsgálat": "Szerkezeti vizsg",
            "Fővizsgálat": "Fővizsgálat",
            "Időszakos biztonsági felülvizsgálat (EBSZ)": "Biztonsági felülvizsg",
        }
        config_cache = {}
        kotelezo_mod_cache = {}

        def get_config(company_id, geptipus):
            key = (company_id, geptipus)
            if key not in config_cache:
                config_cache[key] = db.query(models.MachineTypeConfig).filter(
                    models.MachineTypeConfig.company_id == company_id,
                    models.MachineTypeConfig.geptipus == geptipus
                ).first()
            return config_cache[key]

        def get_kotelezo_mod(company_id):
            if company_id not in kotelezo_mod_cache:
                kotelezo_mod_cache[company_id] = get_vizsgalati_datum_kotelezo_mod(company_id, db)
            return kotelezo_mod_cache[company_id]

        cegek = db.query(models.Company).filter(models.Company.aktiv == True).all()
        for ceg in cegek:
            try:
                _ceg_riport(db, ceg, mai_nap, figyelmezteto_hatar, is_monday, korlat, teszt,
                            tipus_cimke, get_config, get_kotelezo_mod)
            except Exception as e:
                # Egy cég hibája ne akadályozza a többi cég riportját
                db.rollback()
                print(f"❌ Hiba a napi riport generálása közben (cég #{ceg.id}): {type(e).__name__}: {e}")

    except Exception as e:
        db.rollback()
        print(f"❌ Hiba a napi riport generálása közben: {str(e)}")
    finally:
        db.close()


def _ceg_riport(db, ceg, mai_nap, figyelmezteto_hatar, is_monday, korlat, teszt,
                tipus_cimke, get_config, get_kotelezo_mod):
    """Egy cég napi riportja: tételek gyűjtése -> ismétlés-szűrés -> sorba állítás (egy tranzakció)."""
    beallitas = db.query(models.Dictionary).filter(
        models.Dictionary.company_id == ceg.id,
        models.Dictionary.kategoria == "EmailRiportGyakorisag"
    ).first()
    gyak = beallitas.ertek if beallitas else "Kikapcsolva"

    # Ha ki van kapcsolva, vagy hétfői a beállítás de ma nem hétfő van, ugorjuk át
    if gyak == "Kikapcsolva":
        return
    if gyak == "Heti" and not is_monday:
        return

    # Tételek: (stabil kulcs, kész html) - a kulcs azonosítja a hibát az ismétlés-szűréshez.
    # A kulcsba a hiba ÁLLAPOTA ("lejart"/"hamarosan") és az utolsó vizsgálat/lejárat dátuma is beleszámít:
    # ha egy vizsgálat "hamarosan"-ból "lejárt"-ra vált, vagy új vizsgálat történik, az új információ -> új levél.
    lejart_lista = []
    hamarosan_lista = []

    # 1. GÉPEK ELLENŐRZÉSE (Egyszerűsített dátumellenőrzés) - a saját gépek mellett
    # az aktív bérlettel a céghez kihelyezett (más cég tulajdonában lévő) gépek is bekerülnek.
    berelt_gep_idk = berelt_gep_idk_a_ceghez(ceg.id, db)
    gepek_query = db.query(models.Machine).filter(models.Machine.statusz == "Aktív")
    if berelt_gep_idk:
        gepek_query = gepek_query.filter(
            (models.Machine.company_id == ceg.id) | (models.Machine.id.in_(berelt_gep_idk))
        )
    else:
        gepek_query = gepek_query.filter(models.Machine.company_id == ceg.id)
    gepek = gepek_query.all()

    for gep in gepek:
        gep_nev = f"GÉP: {_e(gep.megnevezes)} ({_e(gep.gyari_szam)})"

        # Műszaki vizsga (Közúti forgalom)
        if gep.kozuti_forgalom and gep.kozuti_vizsga_datum:
            if gep.kozuti_vizsga_datum < mai_nap:
                lejart_lista.append((f"gep:{gep.id}:kozuti:lejart:{gep.kozuti_vizsga_datum}",
                                     f"<b>{gep_nev}</b> - Lejárt Műszaki vizsga: {gep.kozuti_vizsga_datum}"))
            elif gep.kozuti_vizsga_datum <= figyelmezteto_hatar:
                hamarosan_lista.append((f"gep:{gep.id}:kozuti:hamarosan:{gep.kozuti_vizsga_datum}",
                                        f"<b>{gep_nev}</b> - Lejáró Műszaki vizsga: {gep.kozuti_vizsga_datum}"))

        # --- SZIGORÚ DÁTUM ELLENŐRZÉS AZ E-MAILBEN IS --- a naptár/PDF-fel közös
        # MSZ 9750 / EBSZ esedékesség-számítással (hónap ÉS üzemóra alapján, amelyik
        # előbb bekövetkezik - l. compute_vizsgalati_esedekesseg).
        config = get_config(gep.company_id, gep.geptipus)
        datum_kotelezo_mod = get_kotelezo_mod(gep.company_id)
        for e in compute_vizsgalati_esedekesseg(gep, mai_nap, config, datum_kotelezo_mod):
            cimke = _e(tipus_cimke.get(e["tipus"], e["tipus"]))
            # FONTOS: a kulcsba az UTOLSÓ VIZSGÁLAT dátuma kerül, NEM a számított esedékesség - az üzemóra-alapú
            # esedékesség a mai naphoz képest számolódik, így szinte naponta változik, és a kulcs ezért napról
            # napra más lenne (az ismétlés-szűrés soha nem fogna). Az utolsó vizsgálat dátuma csak akkor
            # változik, ha tényleg megtörtént egy új vizsgálat.
            kulcs = f"gep:{gep.id}:{e['tipus']}:{e['allapot']}:{e.get('utolso')}"
            if e["allapot"] == "hianyzik":
                lejart_lista.append((kulcs, f"<b>{gep_nev}</b> - <span style='color:#dc3545;'>Hiányzó {cimke} dátum!</span>"))
            elif e["allapot"] == "lejart":
                lejart_lista.append((kulcs, f"<b>{gep_nev}</b> - Lejárt {cimke}: {e['esedekes']}"))
            elif e["allapot"] == "hamarosan":
                hamarosan_lista.append((kulcs, f"<b>{gep_nev}</b> - Lejáró {cimke}: {e['esedekes']}"))

    # 2. HR (GÉPKEZELŐK) ELLENŐRZÉSE
    dolgozok = db.query(models.User).filter(
        models.User.company_id == ceg.id,
        models.User.role.in_(["Felhasználó", "Emelőgép ügyintéző"])
    ).all()

    for d in dolgozok:
        dolgozo_nev = f"DOLGOZÓ: {_e(d.username)}"

        if d.orvosi_alkalmassag_ervenyesseg:
            if d.orvosi_alkalmassag_ervenyesseg < mai_nap:
                lejart_lista.append((f"dolgozo:{d.id}:orvosi:lejart:{d.orvosi_alkalmassag_ervenyesseg}",
                                     f"<b>{dolgozo_nev}</b> - Lejárt Orvosi alkalmassági: {d.orvosi_alkalmassag_ervenyesseg}"))
            elif d.orvosi_alkalmassag_ervenyesseg <= figyelmezteto_hatar:
                hamarosan_lista.append((f"dolgozo:{d.id}:orvosi:hamarosan:{d.orvosi_alkalmassag_ervenyesseg}",
                                        f"<b>{dolgozo_nev}</b> - Lejáró Orvosi alkalmassági: {d.orvosi_alkalmassag_ervenyesseg}"))

        if d.jogositvany_ervenyesseg:
            if d.jogositvany_ervenyesseg < mai_nap:
                lejart_lista.append((f"dolgozo:{d.id}:jogositvany:lejart:{d.jogositvany_ervenyesseg}",
                                     f"<b>{dolgozo_nev}</b> - Lejárt Targonca jogosítvány: {d.jogositvany_ervenyesseg}"))
            elif d.jogositvany_ervenyesseg <= figyelmezteto_hatar:
                hamarosan_lista.append((f"dolgozo:{d.id}:jogositvany:hamarosan:{d.jogositvany_ervenyesseg}",
                                        f"<b>{dolgozo_nev}</b> - Lejáró Targonca jogosítvány: {d.jogositvany_ervenyesseg}"))

    # Címzettek keresése az adott cégben
    # C szelet: a címzetteket a céges szabály + a felhasználói feliratkozás adja (lejarati_riport kategória);
    # alapból az Admin és az EÜI - ahogy korábban -, de ők ki is kapcsolhatják, mások be is kérhetik.
    cimzettek = email_feliratkozas.cimzett_felhasznalok(db, ceg.id, "lejarati_riport")
    # A TELJES riport (a dolgozók orvosi alkalmasságával, jogosítványával együtt) csak az Admin/EÜI címzetteknek
    # megy; a többi szerepkörnek (akit a cégadmin kapcsolt be) a dolgozói (HR) szakasz nélküli változat.
    cimek_teljes = email_sor.cimek_tisztitasa(
        [u.email for u in cimzettek if u.role in email_feliratkozas.ALAP_CIMZETT_SZEREPKOROK])
    cimek_korlatozott = [c for c in email_sor.cimek_tisztitasa(
        [u.email for u in cimzettek if u.role not in email_feliratkozas.ALAP_CIMZETT_SZEREPKOROK])
        if c not in cimek_teljes]

    # Ha nincs kinek küldeni, nincs teendő - az ismétlés-szűrés állapotához sem nyúlunk
    if not cimek_teljes and not cimek_korlatozott:
        return

    def hr_e(kulcs: str) -> bool:
        return kulcs.startswith("dolgozo:")

    if teszt:
        kuldendo = [("l", h, hr_e(k)) for k, h in lejart_lista] + [("h", h, hr_e(k)) for k, h in hamarosan_lista]
        elnyomott = 0
    else:
        # Ismétlés-szűrés: az új és a 7 napja emlékeztetett tételek maradnak, a többi kimarad.
        osszes = ([(k, ("l", h, hr_e(k))) for k, h in lejart_lista]
                  + [(k, ("h", h, hr_e(k))) for k, h in hamarosan_lista])
        kuldendo, elnyomott = email_sor.riport_tetelek_szurese(db, ceg.id, osszes, korlat.ismetles_nap, mai_nap)

    ures_riport = not lejart_lista and not hamarosan_lista          # tényleg nincs semmi -> "Minden rendben"
    osszes_tetel = len(lejart_lista) + len(hamarosan_lista)
    nem_hr_osszes = sum(1 for k, _ in lejart_lista + hamarosan_lista if not hr_e(k))

    # (címzettek, mely tételek kerülhetnek bele, a változatban összesen hány tétel van)
    for cimzettek_csoport, hr_is, valtozat_osszes in ((cimek_teljes, True, osszes_tetel),
                                                       (cimek_korlatozott, False, nem_hr_osszes)):
        if not cimzettek_csoport:
            continue
        resz = [(cs, h) for cs, h, hr in kuldendo if hr_is or not hr]
        kuldendo_lejart = [h for cs, h in resz if cs == "l"]
        kuldendo_hamarosan = [h for cs, h in resz if cs == "h"]
        elnyomott_valtozat = elnyomott if hr_is else (max(0, valtozat_osszes - len(resz)) if not teszt else 0)
        # Az "üres" változat: a teljes riportnál ures_riport ("Minden rendben"); a HR-mentesnél ugyanez, de ha
        # csak HR-tétel van, nem küldünk semmit (ne menjen "Minden rendben" olyankor, amikor van - számára
        # láthatatlan - tétel), és az ismétlődő-csak változatnál sem megy levél.
        csak_ismetlodo = not kuldendo_lejart and not kuldendo_hamarosan and valtozat_osszes > 0
        if (not ures_riport and valtozat_osszes == 0) or csak_ismetlodo:
            continue
        send_summary_email_task(
            cimzettek_csoport, ceg.nev, kuldendo_lejart, kuldendo_hamarosan,
            elnyomott=elnyomott_valtozat, ismetles_nap=korlat.ismetles_nap, company_id=ceg.id, db=db,
        )
    db.commit()  # a sorba állított levél és az ismétlés-szűrés állapota EGY tranzakcióban mentődik
