"""
Script 2 (analyze) – projde nezpracované stažené PDF (status='pending' v
Kongres_pdf_imports), rozparsuje je (Kongres_parse_pdf.parse_pdf) a zapíše/aktualizuje
odpovídající den v Kongres_diary_days.

Uzavřený den: uloží kompletní data (počasí, osoby, mechanizmy, práce, další
záznamy), nastaví status='closed'. Jakmile je den jednou uzavřený, dál se
nezpracovává (viz kontrola níž) – i kdyby omylem přišel další pending import.

Otevřený den: porovná nově zparsované "další záznamy" s tím, co už je
uložené (podle autor+dodavatel+text). Položky, které tam ještě nebyly,
dostanou "first_seen_at" = teď – script 3 (email) pak podle toho pozná,
co přibylo od posledního běhu.

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

import hashlib
import json
import os
from datetime import datetime

import pymysql
from dotenv import load_dotenv

from Kongres_parse_pdf import parse_pdf

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",
}


def _entry_key(entry: dict) -> str:
    raw = f"{entry.get('autor')}|{entry.get('dodavatel')}|{entry.get('text')}"
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()


def merge_dalsi_zaznamy(old_entries: list, new_entries: list, now: datetime) -> tuple[list, list]:
    """Vrátí (merged, nove). merged = kompletní seznam k uložení (staré
    položky si drží původní first_seen_at), nove = položky, co teď poprvé
    přibyly (to je to, co půjde do emailového reportu)."""
    old_by_key = {_entry_key(e): e for e in (old_entries or [])}
    merged, nove = [], []
    for e in new_entries:
        key = _entry_key(e)
        if key in old_by_key:
            merged.append(old_by_key[key])
        else:
            e = dict(e)
            e["first_seen_at"] = now.isoformat()
            merged.append(e)
            nove.append(e)
    return merged, nove


def fetch_pending(conn) -> list:
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute(
            "SELECT id, diary_date, file_path FROM Kongres_pdf_imports "
            "WHERE status = 'pending' ORDER BY diary_date ASC"
        )
        return cur.fetchall()


def fetch_existing_day(conn, diary_date):
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute("SELECT * FROM Kongres_diary_days WHERE diary_date = %s", (diary_date,))
        return cur.fetchone()


def upsert_day(
    conn, diary_date, status,
    pocasi, osoby, mechanizmy, prace, dalsi_zaznamy,
    now: datetime,
) -> None:
    with conn.cursor() as cur:
        cur.execute(
            """
            INSERT INTO Kongres_diary_days
                (diary_date, status, pocasi_json, osoby_json, mechanizmy_json,
                 prace_json, dalsi_zaznamy_json, last_checked_at, closed_at)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE
                status = VALUES(status),
                pocasi_json = VALUES(pocasi_json),
                osoby_json = VALUES(osoby_json),
                mechanizmy_json = VALUES(mechanizmy_json),
                prace_json = VALUES(prace_json),
                dalsi_zaznamy_json = VALUES(dalsi_zaznamy_json),
                last_checked_at = VALUES(last_checked_at),
                closed_at = VALUES(closed_at)
            """,
            (
                diary_date, status,
                json.dumps(pocasi, ensure_ascii=False) if pocasi is not None else None,
                json.dumps(osoby, ensure_ascii=False) if osoby is not None else None,
                json.dumps(mechanizmy, ensure_ascii=False) if mechanizmy is not None else None,
                json.dumps(prace, ensure_ascii=False) if prace is not None else None,
                json.dumps(dalsi_zaznamy, ensure_ascii=False),
                now,
                now if status == "closed" else None,
            ),
        )
    conn.commit()


def mark_import_processed(conn, import_id: int) -> None:
    with conn.cursor() as cur:
        cur.execute(
            "UPDATE Kongres_pdf_imports SET status='processed', processed_at=%s WHERE id=%s",
            (datetime.now(), import_id),
        )
    conn.commit()


def main() -> None:
    now = datetime.now()
    conn = pymysql.connect(**DB_CONFIG)
    try:
        pending = fetch_pending(conn)
        print(f"{now:%Y-%m-%d %H:%M:%S} – nalezeno {len(pending)} nezpracovaných PDF")

        for row in pending:
            diary_date = row["diary_date"]
            parsed = parse_pdf(row["file_path"])
            existing = fetch_existing_day(conn, diary_date)

            if existing and existing["status"] == "closed":
                mark_import_processed(conn, row["id"])
                print(f"  {diary_date}: den už je uzavřený, přeskakuji (jen označen import).")
                continue

            if parsed["closed"]:
                upsert_day(
                    conn, diary_date, "closed",
                    parsed["pocasi"], parsed["osoby"], parsed["mechanizmy"],
                    parsed["prace"], parsed["dalsi_zaznamy"], now,
                )
                mark_import_processed(conn, row["id"])
                print(f"  {diary_date}: den UZAVŘEN, uloženo počasí/osoby/mechanizmy/práce.")
            else:
                old_entries = (
                    json.loads(existing["dalsi_zaznamy_json"])
                    if existing and existing["dalsi_zaznamy_json"] else []
                )
                merged, nove = merge_dalsi_zaznamy(old_entries, parsed["dalsi_zaznamy"], now)
                upsert_day(conn, diary_date, "open", None, None, None, None, merged, now)
                mark_import_processed(conn, row["id"])
                print(f"  {diary_date}: den otevřený, {len(nove)} nových záznamů od minule.")
    finally:
        conn.close()


if __name__ == "__main__":
    main()
