"""Fix stale "Balance due: {{balance_due}}" line in the seeded contract_signed
email template (Variant A) — arq_app.py's send_contract_email never sets a
context["balance_due"] key (it only ever set context["payment_summary"]), so
every tenant still on Variant A has this line render as "Balance due: —" in
the contract-signed confirmation email, for both single-payment and split
payment-plan (e.g. payment_plan_type='deposit_50') contracts.

Background — two variants of the seeded contract_signed body exist in
production (see 0079's docstring, which documents both in full and touches
both, but explicitly leaves this exact divergence alone as "a pre-existing,
unrelated drift, out of scope for that migration"):

  Variant A — tenants provisioned via/after migration 0072, before a later,
  migration-less edit to SYSTEM_TEMPLATES added {{payment_summary}}. As of
  0079 (already applied), Variant A's body contains the literal line
  "Balance due: {{balance_due}}" followed by "{{bank_details_block}}".

  Variant B — tenants provisioned against the CURRENT
  src/apps/settings/services/email_template_service.py:SYSTEM_TEMPLATES
  source. Body already uses "{{payment_summary}}" in place of the "Balance
  due" line, and already renders correctly today. NOT touched by this
  migration.

This migration moves Variant A's body/merge_fields to match Variant B's
current body/merge_fields exactly — i.e. after this migration, both known
seeded variants converge on the same (correct) text. Only rows whose body
still exactly matches Variant A's known post-0079 default are touched — a
tenant that has customized their contract_signed template via Settings (body
no longer matches either known default exactly) is left untouched, same
guard pattern as 0072/0077/0079/0080.

Idempotent: this is an exact-match UPDATE (WHERE body = :old_body), so running
it twice is a no-op the second time — after the first run, no row's body
matches OLD_BODY any more, so the second run's UPDATE affects zero rows.

NOTE: migrations are self-contained/frozen-in-time — this file keeps its own
copy of the old/new body text, per the convention documented in
src/apps/settings/services/email_template_service.py:43-45. SYSTEM_TEMPLATES
already has Variant B's (correct) body — this migration is a pure data
backfill for already-provisioned tenants and requires no change to
SYSTEM_TEMPLATES.

Revision ID: 0083
Revises: 0082
"""
import json

import sqlalchemy as sa
from alembic import op

revision = "0083"
down_revision = "0082"
branch_labels = None
depends_on = None

# ---------------------------------------------------------------------------
# Variant A, as it stands after migration 0079 (bank_details_block already
# swapped in for payment_url; balance_due/payment_summary drift untouched).
# ---------------------------------------------------------------------------
OLD_BODY = (
    "Dear {{purchaser_name}},\n\n"
    "Thank you for choosing {{cemetery_name}}. This confirms your "
    "{{contract_type}} contract ({{contract_number}}) for {{plot_id}} "
    "in {{section}} has been signed.\n\n"
    "Contract total: {{contract_total}}\n"
    "Balance due: {{balance_due}}\n\n"
    "{{bank_details_block}}\n\n"
    "If you have any questions, contact us at {{cemetery_email}} or "
    "{{cemetery_phone}}.\n\n"
    "Sincerely,\n{{cemetery_name}}"
)

# ---------------------------------------------------------------------------
# Target — Variant B's current body (already correct; converges Variant A
# onto it).
# ---------------------------------------------------------------------------
NEW_BODY = (
    "Dear {{purchaser_name}},\n\n"
    "Thank you for choosing {{cemetery_name}}. This confirms your "
    "{{contract_type}} contract ({{contract_number}}) for {{plot_id}} "
    "in {{section}} has been signed.\n\n"
    "Contract total: {{contract_total}}\n"
    "{{payment_summary}}\n\n"
    "{{bank_details_block}}\n\n"
    "If you have any questions, contact us at {{cemetery_email}} or "
    "{{cemetery_phone}}.\n\n"
    "Sincerely,\n{{cemetery_name}}"
)

OLD_MERGE_FIELDS = [
    "purchaser_name", "contract_type", "plot_id", "section",
    "contract_number", "contract_total", "balance_due", "bank_details_block",
    "cemetery_name", "cemetery_email", "cemetery_phone", "current_date",
]
NEW_MERGE_FIELDS = [
    "purchaser_name", "contract_type", "plot_id", "section",
    "contract_number", "contract_total", "payment_summary", "bank_details_block",
    "cemetery_name", "cemetery_email", "cemetery_phone", "current_date",
]


def upgrade() -> None:
    conn = op.get_bind()
    conn.execute(
        sa.text(
            """
            UPDATE email_templates
            SET body = :new_body,
                merge_fields = CAST(:merge_fields AS JSONB),
                updated_at = now()
            WHERE template_key = 'contract_signed'
              AND is_system = true
              AND body = :old_body
            """
        ),
        {
            "new_body": NEW_BODY,
            "old_body": OLD_BODY,
            "merge_fields": json.dumps(NEW_MERGE_FIELDS),
        },
    )


def downgrade() -> None:
    """Best-effort revert: only rows still exactly on the new body.

    A row that started as Variant B (never touched by this migration) is
    indistinguishable from a converged Variant A row after upgrade() — both
    now share NEW_BODY exactly. Downgrade cannot tell them apart and will
    revert both to OLD_BODY (Variant A's "Balance due: {{balance_due}}"
    text), mirroring 0079's own documented downgrade limitation. This is
    only a concern if the migration is ever rolled back in an environment
    that already had genuine Variant B rows before this migration ran.
    """
    conn = op.get_bind()
    conn.execute(
        sa.text(
            """
            UPDATE email_templates
            SET body = :old_body,
                merge_fields = CAST(:merge_fields AS JSONB),
                updated_at = now()
            WHERE template_key = 'contract_signed'
              AND is_system = true
              AND body = :new_body
            """
        ),
        {
            "old_body": OLD_BODY,
            "new_body": NEW_BODY,
            "merge_fields": json.dumps(OLD_MERGE_FIELDS),
        },
    )
