<?php

namespace Bricksforge\ProForms\Actions;

if (!defined('ABSPATH')) exit; // Exit if accessed directly

// Include Stripe library
require_once BRICKSFORGE_PATH . '/includes/vendor/stripe-php/init.php';

// Include Payment Helper for common payment validation
require_once BRICKSFORGE_PATH . '/includes/elements/pro-forms/actions/PaymentHelper.php';

class Stripe
{
    public $name = "stripe";

    /**
     * Create Stripe Checkout Session and redirect user to payment
     *
     * @since 3.1.8
     */
    public function run($form)
    {
        $form_settings = $form->get_settings();
        $form_fields   = $form->get_fields();
        $form_files    = $form->get_uploaded_files();
        $post_id       = $form->get_post_id();
        $form_id       = $form->get_form_id();

        try {
            // Get Stripe API keys from element settings
            $activated_elements = get_option('brf_activated_elements');
            $stripe_settings = null;

            if (is_array($activated_elements)) {
                foreach ($activated_elements as $element) {
                    if (isset($element->id) && $element->id === 5) {
                        $stripe_settings = isset($element->settings) ? $element->settings : null;
                        break;
                    }
                }
            }

            if (empty($stripe_settings) || empty($stripe_settings->stripeSecretKey)) {
                $form->set_result([
                    'action'  => $this->name,
                    'type'    => 'error',
                    'message' => __('Stripe is not configured. Please add your API keys in the Pro Forms settings.', 'bricksforge'),
                ]);
                return ['stripe_redirect' => false];
            }

            $utils = new \Bricksforge\Api\Utils();

            // Decrypt secret key
            $secret_key = $utils->decrypt($stripe_settings->stripeSecretKey);

            if (empty($secret_key)) {
                $form->set_result([
                    'action'  => $this->name,
                    'type'    => 'error',
                    'message' => __('Stripe secret key is missing. Please check your configuration.', 'bricksforge'),
                ]);
                return ['stripe_redirect' => false];
            }

            // Set Stripe API key
            \Stripe\Stripe::setApiKey($secret_key);

            // Get payment amount - support dynamic values from form fields
            $amount_raw = isset($form_settings['stripeAmount']) ? $form->get_form_field_by_id($form_settings['stripeAmount']) : 0;

            // Validate and sanitize amount
            if (!is_numeric($amount_raw) || $amount_raw <= 0) {
                $form->set_result([
                    'action'  => $this->name,
                    'type'    => 'error',
                    'message' => isset($form_settings['stripeErrorMessage']) ? $form_settings['stripeErrorMessage'] : __('Invalid payment amount.', 'bricksforge'),
                ]);
                return ['stripe_redirect' => false];
            }

            // SECURITY: Validate calculation field to prevent price manipulation
            // If the amount comes from a calculation field, we MUST recalculate it server-side
            $price_field = isset($form_settings['stripeAmount']) ? $form_settings['stripeAmount'] : null;
            $is_calculation_valid = PaymentHelper::validate_payment_calculation($amount_raw, $price_field, $post_id, $form);

            if (!$is_calculation_valid) {
                error_log('Bricksforge Stripe Security: Calculation field validation failed. Possible price manipulation attempt.');

                $form->set_result([
                    'action'  => $this->name,
                    'type'    => 'error',
                    'message' => isset($form_settings['stripeErrorMessage']) ? $form_settings['stripeErrorMessage'] : __('Payment amount validation failed. Please try again.', 'bricksforge'),
                ]);
                return ['stripe_redirect' => false];
            }

            // Get currency (default to USD)
            $currency = isset($form_settings['stripeCurrency']) ? sanitize_text_field($form_settings['stripeCurrency']) : 'usd';

            // Convert amount to cents (Stripe requires amounts in smallest currency unit)
            $amount_in_cents = intval(round(floatval($amount_raw) * 100));

            // Get description
            $description = isset($form_settings['stripeDescription']) ? $form->get_form_field_by_id($form_settings['stripeDescription']) : 'Payment';
            $description = sanitize_text_field($description);

            // Get form page URL
            $form_page_url = get_permalink($post_id);

            // If we have a referer header, use that as it's more accurate
            if (isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER'])) {
                $referer = esc_url_raw($_SERVER['HTTP_REFERER']);
                // Only use referer if it's from the same site
                if (strpos($referer, home_url()) === 0) {
                    $form_page_url = $referer;
                }
            }

            // IMPORTANT: Always redirect back to form page after payment
            // This ensures all frontend actions can be executed properly
            // The actual Thank You URL will be used for redirection AFTER webhook completion
            $success_url = add_query_arg([
                'payment_status' => 'success',
                'payment_provider' => 'stripe'
            ], $form_page_url);
            $cancel_url = add_query_arg([
                'payment_status' => 'cancelled',
                'payment_provider' => 'stripe'
            ], $form_page_url);

            // Store the custom Thank You URL separately (if provided)
            // This will be used for final redirection after webhook completes
            $thank_you_url = null;
            if (isset($form_settings['stripeSuccessUrl']) && !empty($form_settings['stripeSuccessUrl'])) {
                $thank_you_url = $form->get_form_field_by_id($form_settings['stripeSuccessUrl']);
                $thank_you_url = esc_url_raw($thank_you_url);
            }

            // Validate URLs
            $success_url = esc_url_raw($success_url);
            $cancel_url = esc_url_raw($cancel_url);

            // Get customer email if provided
            $customer_email = '';
            if (isset($form_settings['stripeCustomerEmail']) && !empty($form_settings['stripeCustomerEmail'])) {
                $customer_email = $form->get_form_field_by_id($form_settings['stripeCustomerEmail']);
                $customer_email = sanitize_email($customer_email);
            }

            // Generate unique session identifier
            $session_identifier = wp_generate_password(32, false);

            // Store form submission data temporarily (expires in 30 minutes)
            // This will be retrieved by the webhook handler
            $transient_key = 'brf_stripe_session_' . $session_identifier;
            $transient_data = [
                'form_id'       => $form_id,
                'post_id'       => $post_id,
                'form_data'     => $form_fields,
                'form_settings' => $form_settings,
                'form_files'    => $form_files,
                'thank_you_url' => $thank_you_url, // Store custom Thank You URL for final redirect
                'timestamp'     => time(),
            ];

            set_transient($transient_key, $transient_data, 30 * MINUTE_IN_SECONDS);

            // Prepare Checkout Session parameters
            $session_params = [
                'payment_method_types' => ['card'],
                'line_items' => [[
                    'price_data' => [
                        'currency' => $currency,
                        'product_data' => [
                            'name' => $description,
                        ],
                        'unit_amount' => $amount_in_cents,
                    ],
                    'quantity' => 1,
                ]],
                'mode' => 'payment',
                'success_url' => add_query_arg('session_id', '{CHECKOUT_SESSION_ID}', $success_url),
                'cancel_url' => $cancel_url,
                'metadata' => [
                    'brf_session_identifier' => $session_identifier,
                    'form_id' => $form_id,
                    'post_id' => $post_id,
                    'site_url' => home_url('/'),
                ],
                'expires_at' => time() + (30 * 60), // Session expires in 30 minutes
            ];

            // Add customer email if provided
            if (!empty($customer_email) && is_email($customer_email)) {
                $session_params['customer_email'] = $customer_email;
            }

            // Create Stripe Checkout Session
            $checkout_session = \Stripe\Checkout\Session::create($session_params);

            // Store the session ID in transient for additional verification
            update_option('brf_stripe_session_' . $checkout_session->id, $session_identifier, false);
            set_transient('brf_stripe_session_' . $checkout_session->id, $session_identifier, 30 * MINUTE_IN_SECONDS);

            // Return success with redirect URL and session identifier
            $form->set_result([
                'action'  => $this->name,
                'type'    => 'success',
                'stripe_redirect' => true,
                'redirect_url' => $checkout_session->url,
                'session_id' => $checkout_session->id,
                'session_identifier' => $session_identifier, // Used to retrieve pending actions after payment
            ]);

            // Also return the result directly so init.php can access it
            return [
                'action'  => $this->name,
                'type'    => 'success',
                'stripe_redirect' => true,
                'redirect_url' => $checkout_session->url,
                'session_id' => $checkout_session->id,
                'session_identifier' => $session_identifier,
            ];
        } catch (\Stripe\Exception\ApiErrorException $e) {
            // Stripe API error
            error_log('Bricksforge Stripe Error: ' . $e->getMessage());

            $form->set_result([
                'action'  => $this->name,
                'type'    => 'error',
                'message' => isset($form_settings['stripeErrorMessage']) ? $form_settings['stripeErrorMessage'] : __('Payment processing error. Please try again.', 'bricksforge'),
            ]);

            return ['stripe_redirect' => false];
        } catch (\Exception $e) {
            // General error
            error_log('Bricksforge Stripe Error: ' . $e->getMessage());

            $form->set_result([
                'action'  => $this->name,
                'type'    => 'error',
                'message' => isset($form_settings['stripeErrorMessage']) ? $form_settings['stripeErrorMessage'] : __('An error occurred. Please try again.', 'bricksforge'),
            ]);

            return ['stripe_redirect' => false];
        }
    }
}
