"""
Script 3 (send) – pošle denní email s přehledem: nové záznamy v otevřených
dnech (od posledního nahlášení) + info o posledním uzavřeném dni.

Po úspěšném odeslání označí nahlášené záznamy jako reported_at=teď, ať se
příště neposílají znovu.

Konfigurace (.env): MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD,
KONGRES_MAIL_RECIPIENTS (čárkou oddělené adresy).

Použití:
    venv/bin/python Kongres_send_report.py
"""

import html
import json
import os
import smtplib
from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr

import pymysql
from dotenv import load_dotenv

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
load_dotenv(os.path.join(BASE_DIR, ".env"))

DB_CONFIG = {
    "host": os.environ.get("KONGRES_DB_HOST", "localhost"),
    "user": os.environ.get("KONGRES_DB_USER", "TODO"),
    "password": os.environ.get("KONGRES_DB_PASS", "TODO"),
    "database": "adeniraImporter",
    "charset": "utf8mb4",
}

MAIL_HOST = os.environ.get("MAIL_HOST", "TODO")
MAIL_PORT = int(os.environ.get("MAIL_PORT", "587"))
MAIL_USERNAME = os.environ.get("MAIL_USERNAME", "TODO")
MAIL_PASSWORD = os.environ.get("MAIL_PASSWORD", "TODO")
MAIL_FROM_ADDRESS = os.environ.get("MAIL_FROM_ADDRESS", MAIL_USERNAME)
MAIL_FROM_NAME = os.environ.get("MAIL_FROM_NAME", "")
RECIPIENTS = [r.strip() for r in os.environ.get("KONGRES_MAIL_RECIPIENTS", "").split(",") if r.strip()]


def fetch_open_days(conn) -> list[dict]:
    """Všechny otevřené dny (i bez záznamů, např. dnešek bez obsahu) – v
    reportu se zobrazí celý aktuální stav, nové položky se jen označí
    štítkem. Řazeno od nejstaršího po nejnovější."""
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute(
            "SELECT diary_date, dalsi_zaznamy_json FROM Kongres_diary_days "
            "WHERE status = 'open' ORDER BY diary_date ASC"
        )
        rows = cur.fetchall()

    result = []
    for row in rows:
        entries = json.loads(row["dalsi_zaznamy_json"]) if row["dalsi_zaznamy_json"] else []
        result.append({"diary_date": row["diary_date"], "entries": entries})
    return result


def fetch_last_closed_day(conn):
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute(
            "SELECT diary_date, closed_at, pocasi_json, osoby_json, dalsi_zaznamy_json "
            "FROM Kongres_diary_days WHERE status = 'closed' ORDER BY diary_date DESC LIMIT 1"
        )
        row = cur.fetchone()
    if not row:
        return None
    row["pocasi"] = json.loads(row["pocasi_json"]) if row["pocasi_json"] else []
    row["osoby"] = json.loads(row["osoby_json"]) if row["osoby_json"] else []
    row["dalsi_zaznamy"] = json.loads(row["dalsi_zaznamy_json"]) if row["dalsi_zaznamy_json"] else []
    return row


def mark_entries_reported(conn, diary_date, now: datetime) -> None:
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute("SELECT dalsi_zaznamy_json FROM Kongres_diary_days WHERE diary_date = %s", (diary_date,))
        row = cur.fetchone()
    entries = json.loads(row["dalsi_zaznamy_json"]) if row and row["dalsi_zaznamy_json"] else []
    for e in entries:
        if not e.get("reported_at"):
            e["reported_at"] = now.isoformat()
    with conn.cursor() as cur:
        cur.execute(
            "UPDATE Kongres_diary_days SET dalsi_zaznamy_json = %s WHERE diary_date = %s",
            (json.dumps(entries, ensure_ascii=False), diary_date),
        )
    conn.commit()


def build_report_text(open_days: list[dict], last_closed) -> str:
    """Prostý text jako záloha pro emailové klienty bez podpory HTML."""
    lines = []
    if open_days:
        lines.append("OTEVŘENÉ DNY:")
        lines.append("")
        for day in open_days:
            lines.append(f"{day['diary_date']:%d.%m.%Y}:")
            if not day["entries"]:
                lines.append("  (zatím žádné záznamy)")
            for e in day["entries"]:
                autor = e.get("autor") or "?"
                dodavatel = e.get("dodavatel") or "?"
                text = e.get("text") or ""
                tag = "[NOVÉ] " if not e.get("reported_at") else ""
                lines.append(f"  - {tag}[{autor} / {dodavatel}] {text}")
            lines.append("")
    else:
        lines.append("Žádné otevřené dny se záznamy.")
        lines.append("")

    lines.append("POSLEDNÍ UZAVŘENÝ DEN:")
    if last_closed:
        lines.append(f"{last_closed['diary_date']:%d.%m.%Y}")
        if last_closed["pocasi"]:
            lines.append("Počasí:")
            for p in last_closed["pocasi"]:
                lines.append(f"  {p['cas']} {p['stav']} {p['teplota_c']}°C, vítr {p['vitr_ms']} m/s, vlhkost {p['vlhkost_pct']}%")
        if last_closed["osoby"]:
            lines.append("Osoby na staveništi:")
            for o in last_closed["osoby"]:
                lines.append(f"  {o['dodavatel']}: {o['pocet']} osob, {o['hodin']} hod.")
        if last_closed["dalsi_zaznamy"]:
            lines.append("Další záznamy:")
            for e in last_closed["dalsi_zaznamy"]:
                autor = e.get("autor") or "?"
                dodavatel = e.get("dodavatel") or "?"
                text = e.get("text") or ""
                lines.append(f"  - [{autor} / {dodavatel}] {text}")
    else:
        lines.append("Zatím žádný uzavřený den.")

    return "\n".join(lines)


