<?php
/**
 * Payment Service - Stripe Integration
 * Install Stripe SDK: composer require stripe/stripe-php
 */

class PaymentService {
    private $db;
    private $config;
    private $stripe_key;

    public function __construct($db, $config) {
        $this->db = $db;
        $this->config = $config;
        $this->stripe_key = $config['stripe']['secret_key'] ?? null;
        
        // Initialize Stripe
        if (class_exists('\Stripe\Stripe')) {
            \Stripe\Stripe::setApiKey($this->stripe_key);
        }
    }

    /**
     * Create payment intent (for Stripe payment)
     */
    public function createPaymentIntent($invoice_id, $return_url = null) {
        try {
            if (!class_exists('\Stripe\Stripe')) {
                return ['success' => false, 'message' => 'Stripe SDK not installed'];
            }

            // Get invoice details
            $stmt = $this->db->prepare("
                SELECT i.*, g.email, g.name
                FROM folio_charges i
                JOIN bookings b ON i.booking_id = b.id
                JOIN guests g ON b.guest_id = g.id
                WHERE i.id = ?
            ");
            $stmt->execute([$invoice_id]);
            $invoice = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$invoice) {
                return ['success' => false, 'message' => 'Invoice not found'];
            }

            // Create Stripe PaymentIntent
            $intent = \Stripe\PaymentIntent::create([
                'amount' => (int)($invoice['total'] * 100), // Stripe uses cents
                'currency' => 'usd',
                'payment_method_types' => ['card'],
                'description' => 'Invoice #' . $invoice['invoice_number'],
                'receipt_email' => $invoice['email'],
                'metadata' => [
                    'invoice_id' => $invoice_id,
                    'guest_name' => $invoice['name'],
                    'invoice_number' => $invoice['invoice_number']
                ]
            ]);

            // Store payment intent in database
            $stmt = $this->db->prepare("
                INSERT INTO payments (
                    booking_id, amount, payment_method, status, 
                    transaction_id, created_at, updated_at
                ) SELECT booking_id, ?, 'stripe', 'pending', ?, NOW(), NOW()
                FROM folio_charges WHERE id = ?
            ");

            $stmt->execute([
                $invoice['total'],
                $intent->id,
                $invoice_id
            ]);

            return [
                'success' => true,
                'client_secret' => $intent->client_secret,
                'intent_id' => $intent->id,
                'amount' => $invoice['total'],
                'currency' => 'usd'
            ];

        } catch (\Stripe\Exception\ApiErrorException $e) {
            error_log('Stripe error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        } catch (Exception $e) {
            error_log('Payment intent error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Error creating payment'];
        }
    }

    /**
     * Confirm payment
     */
    public function confirmPayment($intent_id, $invoice_id) {
        try {
            if (!class_exists('\Stripe\Stripe')) {
                return ['success' => false, 'message' => 'Stripe SDK not installed'];
            }

            // Get payment intent from Stripe
            $intent = \Stripe\PaymentIntent::retrieve($intent_id);

            if ($intent->status !== 'succeeded') {
                return ['success' => false, 'message' => 'Payment not completed'];
            }

            // Update invoice status to paid
            $stmt = $this->db->prepare("
                UPDATE folio_charges 
                SET status = 'paid', paid_date = NOW()
                WHERE id = ?
            ");
            $stmt->execute([$invoice_id]);

            // Update payment record
            $stmt = $this->db->prepare("
                UPDATE payments
                SET status = 'completed'
                WHERE transaction_id = ?
            ");
            $stmt->execute([$intent_id]);

            // Log activity
            $this->logActivity(null, 'payment.success', 'payment', null, 'Invoice ' . $invoice_id);

            // Queue payment confirmation email
            $this->queueEmail([
                'type' => 'payment_confirmation',
                'invoice_id' => $invoice_id,
                'transaction_id' => $intent_id
            ]);

            return [
                'success' => true,
                'message' => 'Payment completed successfully',
                'invoice_id' => $invoice_id,
                'transaction_id' => $intent_id
            ];

        } catch (\Stripe\Exception\ApiErrorException $e) {
            error_log('Stripe error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        } catch (Exception $e) {
            error_log('Confirm payment error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Error confirming payment'];
        }
    }

    /**
     * Get Stripe public key (for frontend)
     */
    public function getPublicKey() {
        return [
            'success' => true,
            'public_key' => $this->config['stripe']['public_key'] ?? null
        ];
    }

    /**
     * Get payment history for invoice
     */
    public function getPaymentHistory($invoice_id) {
        try {
            $stmt = $this->db->prepare("
                SELECT * FROM payments
                WHERE (
                    SELECT booking_id FROM folio_charges WHERE id = ?
                ) = booking_id
                ORDER BY created_at DESC
            ");
            $stmt->execute([$invoice_id]);
            $payments = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return [
                'success' => true,
                'payments' => $payments
            ];

        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error fetching payment history'];
        }
    }

    /**
     * Process refund
     */
    public function processRefund($transaction_id, $reason = null) {
        try {
            if (!class_exists('\Stripe\Stripe')) {
                return ['success' => false, 'message' => 'Stripe SDK not installed'];
            }

            // Create refund in Stripe
            $refund = \Stripe\Refund::create([
                'payment_intent' => $transaction_id,
                'reason' => $reason ?? 'requested_by_customer'
            ]);

            // Update payment status
            $stmt = $this->db->prepare("
                UPDATE payments
                SET status = 'refunded'
                WHERE transaction_id = ?
            ");
            $stmt->execute([$transaction_id]);

            // Log activity
            $this->logActivity(null, 'payment.refund', 'payment', null, $transaction_id);

            return [
                'success' => true,
                'message' => 'Refund processed',
                'refund_id' => $refund->id
            ];

        } catch (\Stripe\Exception\ApiErrorException $e) {
            error_log('Stripe refund error: ' . $e->getMessage());
            return ['success' => false, 'message' => $e->getMessage()];
        } catch (Exception $e) {
            error_log('Refund error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Error processing refund'];
        }
    }

    /**
     * Handle Stripe webhook
     */
    public function handleWebhook($payload, $signature) {
        try {
            if (!class_exists('\Stripe\Stripe')) {
                return ['success' => false, 'message' => 'Stripe SDK not installed'];
            }

            $webhook_secret = $this->config['stripe']['webhook_secret'] ?? null;

            // Verify webhook signature
            $event = \Stripe\Webhook::constructEvent(
                $payload,
                $signature,
                $webhook_secret
            );

            // Handle different event types
            switch ($event->type) {
                case 'payment_intent.succeeded':
                    $this->handlePaymentSucceeded($event->data->object);
                    break;
                case 'payment_intent.payment_failed':
                    $this->handlePaymentFailed($event->data->object);
                    break;
                case 'charge.refunded':
                    $this->handleChargeRefunded($event->data->object);
                    break;
            }

            return ['success' => true];

        } catch (\Stripe\Exception\SignatureVerificationException $e) {
            error_log('Webhook signature verification failed: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Invalid signature'];
        } catch (Exception $e) {
            error_log('Webhook error: ' . $e->getMessage());
            return ['success' => false, 'message' => 'Error processing webhook'];
        }
    }

    /**
     * Handle payment succeeded webhook
     */
    private function handlePaymentSucceeded($payment_intent) {
        try {
            $invoice_id = $payment_intent->metadata->invoice_id ?? null;

            if ($invoice_id) {
                $stmt = $this->db->prepare("
                    UPDATE folio_charges 
                    SET status = 'paid', paid_date = NOW()
                    WHERE id = ?
                ");
                $stmt->execute([$invoice_id]);

                error_log("Payment succeeded for invoice " . $invoice_id);
            }
        } catch (Exception $e) {
            error_log('Handle payment succeeded error: ' . $e->getMessage());
        }
    }

    /**
     * Handle payment failed webhook
     */
    private function handlePaymentFailed($payment_intent) {
        try {
            error_log("Payment failed: " . $payment_intent->id);
        } catch (Exception $e) {
            error_log('Handle payment failed error: ' . $e->getMessage());
        }
    }

    /**
     * Handle charge refunded webhook
     */
    private function handleChargeRefunded($charge) {
        try {
            $stmt = $this->db->prepare("
                UPDATE payments
                SET status = 'refunded'
                WHERE transaction_id = ?
            ");
            $stmt->execute([$charge->payment_intent]);

            error_log("Charge refunded: " . $charge->id);
        } catch (Exception $e) {
            error_log('Handle refund error: ' . $e->getMessage());
        }
    }

    /**
     * Helper: Queue email
     */
    private function queueEmail($email_data) {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO event_queue (event_type, data, status, created_at)
                VALUES (?, ?, 'pending', NOW())
            ");
            $stmt->execute(['email', json_encode($email_data)]);
        } catch (Exception $e) {
            error_log('Error queuing email: ' . $e->getMessage());
        }
    }

    /**
     * Helper: Log activity
     */
    private function logActivity($user_id, $action, $entity_type, $entity_id, $description = null) {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO activity_log (user_id, action, entity_type, entity_id, description, ip, user_agent)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            ");
            $stmt->execute([
                $user_id,
                $action,
                $entity_type,
                $entity_id,
                $description,
                $_SERVER['REMOTE_ADDR'] ?? '',
                $_SERVER['HTTP_USER_AGENT'] ?? ''
            ]);
        } catch (Exception $e) {
            error_log('Error logging activity: ' . $e->getMessage());
        }
    }
}
