<?php
// ─────────────────────────────────────────────────────────────
//  lib/StripeBooking.php — Stripe checkout + webhook handler
// ─────────────────────────────────────────────────────────────
if (!defined('DB_HOST')) require_once dirname(__DIR__) . '/lib.php';

class StripeBooking {
    private static function stripeConfig(): array {
        $mode = defined('STRIPE_MODE') ? strtolower((string)STRIPE_MODE) : 'test';
        if ($mode !== 'live') $mode = 'test';

        $legacySecret = defined('STRIPE_SECRET_KEY') ? (string)STRIPE_SECRET_KEY : '';
        $legacyPub    = defined('STRIPE_PUBLISHABLE_KEY') ? (string)STRIPE_PUBLISHABLE_KEY : '';
        $legacyWh     = defined('STRIPE_WEBHOOK_SECRET') ? (string)STRIPE_WEBHOOK_SECRET : '';

        $testSecret = defined('STRIPE_TEST_SECRET_KEY') ? (string)STRIPE_TEST_SECRET_KEY : $legacySecret;
        $testPub    = defined('STRIPE_TEST_PUBLISHABLE_KEY') ? (string)STRIPE_TEST_PUBLISHABLE_KEY : $legacyPub;
        $testWh     = defined('STRIPE_TEST_WEBHOOK_SECRET') ? (string)STRIPE_TEST_WEBHOOK_SECRET : $legacyWh;

        $liveSecret = defined('STRIPE_LIVE_SECRET_KEY') ? (string)STRIPE_LIVE_SECRET_KEY : '';
        $livePub    = defined('STRIPE_LIVE_PUBLISHABLE_KEY') ? (string)STRIPE_LIVE_PUBLISHABLE_KEY : '';
        $liveWh     = defined('STRIPE_LIVE_WEBHOOK_SECRET') ? (string)STRIPE_LIVE_WEBHOOK_SECRET : '';

        return [
            'mode' => $mode,
            'secret_key' => $mode === 'live' ? $liveSecret : $testSecret,
            'publishable_key' => $mode === 'live' ? $livePub : $testPub,
            'webhook_secret' => $mode === 'live' ? $liveWh : $testWh,
            'currency' => defined('STRIPE_CURRENCY') ? (string)STRIPE_CURRENCY : 'usd',
            'ready' => ($mode === 'live' ? $liveSecret : $testSecret) !== '',
        ];
    }

    public static function publicConfig(): array {
        $cfg = self::stripeConfig();
        return [
            'mode' => $cfg['mode'],
            'stripe_key' => $cfg['publishable_key'],
            'currency' => $cfg['currency'],
            'stripe_ready' => $cfg['ready'],
        ];
    }

    public static function createCheckout(
        int    $planId,
        string $email,
        string $name,
        string $successUrl,
        string $cancelUrl,
        float  $discountAmount = 0.0
    ): string {
        if (!class_exists('\\Stripe\\Stripe')) {
            throw new \Exception('Stripe SDK not installed. Run: composer require stripe/stripe-php');
        }

        $cfg = self::stripeConfig();
        if (!$cfg['secret_key']) {
            throw new \Exception('Stripe is not configured for current mode');
        }
        \Stripe\Stripe::setApiKey($cfg['secret_key']);

        // Get plan
        $plan = db()->prepare('SELECT * FROM bk_plans WHERE id=? AND is_active=1');
        $plan->execute([$planId]);
        $p = $plan->fetch();
        if (!$p) throw new \Exception('Plan not found');

        $unitAmount = (int)($p['price'] * 100);
        $lineItems  = [[
            'price_data' => [
                'currency'     => $cfg['currency'],
                'unit_amount'  => $unitAmount,
                'product_data' => [
                    'name'        => $p['name'],
                    'description' => $p['description'] ?? '',
                ],
            ],
            'quantity' => 1,
        ]];

        // Apply flat discount as a negative line item
        if ($discountAmount > 0.0) {
            $discountCents = (int)($discountAmount * 100);
            $lineItems[] = [
                'price_data' => [
                    'currency'     => $cfg['currency'],
                    'unit_amount'  => -min($discountCents, $unitAmount - 50),
                    'product_data' => ['name' => 'Promo Discount'],
                ],
                'quantity' => 1,
            ];
        }

        $session = \Stripe\Checkout\Session::create([
            'customer_email'         => $email,
            'payment_method_types'   => ['card'],
            'line_items'             => $lineItems,
            'mode'                   => 'payment',
            'success_url'            => $successUrl . (str_contains($successUrl, '?') ? '&' : '?') . 'session_id={CHECKOUT_SESSION_ID}',
            'cancel_url'             => $cancelUrl,
            'metadata'               => [
                'plan_id'         => $planId,
                'customer_email'  => $email,
                'customer_name'   => $name,
                'discount_amount' => $discountAmount,
            ],
        ]);

        return $session->url;
    }

