"""Activity-log writer — the ONLY code path that inserts activity_log rows.

Port of v1's log_add/log_edit/log_delete/log_archive/log_unarchive
(main.py:972-1115) with garden scoping. Every state-changing service calls
one of these; routers never write the log directly.

Per standards: log error_codes and entity ids — never grants, secrets, or
raw prompt/media payloads.
"""
from __future__ import annotations

from datetime import datetime, timezone

from sqlalchemy import delete, insert, update
from sqlalchemy.orm import Session

from ..models.history import ActivityLog


def _log(
    db: Session,
    garden_id: int,
    category: str,
    entity_type: str,
    entity_id: int | None,
    summary: str,
    field: str | None = None,
    old_value: str | None = None,
    new_value: str | None = None,
) -> None:
    db.execute(
        insert(ActivityLog).values(
            garden_id=garden_id,
            created_at=datetime.now(timezone.utc),
            category=category,
            entity_type=entity_type,
            entity_id=entity_id,
            summary=summary,
            field=field,
            old_value=old_value,
            new_value=new_value,
        )
    )


def log_add(db: Session, garden_id: int, entity_type: str, entity_id: int, label: str) -> None:
    _log(db, garden_id, "add", entity_type, entity_id, f"Added {entity_type} {label}")


def log_edit(
    db: Session, garden_id: int, entity_type: str, entity_id: int,
    field: str, old_value, new_value, label: str = "",
) -> None:
    _log(
        db, garden_id, "edit", entity_type, entity_id,
        f"Edited {entity_type} {label or entity_id}: {field}",
        field=field,
        old_value=None if old_value is None else str(old_value),
        new_value=None if new_value is None else str(new_value),
    )


def log_delete(db: Session, garden_id: int, entity_type: str, entity_id: int, label: str) -> None:
    _log(db, garden_id, "delete", entity_type, entity_id, f"Deleted {entity_type} {label}")


def log_archive(db: Session, garden_id: int, entity_type: str, entity_id: int, label: str) -> None:
    _log(db, garden_id, "archive", entity_type, entity_id, f"Archived {entity_type} {label}")


def log_unarchive(db: Session, garden_id: int, entity_type: str, entity_id: int, label: str) -> None:
    _log(db, garden_id, "unarchive", entity_type, entity_id, f"Unarchived {entity_type} {label}")


# --- chat sessions (v1 main.py:7809-7987) ----------------------------------
#
# v1 wrote ONE activity_log row per chat session (category 'chat') at
# session create, then updated its summary with the AI title at session end
# and deleted it when an empty session was discarded. Those three writes
# stay here so this module remains the only activity_log writer.

def log_chat_session_start(db: Session, garden_id: int, session_id: int) -> int:
    """Insert the session's log row and return its id (stored on
    chat_sessions.activity_log_id, exactly like v1)."""
    row = ActivityLog(
        garden_id=garden_id,
        created_at=datetime.now(timezone.utc),
        category="chat",
        entity_type="chat_session",
        entity_id=session_id,
        summary=f"Chat session #{session_id} started",
    )
    db.add(row)
    db.flush()
    return row.id


def update_chat_log_summary(db: Session, log_id: int, summary: str) -> None:
    db.execute(
        update(ActivityLog).where(ActivityLog.id == log_id).values(summary=summary)
    )


def delete_chat_log(db: Session, log_id: int) -> None:
    db.execute(delete(ActivityLog).where(ActivityLog.id == log_id))
