"""@taxman-authored "Debits & credits" ledger — user-spec 2026-05-26.

`log_tax_debit(user, slug)` appends one Line + spawns one Brief on the user's
single TAX_LEDGER Post for each FREE/PAID DRAW spend at /gameboard/my-sea/.
Parallels `apps.drama.models.Note.grant_if_new` for Note unlocks; the same
post_save guard in `billboard.models` nukes any Line saved on a TAX_LEDGER
Post w.o. admin_solicited=True.

Two debit slugs today:
    free_draw_locked  → my_sea_lock first-card-of-cycle
    paid_draw_locked  → my_sea_paid_draw commit

The Brief that spawns here is rendered via the existing slide-down banner
(note.js `Brief.showBanner`); its FYI .btn-info navigates to the user's
ledger Post; its NVM stamps the matching `User.{free,paid}_draw_brief_
dismissed_at` field via the dismiss-brief gameboard endpoints.

Line text is timestamp-prefixed so a second identical-slug spend doesn't
collide w. `Line.Meta.unique_together = ("post", "text")`."""

from django.utils import timezone

from apps.billboard.models import (
    Brief,
    Line,
    Post,
    TAX_LEDGER_POST_TITLE,
)
from apps.lyric.models import get_or_create_taxman


# Canonical Line text per slug. Replaces the prior `_showFreeDrawLockedBrief`
# helper's wording in my_sea.html — the ledger Line IS the source of truth
# for both the persistent log surface (Debits & credits Post) AND the slide-
# down Brief banner (via Brief.line.text in to_banner_dict).
#
# `.btn-pri-name` spans wrap canonical .btn-primary button labels referenced
# inline (FREE DRAW, PAID DRAW, GATE VIEW per user-spec 2026-05-26). SCSS
# (`_billboard.scss` under `.post-line--system .post-line-text`) styles the
# spans so the user sees the same `--quaUser` colour + 700-weight on the
# token in prose as they would on the actual button. Rendered as HTML via
# `Line.display_text|safe` in post.html (the system-author branch).
TAX_DEBIT_TEMPLATES = {
    "free_draw_locked": (
        'Look!—My Sea\'s <span class="btn-pri-name">FREE DRAW</span> '
        'is locked. Next free draw available 24h from the production of this log.'
    ),
    "paid_draw_locked": (
        'Look!—My Sea\'s <span class="btn-pri-name">PAID DRAW</span> '
        'is locked. Another may be unlocked by depositing a Token in '
        '<span class="btn-pri-name">GATE VIEW</span>.'
    ),
}


def log_tax_debit(user, slug):
    """Append a Line to the user's "Debits & credits" Post (creating the Post
    on first call) + spawn a Brief that the next page-load surfaces as a
    slide-down banner.

    Returns ``(post, line, brief)``. Raises ``KeyError`` for unknown slugs.

    Line text is prefixed with `[<ISO timestamp>] ` so successive spends of
    the same slug produce distinct rows (each one survives `Line.Meta.
    unique_together = ("post", "text")`)."""
    if slug not in TAX_DEBIT_TEMPLATES:
        raise KeyError(f"Unknown tax debit slug: {slug!r}")

    post, _ = Post.objects.get_or_create(
        owner=user,
        kind=Post.KIND_TAX_LEDGER,
        defaults={"title": TAX_LEDGER_POST_TITLE},
    )
    # Existing TAX_LEDGER Posts (pre-feature migration) might lack a title;
    # heal once on next debit. Mirrors the Note.grant_if_new title heal.
    if post.title != TAX_LEDGER_POST_TITLE:
        post.title = TAX_LEDGER_POST_TITLE
        post.save(update_fields=["title"])

    body = TAX_DEBIT_TEMPLATES[slug]
    # Sub-second timestamp prefix — keeps text unique even when two debits
    # land in the same wallclock second (defensive vs auto-draw paths that
    # could conceivably commit free + paid in rapid succession).
    stamp = timezone.now().isoformat(timespec="microseconds")
    text = f"[{stamp}] {body}"

    line = Line.objects.create(
        post=post,
        text=text,
        author=get_or_create_taxman(),
        admin_solicited=True,
    )
    brief = Brief.objects.create(
        owner=user,
        post=post,
        line=line,
        kind=Brief.KIND_TAX_LEDGER,
        title=TAX_LEDGER_POST_TITLE,
    )
    return post, line, brief
