<?php
// ============================================================
//  Finalise scheduled cancellations — daily
// ============================================================
//
//  When a member cancels, we PAUSE their PayFast subscription
//  and set members.cancel_effective_at to the end of their
//  paid-up period. They keep access during this grace period
//  and can reactivate (unpause) without a new charge.
//
//  This cron runs daily and, for any member whose grace period
//  has ended:
//    1. CANCELS the subscription at PayFast (irreversible)
//    2. Marks members.status='cancelled'
//    3. Hides the public listing
//    4. Sends the final goodbye email
//
// ============================================================

require_once __DIR__ . '/_bootstrap.php';
require_once __DIR__ . '/../includes/mailer.php';
require_once __DIR__ . '/../includes/payfast.php';
require_once __DIR__ . '/../includes/member_history.php';

$run_id = cron_begin('cancel-finalise');

// Find members whose grace period has ended
$to_cancel = db_all(
    "SELECT id, email, first_name, last_name, business_name, cancel_effective_at
       FROM members
      WHERE cancel_effective_at IS NOT NULL
        AND cancel_effective_at <= CURDATE()
        AND status = 'active'"
);

$processed = 0;
foreach ($to_cancel as $m) {
    echo "  -> {$m['email']} (grace ended {$m['cancel_effective_at']})\n";

    // ── 1. Hard-cancel any paused PayFast subscription tokens ──
    $tokens = db_all(
        "SELECT id, token FROM payment_tokens
          WHERE member_id = :m AND token IS NOT NULL AND token != ''
            AND status = 'active'",
        ['m' => $m['id']]
    );
    foreach ($tokens as $t) {
        $r = pf_cancel_subscription($t['token']);
        echo "     PayFast cancel " . substr($t['token'], 0, 8) . "… → "
            . ($r['ok'] ? 'ok' : 'FAILED: '.$r['message']) . "\n";
        // Mark token as cancelled regardless — the grace period is over
        db_exec(
            "UPDATE payment_tokens SET status='cancelled', cancelled_at=NOW() WHERE id=:id",
            ['id' => $t['id']]
        );
        if (!$r['ok']) {
            app_log("cancel-finalise: PayFast cancel failed for member {$m['id']} token=" .
                substr($t['token'], 0, 8) . "…: " . $r['message']);
        }
    }

    // ── 2. Flip account to cancelled ──────────────────────────
    db_exec(
        "UPDATE members SET status='cancelled' WHERE id=:id",
        ['id' => $m['id']]
    );

    // ── 3. Hide the public listing ────────────────────────────
    db_exec(
        "UPDATE listings SET published=0 WHERE member_id=:id",
        ['id' => $m['id']]
    );

    // ── 4. Send the final goodbye email ───────────────────────
    email_enqueue('cancellation_final', $m['email'],
        trim($m['first_name'] . ' ' . $m['last_name']),
        [
            'first_name'    => $m['first_name'],
            'business_name' => $m['business_name'],
        ]
    );

    // ── 5. Member history ────────────────────────────────────
    member_history_log(
        (int)$m['id'],
        'cancelled',
        'Cancellation finalised — subscription cancelled at PayFast, listing hidden',
        null,
        ['actor_type'=>'system', 'actor_name'=>'Cron']
    );

    app_log("Cancellation finalised: member {$m['id']} <{$m['email']}> — listing hidden");
    $processed++;
}

echo "  finalised $processed cancellation(s)\n";
cron_finish($run_id, "ok", $processed);