    public static function handleWebhook(string $payload, string $sigHeader): void {
        if (!class_exists('\Stripe\Stripe')) {
            throw new \Exception('Stripe SDK not installed');
        }

        $cfg = self::stripeConfig();
        if (!$cfg['secret_key']) {
            throw new \Exception('Stripe is not configured for current mode');
        }
        $secret = $cfg['webhook_secret'];
        \Stripe\Stripe::setApiKey($cfg['secret_key']);

        $event = \Stripe\Webhook::constructEvent($payload, $sigHeader, $secret);

        if ($event->type === 'checkout.session.completed') {
            $session = $event->data->object;
            $meta    = $session->metadata;
            $planId  = (int) $meta->plan_id;
            $email   = $meta->customer_email;
            $name    = $meta->customer_name;

            // Get or create customer
            $custStmt = db()->prepare('SELECT id FROM bk_customers WHERE email=?');
            $custStmt->execute([$email]);
            $cust = $custStmt->fetch();
            if (!$cust) {
                db()->prepare('INSERT INTO bk_customers (email, name) VALUES (?, ?)')
                    ->execute([$email, $name]);
                $customerId = (int) db()->lastInsertId();
            } else {
                $customerId = (int) $cust['id'];
            }

            // Get plan (including session_limit added in Phase 1)
            $planStmt = db()->prepare('SELECT * FROM bk_plans WHERE id=?');
            $planStmt->execute([$planId]);
            $plan = $planStmt->fetch();
            if (!$plan) return;

            $startsAt  = date('Y-m-d H:i:s');
            $expiresAt = date('Y-m-d H:i:s', strtotime('+' . $plan['duration_days'] . ' days'));

            // sessions_remaining: NULL for unlimited plans, plan value for session-limited
            $sessionLimit     = isset($plan['session_limit']) ? (int)$plan['session_limit'] : 0;
            $sessionsRemaining = $sessionLimit > 0 ? $sessionLimit : null;

            // ── Renewal check: does an active membership already exist? ──
            $existStmt = db()->prepare(
                'SELECT id FROM bk_memberships
                 WHERE customer_id = ? AND plan_id = ? AND status = "active"
                 ORDER BY created_at DESC LIMIT 1'
            );
            $existStmt->execute([$customerId, $planId]);
            $existingId = $existStmt->fetchColumn();

            if ($existingId) {
                // Renewal — extend expiry, reset session counter, keep same row
                db()->prepare(
                    'UPDATE bk_memberships
                     SET expires_at         = ?,
                         sessions_remaining = ?,
                         stripe_payment_id  = ?,
                         stripe_session_id  = ?,
                         status             = "active"
                     WHERE id = ?'
                )->execute([
                    $expiresAt,
                    $sessionsRemaining,
                    $session->payment_intent,
                    $session->id,
                    $existingId,
                ]);
            } else {
                // New membership
                db()->prepare(
                    'INSERT INTO bk_memberships
                     (customer_id, plan_id, starts_at, expires_at, status,
                      sessions_remaining, stripe_payment_id, stripe_session_id, activated_by)
                     VALUES (?, ?, ?, ?, "active", ?, ?, ?, "stripe")'
                )->execute([
                    $customerId, $planId, $startsAt, $expiresAt,
                    $sessionsRemaining,
                    $session->payment_intent, $session->id,
                ]);
            }

            // Send confirmation email
            $sessionLine = $sessionsRemaining !== null
                ? "<p>Sessions included: <strong>{$sessionsRemaining}</strong></p>"
                : '';
            $html = "<h2>Membership Activated — {$plan['name']}</h2>
                     <p>Hi {$name},</p>
                     <p>Your <strong>{$plan['name']}</strong> membership is now active.</p>
                     <p>Expires: <strong>{$expiresAt}</strong></p>
                     {$sessionLine}
                     <p><a href=\"" . APP_URL . "/booking/book.php\">Book an appointment now →</a></p>";
            $text = "Membership Active — {$plan['name']}\nExpires: {$expiresAt}\nBook: " . APP_URL . "/booking/book.php";
            try {
                send_mail($email, $name, "Membership Active — {$plan['name']}", $html, $text);
            } catch (\Throwable $e) {
                error_log('Booking email error: ' . $e->getMessage());
            }
        }
    }
}
