<?php
// ═══════════════════════════════════════════════════════════
//  FICTION IGNITION — api/webhook/square.php
//  Receives subscription lifecycle events from Square.
//  Configure this URL in Square Dashboard → Webhooks:
//    https://yourdomain.com/api/webhook/square.php
//
//  Events handled:
//    subscription.activated
//    subscription.updated
//    subscription.deactivated
//    payment.completed  (for logging)
// ═══════════════════════════════════════════════════════════

declare(strict_types=1);

require_once __DIR__ . '/../lib/config.php';
require_once __DIR__ . '/../lib/square.php';

// Webhooks must be POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit('Method Not Allowed');
}

$rawBody  = file_get_contents('php://input');
$sig      = $_SERVER['HTTP_X_SQUARE_HMACSHA256_SIGNATURE'] ?? '';
$webhookUrl = rtrim(env('APP_URL'), '/') . '/api/webhook/square.php';

// ── Verify signature ───────────────────────────────────────
if (!square_verify_webhook($rawBody, $sig, $webhookUrl)) {
    error_log('Fiction Ignition: Invalid Square webhook signature');
    http_response_code(403);
    exit('Invalid signature');
}

$event = json_decode($rawBody, true);
if (!$event) { http_response_code(400); exit('Invalid JSON'); }

$eventId   = $event['event_id']  ?? '';
$eventType = $event['type']      ?? '';

$db = fi_db();

// ── Idempotency: skip already-processed events ─────────────
$stmt = $db->prepare('SELECT id FROM webhook_events WHERE square_event_id = ? LIMIT 1');
$stmt->execute([$eventId]);
if ($stmt->fetch()) {
    http_response_code(200);
    exit('Already processed');
}

// Log the event
$db->prepare('INSERT INTO webhook_events (square_event_id, event_type, payload) VALUES (?,?,?)')
   ->execute([$eventId, $eventType, $rawBody]);

// ── Handle event types ─────────────────────────────────────
try {
    match ($eventType) {
        'subscription.activated'   => handle_activated($event, $db),
        'subscription.updated'     => handle_updated($event, $db),
        'subscription.deactivated' => handle_deactivated($event, $db),
        default                    => null, // Ignore unhandled events
    };

    // Mark processed
    $db->prepare('UPDATE webhook_events SET processed = 1 WHERE square_event_id = ?')->execute([$eventId]);
    http_response_code(200);
    echo 'OK';

} catch (Throwable $e) {
    error_log('Webhook processing error: ' . $e->getMessage());
    http_response_code(500);
    exit('Processing error');
}

// ── Activated ─────────────────────────────────────────────
function handle_activated(array $event, PDO $db): void {
    $sub    = $event['data']['object']['subscription'] ?? [];
    $subId  = $sub['id'] ?? '';
    $status = 'active';

    if (!$subId) return;

    $db->prepare("UPDATE subscriptions SET status = ?, current_period_end = ? WHERE square_subscription_id = ?")
       ->execute([$status, $sub['charged_through_date'] ?? null, $subId]);
}

// ── Updated (e.g. renewal, card change) ───────────────────
function handle_updated(array $event, PDO $db): void {
    $sub   = $event['data']['object']['subscription'] ?? [];
    $subId = $sub['id'] ?? '';
    if (!$subId) return;

    // If status changed to active (renewal succeeded), update period
    $newStatus = match ($sub['status'] ?? '') {
        'ACTIVE'    => 'active',
        'PAUSED'    => 'paused',
        'CANCELED'  => 'cancelled',
        'DEACTIVATED' => 'cancelled',
        default     => null,
    };

    if ($newStatus) {
        $db->prepare("UPDATE subscriptions SET status = ?, current_period_end = ? WHERE square_subscription_id = ?")
           ->execute([$newStatus, $sub['charged_through_date'] ?? null, $subId]);

        // If cancelled/deactivated, downgrade user tier
        if (in_array($newStatus, ['cancelled', 'paused'])) {
            $stmt = $db->prepare('SELECT user_id FROM subscriptions WHERE square_subscription_id = ? LIMIT 1');
            $stmt->execute([$subId]);
            $row = $stmt->fetch();
            if ($row) {
                $db->prepare('UPDATE users SET tier = \'free\' WHERE id = ?')->execute([$row['user_id']]);
            }
        }
    }
}

// ── Deactivated ───────────────────────────────────────────
function handle_deactivated(array $event, PDO $db): void {
    $sub   = $event['data']['object']['subscription'] ?? [];
    $subId = $sub['id'] ?? '';
    if (!$subId) return;

    $db->prepare("UPDATE subscriptions SET status = 'cancelled', cancelled_at = NOW() WHERE square_subscription_id = ?")
       ->execute([$subId]);

    // Downgrade user to free
    $stmt = $db->prepare('SELECT user_id FROM subscriptions WHERE square_subscription_id = ? LIMIT 1');
    $stmt->execute([$subId]);
    $row = $stmt->fetch();
    if ($row) {
        $db->prepare('UPDATE users SET tier = \'free\' WHERE id = ?')->execute([$row['user_id']]);
    }
}
