<?php
// ═══════════════════════════════════════════════════════════
//  FICTION IGNITION — api/lib/square.php
//  Square API wrapper for subscriptions
//  Install SDK: composer require square/square
// ═══════════════════════════════════════════════════════════

declare(strict_types=1);

require_once __DIR__ . '/config.php';

/**
 * Returns the correct Square base URL based on environment
 */
function square_base_url(): string {
    return env('SQUARE_ENV') === 'production'
        ? 'https://connect.squareup.com'
        : 'https://connect.squareupsandbox.com';
}

/**
 * Make an authenticated request to Square API
 */
function square_request(string $method, string $path, array $body = []): array {
    $url = square_base_url() . $path;
    $ch  = curl_init($url);

    $headers = [
        'Square-Version: 2024-01-18',
        'Authorization: Bearer ' . env('SQUARE_ACCESS_TOKEN'),
        'Content-Type: application/json',
    ];

    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_CUSTOMREQUEST  => strtoupper($method),
        CURLOPT_TIMEOUT        => 15,
    ]);

    if (!empty($body)) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error    = curl_error($ch);
    curl_close($ch);

    if ($error) {
        throw new RuntimeException('Square cURL error: ' . $error);
    }

    $data = json_decode($response, true);
    if ($httpCode >= 400) {
        $msg = $data['errors'][0]['detail'] ?? 'Square API error ' . $httpCode;
        throw new RuntimeException($msg);
    }

    return $data ?? [];
}

/**
 * Create or retrieve a Square Customer for the given user
 * Returns the Square customer_id
 */
function square_get_or_create_customer(string $userId, string $email, string $name): string {
    $db   = fi_db();
    // Check if already has a subscription row with a customer ID
    $stmt = $db->prepare('SELECT square_customer_id FROM subscriptions WHERE user_id = ? LIMIT 1');
    $stmt->execute([$userId]);
    $existing = $stmt->fetchColumn();
    if ($existing) return $existing;

    // Create new customer in Square
    [$firstName, ...rest] = explode(' ', $name, 2);
    $lastName = implode(' ', $rest) ?: '';

    $response = square_request('POST', '/v2/customers', [
        'idempotency_key' => 'create-customer-' . $userId,
        'given_name'      => $firstName,
        'family_name'     => $lastName,
        'email_address'   => $email,
        'reference_id'    => $userId,
    ]);

    return $response['customer']['id'];
}

/**
 * Create a Square subscription
 * Returns the subscription array from Square
 */
function square_create_subscription(
    string $customerId,
    string $planKey,
    string $cardNonce      // from Square Web Payments SDK
): array {
    $planIds = [
        'starter'    => env('SQUARE_PLAN_STARTER'),
        'writer'     => env('SQUARE_PLAN_WRITER'),
        'author_pro' => env('SQUARE_PLAN_AUTHOR_PRO'),
    ];

    if (!isset($planIds[$planKey])) {
        throw new RuntimeException('Invalid plan key: ' . $planKey);
    }

    // First, create/save the card
    $cardResp = square_request('POST', '/v2/cards', [
        'idempotency_key' => 'card-' . $customerId . '-' . time(),
        'source_id'       => $cardNonce,
        'card'            => ['customer_id' => $customerId],
    ]);
    $cardId = $cardResp['card']['id'];

    // Create the subscription
    $subResp = square_request('POST', '/v2/subscriptions', [
        'idempotency_key' => 'sub-' . $customerId . '-' . time(),
        'location_id'     => env('SQUARE_LOCATION_ID'),
        'plan_variation_id' => $planIds[$planKey],
        'customer_id'     => $customerId,
        'card_id'         => $cardId,
        'start_date'      => date('Y-m-d'),
    ]);

    return [
        'subscription' => $subResp['subscription'],
        'card_id'      => $cardId,
    ];
}

/**
 * Cancel a Square subscription
 */
function square_cancel_subscription(string $squareSubscriptionId): void {
    square_request('POST', "/v2/subscriptions/{$squareSubscriptionId}/cancel");
}

/**
 * Verify Square webhook signature
 * Prevents fake webhook events
 */
function square_verify_webhook(string $body, string $signature, string $url): bool {
    $sigKey = env('SQUARE_WEBHOOK_SIGNATURE_KEY');
    if (!$sigKey) return false;

    $combined = $url . $body;
    $expected = base64_encode(hash_hmac('sha256', $combined, $sigKey, true));
    return hash_equals($expected, $signature);
}
