#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
03 — La Bitácora: la memoria que se escribe sola
================================================

Episodio «¿Cómo se le da memoria a una IA?» — Punto 5 del guion,
«El diario que se escribe solo» (acto III — El relato y lo que lo sostiene),
la Capa E.

La idea del episodio
--------------------
La quinta pregunta no es «qué hiciste», es «¿cómo fue el día?». No pide una
lista: pide un **relato**. Y lo mejor es que **se escribe sola**: una vez al
día, de madrugada, el asistente coge lo del día (los hechos, los mensajes y el
diario de ayer para no repetirse) y escribe **una entrada por día**. Con un
detalle de otro nivel: puede decidir que **ese día no hay nada que contar**.
Ese «no escribo» no es un error; es una respuesta válida.

Qué hace este ejemplo
---------------------
Lee un fichero con el «material del día» y hace lo mismo que haría Valet:

  * Si el día trae algo que merece memoria → escribe una entrada en
    `bitacora/AAAA-MM-DD.md`, en primera persona, y le añade los matices
    (ánimo, logros, dificultades, etiquetas).
  * Si el día está vacío → **no escribe nada** y lo dice en voz alta.

Y respeta la regla de oro: **una sola entrada por día**. Si ya existe, no la
duplica.

En Valet el relato lo escribe un modelo. Aquí lo montamos a base de plantilla,
sin instalar nada, porque lo que queremos enseñar no es la prosa, sino el
**mecanismo**: recoger el día, decidir, y escribir una única entrada.

Uso:
    python3 03-la-bitacora.py                      # enseña los días de ejemplo
    python3 03-la-bitacora.py datos/dia-2026-10-18.json
"""

import json
import os
import sys

# Dónde se guardan las entradas, como en un diario real: un fichero por día.
CARPETA_BITACORA = "bitacora"


def dia_vacio(material):
    """Un día sin hechos, sin mensajes y sin nada que contar no merece entrada."""
    return not material.get("hechos") and not material.get("mensajes")


def componer_relato(material):
    """
    Escribe el relato del día, en primera persona y con nuestras palabras.

    El episodio lo pide así: «no enumeres los hechos otra vez, descríbelos con
    tus palabras. Describe en vez de diagnosticar.» Aquí, sin modelo, hacemos
    una versión sencilla de esa idea: unimos los hechos en un párrafo que suene
    a cómo lo contarías tú, no a un informe.
    """
    hechos = material.get("hechos", [])
    frases = []

    # Abrimos con el primer hecho como arranque del día.
    if hechos:
        frases.append("Hoy " + hechos[0].rstrip(".").lower() + ".")
    # Y seguimos con el resto, enganchándolos con naturalidad.
    for hecho in hechos[1:]:
        frases.append("También " + hecho.rstrip(".").lower() + ".")

    if material.get("mensajes"):
        frases.append("Entre medias he ido hablando con el asistente de lo de siempre.")

    return " ".join(frases)


def escribir_entrada(ruta, material):
    fecha = material["fecha"]
    os.makedirs(CARPETA_BITACORA, exist_ok=True)
    destino = os.path.join(CARPETA_BITACORA, f"{fecha}.md")

    # Regla de oro: una sola entrada por día.
    if os.path.exists(destino):
        print(f"  {fecha}: ya había una entrada, no se duplica → {destino}")
        return

    relato = componer_relato(material)
    animo = material.get("animo", "sin determinar")
    logros = material.get("logros", [])
    dificultades = material.get("dificultades", [])
    etiquetas = material.get("etiquetas", [])

    lineas = [
        f"# {fecha}",
        "",
        relato,
        "",
        f"- **Ánimo:** {animo}",
    ]
    if logros:
        lineas.append("- **Logros:** " + "; ".join(logros))
    if dificultades:
        lineas.append("- **Dificultades:** " + "; ".join(dificultades))
    if etiquetas:
        lineas.append("- **Etiquetas:** " + ", ".join(etiquetas))
    lineas.append("")

    with open(destino, "w", encoding="utf-8") as f:
        f.write("\n".join(lineas))

    print(f"  {fecha}: se escribe la entrada → {destino}")
    print("  " + "-" * 62)
    for linea in lineas:
        print("    " + linea)
    print("  " + "-" * 62)


def procesar(material):
    fecha = material.get("fecha", "sin fecha")
    print(f"\n  Material del día {fecha}:")
    print(f"    hechos    : {len(material.get('hechos', []))}")
    print(f"    mensajes  : {len(material.get('mensajes', []))}")

    if dia_vacio(material):
        # Este es el «no escribo» explícito: una respuesta válida, no un error.
        print("  → NO se escribe entrada: ese día no hay nada que merezca memoria.")
        return

    escribir_entrada(CARPETA_BITACORA, material)


def main():
    print("=" * 68)
    print("  LA BITÁCORA: LA MEMORIA QUE SE ESCRIBE SOLA")
    print("=" * 68)

    if len(sys.argv) > 1:
        with open(sys.argv[1], encoding="utf-8") as f:
            procesar(json.load(f))
    else:
        # Sin argumentos, enseña los días de ejemplo que trae el episodio:
        # dos jornadas reales (18 y 20 de octubre) y un día vacío, para ver
        # el «no escribo» en acción.
        aqui = os.path.dirname(os.path.abspath(__file__))
        carpeta = os.path.join(aqui, "datos")
        for nombre in sorted(os.listdir(carpeta)):
            if nombre.startswith("dia-") and nombre.endswith(".json"):
                with open(os.path.join(carpeta, nombre), encoding="utf-8") as f:
                    procesar(json.load(f))

    print("\n  Y así, sin que se lo pidas, el asistente te lleva el diario.")
    print("  De madrugada, una vez al día, decide y escribe. O decide no escribir.\n")


if __name__ == "__main__":
    main()