def _entry_html(e: dict, show_new_badge: bool = False) -> str:
    autor = html.escape(e.get("autor") or "?")
    dodavatel = html.escape(e.get("dodavatel") or "?")
    text = html.escape(e.get("text") or "")
    badge = ""
    if show_new_badge and not e.get("reported_at"):
        badge = (
            '<span style="background:#e74c3c;color:#fff;font-size:11px;'
            'font-weight:bold;padding:2px 6px;border-radius:3px;margin-right:6px;">NOVÉ</span>'
        )
    return (
        '<li style="margin-bottom:10px;">'
        f'{badge}<b>{autor}</b> <span style="color:#777;">({dodavatel})</span><br>'
        f'<span>{text}</span></li>'
    )


def build_report_html(open_days: list[dict], last_closed) -> str:
    h2 = 'style="color:#1a5276;border-bottom:2px solid #1a5276;padding-bottom:4px;margin-top:28px;"'
    parts = [
        '<div style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#222;max-width:700px;">',
        f'<h1 style="color:#1a5276;">Kongres – denní report {datetime.now():%d.%m.%Y}</h1>',
        f'<h2 {h2}>Otevřené dny</h2>',
    ]

    if open_days:
        for day in open_days:
            parts.append(f'<h3 style="margin-bottom:4px;">{day["diary_date"]:%d.%m.%Y}</h3>')
            if day["entries"]:
                parts.append('<ul style="margin-top:0;padding-left:20px;">')
                parts.extend(_entry_html(e, show_new_badge=True) for e in day["entries"])
                parts.append('</ul>')
            else:
                parts.append('<p style="color:#777;margin-top:0;">Zatím žádné záznamy.</p>')
    else:
        parts.append('<p>Žádné otevřené dny.</p>')

    parts.append(f'<h2 {h2}>Poslední uzavřený den</h2>')
    if last_closed:
        parts.append(f'<p><b>{last_closed["diary_date"]:%d.%m.%Y}</b></p>')

        if last_closed["pocasi"]:
            parts.append('<table style="border-collapse:collapse;margin-bottom:16px;" cellpadding="6">')
            parts.append(
                '<tr style="background:#f0f0f0;">'
                '<th align="left">Čas</th><th align="left">Počasí</th>'
                '<th align="left">Teplota</th><th align="left">Vítr</th><th align="left">Vlhkost</th></tr>'
            )
            for p in last_closed["pocasi"]:
                parts.append(
                    '<tr style="border-bottom:1px solid #eee;">'
                    f'<td>{html.escape(p["cas"])}</td><td>{html.escape(p["stav"])}</td>'
                    f'<td>{p["teplota_c"]}°C</td><td>{p["vitr_ms"]} m/s</td><td>{p["vlhkost_pct"]}%</td></tr>'
                )
            parts.append('</table>')

        if last_closed["osoby"]:
            parts.append('<table style="border-collapse:collapse;margin-bottom:16px;" cellpadding="6">')
            parts.append(
                '<tr style="background:#f0f0f0;">'
                '<th align="left">Dodavatel</th><th align="left">Počet osob</th><th align="left">Hodin</th></tr>'
            )
            for o in last_closed["osoby"]:
                parts.append(
                    '<tr style="border-bottom:1px solid #eee;">'
                    f'<td>{html.escape(o["dodavatel"])}</td><td>{o["pocet"]}</td><td>{o["hodin"]}</td></tr>'
                )
            parts.append('</table>')

        if last_closed["dalsi_zaznamy"]:
            parts.append('<p><b>Další záznamy:</b></p>')
            parts.append('<ul style="padding-left:20px;">')
            parts.extend(_entry_html(e) for e in last_closed["dalsi_zaznamy"])
            parts.append('</ul>')
    else:
        parts.append('<p>Zatím žádný uzavřený den.</p>')

    parts.append('</div>')
    return "".join(parts)


def send_email(subject: str, text_body: str, html_body: str) -> None:
    # "alternative" = klient si vybere jednu variantu k zobrazení (HTML,
    # pokud umí; jinak text), nezobrazí obě najednou jako přílohy.
    msg = MIMEMultipart("alternative")
    msg["From"] = formataddr((MAIL_FROM_NAME, MAIL_FROM_ADDRESS)) if MAIL_FROM_NAME else MAIL_FROM_ADDRESS
    msg["To"] = ", ".join(RECIPIENTS)
    msg["Subject"] = subject
    msg.attach(MIMEText(text_body, "plain", "utf-8"))
    msg.attach(MIMEText(html_body, "html", "utf-8"))

    with smtplib.SMTP(MAIL_HOST, MAIL_PORT) as server:
        server.starttls()
        server.login(MAIL_USERNAME, MAIL_PASSWORD)
        server.sendmail(MAIL_FROM_ADDRESS, RECIPIENTS, msg.as_string())


def main() -> None:
    now = datetime.now()
    if not RECIPIENTS:
        print(f"{now:%Y-%m-%d %H:%M:%S} – CHYBA: KONGRES_MAIL_RECIPIENTS není nastaveno v .env")
        return

    conn = pymysql.connect(**DB_CONFIG)
    try:
        open_days = fetch_open_days(conn)
        last_closed = fetch_last_closed_day(conn)

        text_body = build_report_text(open_days, last_closed)
        html_body = build_report_html(open_days, last_closed)
        subject = f"Kongres – denní report {now:%d.%m.%Y}"

        send_email(subject, text_body, html_body)
        print(f"{now:%Y-%m-%d %H:%M:%S} – email odeslán na {', '.join(RECIPIENTS)}")

        for day in open_days:
            mark_entries_reported(conn, day["diary_date"], now)
    finally:
        conn.close()


if __name__ == "__main__":
    main()
