<?php
/**
 * Includes: Webhooks
 */
if (! defined('ABSPATH')) {
    die('Sorry, you cannot access this page.');
}

add_action('init', 'chama_process_stripe_webhook');
if (! function_exists('chama_process_stripe_webhook')):
    function chama_process_stripe_webhook()
{
        // Only process if the specific listener param is set and equals 'stripe'
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (isset($_GET['chama-listener']) && sanitize_text_field(wp_unslash($_GET['chama-listener'])) === 'stripe') {
            // Retrieve the raw POST body sent by Stripe as JSON.
            // The file_get_contents('php://input') call is used solely to access Stripe's raw webhook payload, which is sent as a JSON body (not as $_POST).
            // We avoid inspecting the entire $_GET stack and only reference $_GET['chama-listener']
            // This is required for validating and processing webhook events.
            $payload = @file_get_contents('php://input');
            if (empty($payload)) {
                http_response_code(400);
                echo 'Missing payload.';
                exit;
            }
            $event = null;
            try {
                $event = \ChamaWP\Vendor\Stripe\Event::constructFrom(
                    json_decode($payload, true)
                );
            } catch (\UnexpectedValueException $e) {
                // Invalid payload
                http_response_code(400);
                die('⚠️  Webhook error while parsing basic request.');
                exit();
            }
            // Switch through known Stripe webhook event types
            switch ($event->type) {
                case 'payment_intent.succeeded':
                    $payment_intent = $event->data->object; // contains a \Stripe\PaymentIntent
                                                            // Then define and call a method to handle the successful payment intent.
                    chama_handle_payment_intent_succeeded($payment_intent);
                    break;
                case 'payment_method.attached':
                    $payment_method = $event->data->object; // contains a \Stripe\PaymentMethod
                                                            // Then define and call a method to handle the successful attachment of a PaymentMethod.
                                                            // handlePaymentMethodAttached($paymentMethod);
                    break;
                case 'account.updated':
                    $account = $event->data->object; // contains a \Stripe\Account
                                                     // Then define and call a method to handle the successful update of an account.
                    chama_handle_account_updated($account);
                    break;
                case 'invoice_payment.paid':
                case 'invoice.paid':
                    $invoice = $event->data->object; // contains a \Stripe\Invoice
                                                     // Then define and call a method to handle the successful payment of subscription invoice.
                    chama_handle_invoice_paid($invoice);
                    break;
                case 'invoice.payment_failed':
                    $invoice = $event->data->object; // contains a \Stripe\Invoice
                                                     // Then define and call a method to handle failed invoice payment.
                    chama_handle_invoice_payment_failed($invoice);
                    break;
                case 'customer.subscription.deleted':
                    $status       = 'canceled';
                    $subscription = $event->data->object; // contains a \Stripe\Subscription
                                                          // Then define and call a method to handle inactive subscription.
                    chama_handle_subscription_deactivation($subscription, true, $status);
                    break;
                case 'customer.subscription.resumed':
                    $subscription = $event->data->object; // contains a \Stripe\Subscription
                                                          // Then define and call a method to handle subscription resumed.
                    chama_handle_subscription_resumed($subscription, true);
                    break;
                case 'customer.subscription.updated':
                    $subscription = $event->data->object; // contains a \Stripe\Subscription
                                                          // Then define and call a method to handle subscription resumed.
                    chama_handle_subscription_updated($subscription);
                    break;
                default:
                    // Unknown or unhandled event type
                    http_response_code(400);
                    echo 'Unhandled event type.';
                    exit;
            }

            // Acknowledge receipt to Stripe
            http_response_code(200);
            echo 'Webhook processed.';
        }
    }
endif;

function chama_handle_account_updated($account)
{
    $account_id = $account->Id;
    $email      = $account->Email;
    $mode       = chama_is_live_mode() ? 'live' : 'test';
    if ($account->details_submitted) {
        if ($account->payouts_enabled && $account->charges_enabled) {
            update_option('chama_stripe_' . $mode . '_account_completed_onboarding', true);
            update_option('chama_stripe_' . $mode . '_webhook_initialized', true);
        }
    }
    die('✔️ Successfully updated account.');
}
function chama_handle_payment_intent_succeeded($payment_intent)
{
    try {
        $mode                   = chama_is_live_mode() ? 'live' : 'test';
        $payment_intent_id      = $payment_intent->id;
        $type                   = $payment_intent->metadata->type;
        $currency               = $payment_intent->currency;
        $currency_minimum       = chama_get_currency_minimum($currency);
        $total_amount           = 0;
        $total_amount_formatted = '0.00';
        if ($payment_intent->amount) {
            $total_amount_cents     = sanitize_text_field($payment_intent->amount);
            $total_amount           = $total_amount_cents / $currency_minimum;
            $total_amount_formatted = number_format(floatval($total_amount), 2);
        }
        $cpt               = '';
        $role              = '';
        $from              = sprintf("%s <%s>", CHAMA_FROM_NAME, CHAMA_FROM_EMAIL);
        $from_header       = 'From: ' . $from;
        $headers           = ['Content-Type: text/html; charset=UTF-8', $from_header];
        $supporter_message = $admin_message = $description = $cpt = $commission_request = $commission_price = $commission_shipping = $commission_addons = $commission_addons_html = $shipping_location = $shipping_display_cost = $commission_display_price = $commission_shipping_address = '';
        $payment           = $payment_args           = null;
        $receipt_id        = 0;
        $description       = $payment_intent->description;
        if ($payment_intent_id) {
            $payment_args = [
                'meta_key'       => 'chama_stripe_payment_intent_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
                'meta_value'     => $payment_intent_id,               // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
                'post_status'    => 'any',
                'posts_per_page' => 1,
            ];
        }

        switch ($type) {
            case 'one-time':
                $role                      = 'chama_donor';
                $cpt                       = 'chama_donation';
                $payment_args['post_type'] = $cpt;
                $payment                   = get_posts($payment_args);

                if ($payment && $payment[0]->ID) {
                    $receipt_id = $payment[0]->ID;
                }

                $user_id = get_post_meta($receipt_id, 'chama_user_id', true);

                /*=============================================ADD TO ACTIVE CAMPAIGN TOTAL=============================================*/
                if ($user_id) {
                    chama_add_to_campaign($user_id, $receipt_id, $total_amount, $cpt);
                }

                break;
            case 'membership':
                $role                      = 'chama_member';
                $cpt                       = 'chama_subscription';
                $payment_args['post_type'] = $cpt;
                $payment                   = get_posts($payment_args);

                if ($payment && $payment[0]->ID) {
                    $receipt_id = $payment[0]->ID;
                }
                $user_id = get_post_meta($receipt_id, 'chama_user_id', true);
                /*=============================================UPDATE TIER SLOTS=============================================*/
                $subtract_from_tier_slots = ! get_post_meta($receipt_id, $cpt . '_subtracted_from_slots', true);
                if ($subtract_from_tier_slots && $subtract_from_tier_slots > 0) {
                    $tier_id            = $payment_intent->metadata->tier_id;
                    $current_tier_slots = 0;

                    if ($tier_id) {
                        if (get_post_meta($tier_id, 'member_limit', true)) {
                            $current_tier_slots = get_post_meta($tier_id, 'member_limit', true);
                            if ($current_tier_slots > 0) {
                                $new_tier_slots = $current_tier_slots - 1;
                                update_post_meta($tier_id, 'member_limit', $new_tier_slots);
                                update_post_meta($receipt_id, $cpt . '_subtracted_from_slots', true);
                            }

                        }

                    }
                }

                /*=============================================ADD TO ACTIVE CAMPAIGN TOTAL=============================================*/
                if ($user_id) {
                    chama_add_to_campaign($user_id, $receipt_id, $total_amount, $cpt);
                }

                break;
            case 'crowdfunding':
                $role                      = 'chama_funder';
                $cpt                       = 'chama_fund';
                $payment_args['post_type'] = $cpt;
                $payment                   = get_posts($payment_args);

                if ($payment && $payment[0]->ID) {
                    $receipt_id = $payment[0]->ID;
                }
                $user_id = get_post_meta($receipt_id, 'chama_user_id', true);
                /*=============================================ADD TO CAMPAIGN TOTAL=============================================*/
                $campaign_id = $payment_intent->metadata->campaign_id;
                if ($user_id) {
                    chama_add_to_campaign($user_id, $receipt_id, $total_amount, $cpt, $campaign_id);
                }

                break;
            case 'commission':
                $role                      = 'chama_comissioner';
                $cpt                       = 'chama_com_order';
                $payment_args['post_type'] = $cpt;
                $payment                   = get_posts($payment_args);

                if ($payment && $payment[0]->ID) {
                    $receipt_id = $payment[0]->ID;
                }
                $user_id = get_post_meta($receipt_id, 'chama_user_id', true);
                $commission_request       = $payment_intent->metadata->commission_request;
                $commission_price         = $payment_intent->metadata->commission_price;
                $commission_shipping      = $payment_intent->metadata->commission_shipping;
                $commission_price_cents   = $commission_price * CHAMA_CURRENCY_MINIMUM;
                $commission_display_price = chama_get_formatted_price($commission_price_cents);
                if ($payment_intent->metadata->commission_addons) {
                    $commission_addons = $payment_intent->metadata->commission_addons;
                }
                /*=============================================SUBTRACT FROM SLOTS=============================================*/
                $subtract_from_commission_slots = ! get_post_meta($receipt_id, $cpt . '_subtracted_from_slots', true);
                if ($subtract_from_commission_slots && $subtract_from_commission_slots > 0) {
                    $commission_id            = $payment_intent->metadata->commission_id;
                    $current_commission_slots = 0;

                    if ($commission_id) {
                        if (get_post_meta($commission_id, 'commission_limit', true)) {
                            $current_commission_slots = get_post_meta($commission_id, 'commission_limit', true);
                            $new_commission_slots     = $current_commission_slots - 1;
                            update_post_meta($commission_id, 'commission_limit', $new_commission_slots);
                            update_post_meta($receipt_id, $cpt . '_subtracted_from_slots', true);
                        }

                    }
                }
                /*=============================================UPDATE SHIPPING ADDRESS=============================================*/
                if ($payment_intent->shipping) {

                    $commission_shipping_address                                         = [];
                    $commission_shipping_address[0]['commission_shipping_address_key']   = 'Name';
                    $commission_shipping_address[0]['commission_shipping_address_value'] = $payment_intent->shipping->name;
                    $commission_shipping_address[1]['commission_shipping_address_key']   = 'Address Line 1';
                    $commission_shipping_address[1]['commission_shipping_address_value'] = $payment_intent->shipping->address->line1;
                    $array_index                                                         = 2;
                    if ($payment_intent->shipping->address->line2) {
                        $commission_shipping_address[$array_index]['commission_shipping_address_key']   = 'Address Line 2';
                        $commission_shipping_address[$array_index]['commission_shipping_address_value'] = $payment_intent->shipping->address->line2;
                        $array_index++;
                    }
                    if ($payment_intent->shipping->address->state) {
                        $commission_shipping_address[$array_index]['commission_shipping_address_key']   = 'State';
                        $commission_shipping_address[$array_index]['commission_shipping_address_value'] = $payment_intent->shipping->address->state;
                        $array_index++;
                    }
                    $commission_shipping_address[$array_index]['commission_shipping_address_key']   = 'Postal Code';
                    $commission_shipping_address[$array_index]['commission_shipping_address_value'] = $payment_intent->shipping->address->postal_code;
                    $array_index++;

                    $country                                                                        = chama_get_country_from_code($payment_intent->shipping->address->country);
                    $commission_shipping_address[$array_index]['commission_shipping_address_key']   = 'Country';
                    $commission_shipping_address[$array_index]['commission_shipping_address_value'] = $country;
                    $array_index++;

                    update_post_meta($receipt_id, $cpt . '_shipping_address', sanitize_text_field($commission_shipping_address));
                }
                break;
            default:
        }
        if (get_option('chama_supporter_enable_payment_notification') || get_option('chama_admin_enable_payment_notification')) {
            if (get_option($cpt . '_receipt_template')) {
                $supporter_message = get_option($cpt . '_receipt_template');
                $supporter_message = wpautop($supporter_message);
                $admin_message     = get_option('chama_new_' . $cpt . '_template');
                $admin_message     = wpautop($admin_message);
                switch ($cpt) {
                    case 'chama_donation':
                        //replace donation email template variables
                        foreach ([
                            "{date}"       => gmdate('F j, Y'),
                            "{amount}"     => $total_amount_formatted,
                            "{receipt_id}" => $receipt_id,
                        ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}
                        foreach ([
                            "{date}"       => gmdate('F j, Y'),
                            "{amount}"     => CHAMA_SYMBOL . $total_amount_formatted,
                            "{receipt_id}" => $receipt_id,
                        ] as $k => $v) {$admin_message = str_replace($k, $v, $admin_message);}
                        $supporter_subject = 'Donation Receipt';
                        $admin_subject     = 'New Donation - #' . $receipt_id;
                        break;
                    case 'chama_subscription':
                        //replace subscription email template variables
                        $today = gmdate('Y-m-d');
                        foreach ([
                            "{description}"  => $description,
                            "{date}"         => gmdate('F j, Y'),
                            "{renewal-date}" => gmdate("F, j, Y", strtotime('+1 month', strtotime($today))),
                            "{amount}"       => $total_amount_formatted,
                            "{receipt_id}"   => $receipt_id,
                        ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}
                        foreach ([
                            "{description}"  => $description,
                            "{date}"         => gmdate('F j, Y'),
                            "{renewal-date}" => gmdate("F, j, Y", strtotime('+1 month', strtotime($today))),
                            "{amount}"       => CHAMA_SYMBOL . $total_amount_formatted,
                            "{receipt_id}"   => $receipt_id,
                        ] as $k => $v) {$admin_message = str_replace($k, $v, $admin_message);}
                        $supporter_subject = 'Subscription Receipt';
                        $admin_subject     = 'New Subscription - #' . $receipt_id;
                        break;
                    case 'chama_fund':
                        //replace fund email template variables
                        foreach ([
                            "{description}" => $description,
                            "{date}"        => gmdate('F j, Y'),
                            "{amount}"      => $total_amount_formatted,
                            "{receipt_id}"  => $receipt_id,
                        ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}
                        foreach ([
                            "{description}" => $description,
                            "{date}"        => gmdate('F j, Y'),
                            "{amount}"      => CHAMA_SYMBOL . $total_amount_formatted,
                            "{receipt_id}"  => $receipt_id,
                        ] as $k => $v) {$admin_message = str_replace($k, $v, $admin_message);}
                        $supporter_subject = 'Crowfunding Receipt';
                        $admin_subject     = 'New Crowfunding - #' . $receipt_id;
                        break;
                    case 'chama_com_order':
                        //replace commission order email template variables
                        $shipping              = explode('|', $commission_shipping);
                        $shipping_cost         = $shipping[1];
                        $shipping_location     = $shipping[0];
                        $shipping_cost_cents   = $shipping_cost * CHAMA_CURRENCY_MINIMUM;
                        $shipping_display_cost = chama_get_formatted_price($shipping_cost_cents);
                        if ($commission_addons) {
                            $addons = explode(',', $commission_addons);

                            foreach ($addons as $addon) {
                                $item                   = explode('|', $addon);
                                $item_amount            = $item[1];
                                $item_amount_cents      = $item_amount * CHAMA_CURRENCY_MINIMUM;
                                $item_display_amount    = chama_get_formatted_price($item_amount_cents);
                                $commission_addons_html = $commission_addons_html . '<strong>' . esc_html($item[0]) . '</strong>: ' . esc_html($item_display_amount) . "<br/>";
                            }
                        }

                        foreach ([
                            "{description}"       => $description,
                            "{price}"             => $commission_display_price,
                            "{date}"              => gmdate('F j, Y'),
                            "{request}"           => $commission_request,
                            "{add_ons}"           => $commission_addons_html,
                            "{shipping-location}" => $shipping_location,
                            "{shipping-fee}"      => $shipping_display_cost,
                            "{amount}"            => CHAMA_SYMBOL . $total_amount_formatted,
                            "{receipt_id}"        => $receipt_id,
                        ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}
                        foreach ([
                            "{description}"       => $description,
                            "{price}"             => $commission_display_price,
                            "{date}"              => gmdate('F j, Y'),
                            "{request}"           => $commission_request,
                            "{add_ons}"           => $commission_addons_html,
                            "{shipping-location}" => $shipping_location,
                            "{shipping-fee}"      => $shipping_display_cost,
                            "{amount}"            => CHAMA_SYMBOL . $total_amount_formatted,
                            "{receipt_id}"        => $receipt_id,
                        ] as $k => $v) {$admin_message = str_replace($k, $v, $admin_message);}
                        $supporter_subject = 'Commission Receipt';
                        $admin_subject     = 'New Commission - #' . $receipt_id;
                        break;
                    default:
                }
                if ($payment_intent->receipt_email) {
                    if (get_option('chama_supporter_enable_payment_notification')) {
                        chama_send_email($payment_intent->receipt_email, $supporter_subject, $supporter_message, $headers);
                    }
                    if (get_option('chama_admin_enable_payment_notification')) {
                        chama_send_email(get_option('chama_admin_email'), $admin_subject, $admin_message, $headers);
                    }
                }

            }
        }

        if ($receipt_id) {
            update_post_meta($receipt_id, 'chama_payment_status', 'complete');
            //update user role
            $user = $user_id ? get_user_by('id', $user_id) : false;
            chama_add_user_to_role($user, $role, true, 0);

        } else {
            die('No receipt id for payment intent: ' . esc_html($payment_intent_id));
        }
        update_option('chama_stripe_' . $mode . '_webhook_initialized', true);
        die('✔️ Successfully processed payment.');
    } catch (Exception $e) {
        die(esc_html('Error in ' . $e->getFile() . ' on line ' . $e->getLine() . ': ' . $e->getMessage()));
    }

}
function chama_handle_invoice_paid($invoice)
{
    try {

        $mode       = chama_is_live_mode() ? 'live' : 'test';
        $secret_key = chama_is_live_mode() ? CHAMA_STRIPE_LIVE_SECRET_KEY : CHAMA_STRIPE_TEST_SECRET_KEY;
        if ($secret_key) {
            $stripe = new \ChamaWP\Vendor\Stripe\StripeClient(
                $secret_key // API Secret here
            );
            $invoice_id               = $invoice->invoice;
            $invoice_payment_id       = $invoice->id;
            $stripe_payment_intent_id = null;
            $stripe_subscription_id   = $tier_id   = $description   = '';
            $subscription_metadata    = null;

            /*=============================================GET PAYMENT INTENT ID=============================================*/
            //first check if the payment intent is available via older API payload
            $stripe_payment_intent_id = $invoice->payment_intent ?? '';

            //we have no payment intent, try to get it through updated API (from Basil.2025-05-28)
            if (! $stripe_payment_intent_id) {
                $payment = $invoice->payment;
                if (! $payment) {
                    die(esc_html("❌ No payment field for invoice: {$invoice_payment_id}."));
                }
                if ($payment->type === 'payment_intent') {
                    $stripe_payment_intent_id = $payment->payment_intent;

                } else {
                    die(esc_html("❌ No payment intent on the payment field for invoice: {$invoice_payment_id}."));
                }
            }

            /*=============================================REQUERY INVOICE FOR FULL DATA=============================================*/
            $invoice = $stripe->invoices->retrieve(
                $invoice_id,
                ['expand' => ['payment_intent', 'subscription']]
            );

            //Check for subscription in multiple possible locations
            if (! empty($invoice->subscription) && ! empty($invoice->subscription_details)) {
                // Primary location
                $stripe_subscription_id = $invoice->subscription;
                $subscription_metadata  = $invoice->subscription_details->metadata ?? [];
            } elseif ($invoice && ! empty($invoice->parent) && ! empty($invoice->parent->subscription_details)) {
                // Nested in parent
                $subscription_details   = $invoice->parent->subscription_details;
                $stripe_subscription_id = $subscription_details->subscription ?? '';
                $subscription_metadata  = $subscription_details->metadata ?? [];
            } else {
                die( esc_html("❌ No subscription field for invoice: {$invoice_id}."));
            }

            // Fetch subscription if found
            if ($stripe_subscription_id) {
                $tier_id     = $subscription_metadata['tier_id'] ?? '';
                $description = $subscription_metadata['description'] ?? '';

            }

            /*=============================================PROCESS SUBSCRIPTION=============================================*/
            if ($stripe_payment_intent_id && ($invoice->billing_reason == 'subscription_create' || $invoice->billing_reason == 'subscription_cycle')) {
                /*=============================================INITIALIZE VARIABLES=============================================*/
                $stripe_billing_reason  = $invoice->billing_reason;
                $total_amount_cents     = $invoice->amount_paid;
                $customer_email         = $invoice->customer_email;
                $stripe_customer_id     = $invoice->customer;
                $currency               = $invoice->currency;
                $total_amount_formatted = '0.00';
                $total_amount           = 0;

                if ($total_amount_cents) {
                    $currency_minimum       = chama_get_currency_minimum($currency);
                    $total_amount           = $total_amount_cents / $currency_minimum;
                    $total_amount_formatted = number_format(floatval($total_amount), 2);
                }

                $from                        = sprintf("%s <%s>", CHAMA_FROM_NAME, CHAMA_FROM_EMAIL);
                $from_header                 = 'From: ' . $from;
                $headers                     = ['Content-Type: text/html; charset=UTF-8', $from_header];
                $supporter_message           = $admin_message;
                $subscription                = $subscription_args                = null;
                $receipt_id                  = 0;
                $user_id                     = 0;
                $user                        = null;
                $stripe_current_period_start = $stripe_current_period_end = '';

                /*=============================================INVOICE CYCLE=============================================*/
                if ($stripe_subscription_id) {
                    $stripe_subscription = $stripe->subscriptions->retrieve(
                        $stripe_subscription_id, []
                    );
                    if ($stripe_subscription) {

                        $stripe_current_period_start = gmdate("F, j, Y", $stripe_subscription->current_period_start);
                        $stripe_current_period_end   = gmdate("F, j, Y", $stripe_subscription->current_period_end);
                    }
                }
                /*
                if ($invoice->period_start) {
                $stripe_current_period_start = gmdate("F, j, Y", $invoice->period_start);
                }
                if ($invoice->period_end) {
                $stripe_current_period_end = gmdate("F, j, Y", $invoice->period_end);
                }
                 */

                /*=============================================GET STRIPE CUSTOMER=============================================*/
                $stripe_customer = $stripe->customers->retrieve($stripe_customer_id, []);
                if ($stripe_customer && $stripe_customer->metadata->user_id) {
                    $user_id = $stripe_customer->metadata->user_id;
                }

                /*=============================================FIRST TIME PAYMENT=============================================*/
                if ($stripe_billing_reason == 'subscription_create') {
                    if ($stripe_payment_intent_id) {
                        $subscription_args = [
                            'meta_key'       => 'chama_stripe_payment_intent_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
                            'meta_value'     => $stripe_payment_intent_id,        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
                            'post_status'    => 'any',
                            'posts_per_page' => 1,
                            'post_type'      => 'chama_subscription',
                        ];
                    }
                    $subscription = get_posts($subscription_args);
                    if ($subscription && $subscription[0]->ID) {
                        $receipt_id = $subscription[0]->ID;
                        $user_id    = get_post_meta($receipt_id, 'chama_user_id', true);
                        $user       = $user_id ? get_user_by('id', $user_id) : false;
                    }
                    /*=============================================CANCEL PREVIOUS SUBSCRIPTION=============================================*/
                    if ($receipt_id && $user_id) {
                        chama_cancel_current_subscription($user_id, true, true);
                    }
                    /*=============================================UPDATE TIER SLOTS=============================================*/
                    $subtract_from_tier_slots = ! get_post_meta($receipt_id, 'chama_subscription_subtracted_from_slots', true);
                    if ($subtract_from_tier_slots && $subtract_from_tier_slots > 0) {
                        $current_tier_slots = 0;

                        if ($tier_id) {
                            if (get_post_meta($tier_id, 'member_limit', true)) {
                                $current_tier_slots = get_post_meta($tier_id, 'member_limit', true);
                                if ($current_tier_slots > 0) {
                                    $new_tier_slots = $current_tier_slots - 1;
                                    update_post_meta($tier_id, 'member_limit', $new_tier_slots);
                                    update_post_meta($receipt_id, 'chama_subscription_subtracted_from_slots', true);
                                }
                            }

                        }
                    }
                    /*=============================================UPDATE USER & SUBSCRIPTION=============================================*/
                    $role = 'chama_member';

                    if ($receipt_id) {

                        $subscription_level = get_post_meta($receipt_id, 'chama_subscription_total_amount', true);
                        update_post_meta($receipt_id, 'chama_payment_status', 'complete');

                        //update user role
                        $user_id = get_post_meta($receipt_id, 'chama_user_id', true);
                        $user    = $user_id ? get_user_by('id', $user_id) : false;
                        chama_add_user_to_role($user, $role, true, $tier_id);

                        //update user
                        update_user_meta($user_id, 'chama_stripe_customer_id', $stripe_customer_id);
                        update_user_meta($user_id, 'chama_stripe_subscription_id', $stripe_subscription_id);
                        update_user_meta($user_id, 'chama_subscription_status', 'active');
                        update_post_meta($receipt_id, 'chama_subscription_status', 'active');
                        update_user_meta($user_id, 'chama_tier_id', $tier_id);
                        update_user_meta($user_id, 'chama_tier_description', $description);
                        update_user_meta($user_id, 'chama_subscription_level', $subscription_level);

                    } else {
                        die('No receipt id for payment intent: ' . esc_html($stripe_payment_intent_id));
                    }
                    /*=============================================EMAIL NOTIFICATION=============================================*/
                    if (get_option('chama_supporter_enable_payment_notification') || get_option('chama_admin_enable_payment_notification')) {
                        if (get_option('chama_subscription_receipt_template')) {
                            $supporter_message = get_option('chama_subscription_receipt_template');
                            $supporter_message = wpautop($supporter_message);
                            $admin_message     = get_option('chama_new_subscription_template');
                            $admin_message     = wpautop($admin_message);
                            //replace subscription email template variables
                            $today = gmdate('Y-m-d');
                            foreach ([
                                "{description}"  => $description,
                                "{date}"         => gmdate('F j, Y'),
                                "{renewal-date}" => gmdate("F, j, Y", strtotime('+1 month', strtotime($today))),
                                "{amount}"       => $total_amount_formatted,
                                "{receipt_id}"   => $receipt_id,
                            ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}
                            foreach ([
                                "{description}"  => $description,
                                "{date}"         => gmdate('F j, Y'),
                                "{renewal-date}" => gmdate("F, j, Y", strtotime('+1 month', strtotime($today))),
                                "{amount}"       => CHAMA_SYMBOL . $total_amount_formatted,
                                "{receipt_id}"   => $receipt_id,
                            ] as $k => $v) {$admin_message = str_replace($k, $v, $admin_message);}
                            $supporter_subject = 'Subscription Receipt';
                            $admin_subject     = 'New Subscription - #' . $receipt_id;

                            if ($customer_email && get_option('chama_supporter_enable_payment_notification')) {
                                chama_send_email($customer_email, $supporter_subject, $supporter_message, $headers);
                            }
                            if (get_option('chama_admin_enable_payment_notification')) {
                                chama_send_email(get_option('chama_admin_email'), $admin_subject, $admin_message, $headers);
                            }

                        }
                    }

                }
                /*=============================================END FIRST TIME PAYMENT=============================================*/
                /*=============================================RENEWAL=============================================*/
                if ($stripe_billing_reason == 'subscription_cycle') {
                    $cpt_args = [
                        'post_type'   => 'chama_subscription',
                        'post_status' => 'publish',
                    ];
                    $receipt_id = wp_insert_post($cpt_args);
                    if ($receipt_id) {
                        if ($customer_email) {
                            $user = null;
                            if ($user_id) {
                                $user = get_user_by('id', $user_id);
                            } else {
                                $user = get_user_by('email', $customer_email);
                            }

                            if ($user) {
                                $user_id = $user->ID;
                                update_post_meta($receipt_id, 'chama_user_id', $user_id);
                                update_post_meta($receipt_id, 'chama_email', $customer_email);
                                if ($user->first_name && $user->last_name) {
                                    update_post_meta($receipt_id, 'chama_full_name', $user->first_name . ' ' . $user->last_name);
                                }
                            }

                        }
                        if ($stripe_customer_id) {
                            update_post_meta($receipt_id, 'chama_stripe_customer_id', sanitize_text_field($stripe_customer_id));
                        }
                        if ($description) {
                            update_post_meta($receipt_id, 'chama_subscription_description', sanitize_text_field($description));
                        }
                        if ($tier_id) {
                            update_post_meta($receipt_id, 'chama_subscription_item_id', sanitize_text_field($tier_id));
                        }

                        update_post_meta($receipt_id, 'chama_payment_status', 'complete');
                        if ($total_amount_cents) {
                            update_post_meta($receipt_id, 'chama_subscription_currency', sanitize_text_field($currency));
                            update_post_meta($receipt_id, 'chama_subscription_total_amount', sanitize_text_field($total_amount_formatted));
                            update_user_meta($user_id, 'chama_subscription_level', $total_amount_formatted);
                        }

                        update_post_meta($receipt_id, 'chama_subscription_date_time', gmdate('Y-m-d H:i:s'));
                        update_post_meta($receipt_id, 'chama_is_test_subscription', ! chama_is_live_mode());
                        update_post_meta($receipt_id, 'chama_stripe_payment_intent_id', $stripe_payment_intent_id);
                        if ($stripe_subscription_id) {
                            update_user_meta($user_id, 'chama_subscription_status', 'active');
                            update_post_meta($receipt_id, 'chama_subscription_status', 'active');
                            update_post_meta($receipt_id, 'chama_subscription_event', 'renewal');
                            update_post_meta($receipt_id, 'chama_stripe_subscription_id', $stripe_subscription_id);
                        }
                        /*=============================================EMAIL NOTIFICATION=============================================*/
                        if (get_option('chama_supporter_enable_renewal_notification')) {
                            if (get_option('chama_subscription_receipt_template')) {
                                $supporter_message = get_option('chama_subscription_receipt_template');
                                $supporter_message = wpautop($supporter_message);
                                //replace subscription email template variables
                                $today = gmdate('Y-m-d');
                                foreach ([
                                    "{description}"  => $description,
                                    "{date}"         => gmdate('F j, Y'),
                                    "{renewal-date}" => gmdate("F, j, Y", strtotime('+1 month', strtotime($today))),
                                    "{amount}"       => $total_amount_formatted,
                                    "{receipt_id}"   => $receipt_id,
                                ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}

                                $supporter_subject = 'Subscription Receipt';

                                if ($customer_email && get_option('chama_supporter_enable_renewal_notification')) {
                                    chama_send_email($customer_email, $supporter_subject, $supporter_message, $headers);
                                }

                            }
                        }
                    }

                }
                /*=============================================END RENEWAL=============================================*/
                /*=============================================UPDATES FOR BOTH FIRST TIME PAYMENTS AND RENEWALS=============================================*/
                /*=============================================UPDATE PERIODS=============================================*/
                if ($stripe_current_period_start) {
                    update_user_meta($user_id, 'chama_subscription_current_period_start', $stripe_current_period_start);
                }
                if ($stripe_current_period_end) {
                    update_user_meta($user_id, 'chama_subscription_current_period_end', $stripe_current_period_end);
                    update_post_meta($receipt_id, 'chama_subscription_renewal_date', $stripe_current_period_end);
                }
                /*=============================================UPDATE PAYMENT METHOD=============================================*/
                $payment_methods = $stripe->paymentMethods->all([
                    'type'     => 'card',
                    'limit'    => 1,
                    'customer' => $stripe_customer_id,
                ]);

                if ($payment_methods) {
                    $latest_payment_method    = $payment_methods->data[0];
                    $payment_method_id        = $latest_payment_method->id;
                    $payment_method_brand     = $latest_payment_method->card->brand;
                    $payment_method_exp_month = $latest_payment_method->card->exp_month;
                    $payment_method_exp_year  = $latest_payment_method->card->exp_year;
                    $payment_method_last4     = $latest_payment_method->card->last4;
                    update_user_meta($user_id, 'chama_payment_method_id', $payment_method_id);
                    update_user_meta($user_id, 'chama_payment_method_brand', ucfirst($payment_method_brand));
                    update_user_meta($user_id, 'chama_payment_method_expiration', $payment_method_exp_month . '/' . $payment_method_exp_year);
                    update_user_meta($user_id, 'chama_payment_method_last4', 'Last 4 digits:' . $payment_method_last4);
                }
                /*=============================================END UPDATES FOR BOTH FIRST TIME PAYMENTS AND RENEWALS=============================================*/
                update_option('chama_stripe_' . $mode . '_webhook_initialized', true);

                /*=============================================ADD TO ACTIVE CAMPAIGN TOTAL=============================================*/
                chama_add_to_campaign($user_id, $receipt_id, $total_amount, 'chama_subscription');
            } else {
                die( esc_html("❌ No subscription billing data for invoice: {$invoice_id}."));
            }
        }
        die('✔️ Successfully processed invoice.');
    } catch (Exception $e) {

        die(esc_html('Error in ' . $e->getFile() . ' on line ' . $e->getLine() . ': ' . $e->getMessage()));
    }
}

function chama_handle_invoice_payment_failed($invoice)
{
    try {
        $mode       = chama_is_live_mode() ? 'live' : 'test';
        $secret_key = chama_is_live_mode() ? CHAMA_STRIPE_LIVE_SECRET_KEY : CHAMA_STRIPE_TEST_SECRET_KEY;
        if ($secret_key) {
            $stripe = new \ChamaWP\Vendor\Stripe\StripeClient(
                $secret_key // API Secret here
            );
            /*=============================================INITIALIZE VARIABLES=============================================*/
            $from                     = sprintf("%s <%s>", CHAMA_FROM_NAME, CHAMA_FROM_EMAIL);
            $from_header              = 'From: ' . $from;
            $headers                  = ['Content-Type: text/html; charset=UTF-8', $from_header];
            $supporter_message        = $admin_message        = $description        = '';
            $stripe_payment_intent_id = $invoice->payment_intent;
            $total_amount_cents       = $invoice->amount_due;
            $stripe_subscription_id   = $invoice->subscription;
            $tier_id                  = $invoice->subscription_details->metadata->tier_id;
            $customer_email           = $invoice->customer_email;
            $total_amount_formatted   = '0.00';
            $renewal_date             = '';
            if ($total_amount_cents) {
                $currency_minimum       = chama_get_currency_minimum($currency);
                $total_amount           = $total_amount_cents / $currency_minimum;
                $total_amount_formatted = number_format(floatval($total_amount), 2);
            }

            $subscription = $subscription_args = null;
            $receipt_id   = 0;
            $description  = $invoice->subscription_details->metadata->description;
            if ($stripe_payment_intent_id) {
                $subscription_args = [
                    'meta_key'       => 'chama_stripe_payment_intent_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
                    'meta_value'     => $stripe_payment_intent_id,        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
                    'post_status'    => 'any',
                    'posts_per_page' => 1,
                    'post_type'      => 'chama_subscription',
                ];
            }

            $subscription = get_posts($subscription_args);

            if ($subscription && $subscription[0]->ID) {
                $receipt_id = $subscription[0]->ID;
            }

            $stripe_subscription = $stripe->subscriptions->retrieve(
                $stripe_subscription_id, []
            );
            if ($stripe_subscription->current_period_end) {
                $renewal_date = gmdate("F, j, Y", $stripe_subscription->current_period_end);
            }
            /*=============================================EMAIL NOTIFICATION=============================================*/
            if (get_option('chama_supporter_enable_failed_payment_notification')) {
                if (get_option('chama_payment_failure_template')) {
                    $supporter_message = get_option('chama_payment_failure_template');
                    $supporter_message = wpautop($supporter_message);

                    //replace subscription email template variables
                    $today = gmdate('Y-m-d');
                    foreach ([
                        "{description}"  => $description,
                        "{renewal-date}" => $renewal_date,
                        "{amount}"       => $total_amount_formatted,
                    ] as $k => $v) {$supporter_message = str_replace($k, $v, $supporter_message);}

                    $supporter_subject = 'Notice Regarding Your ' . get_bloginfo('name') . ' Account';

                    if ($customer_email && get_option('chama_supporter_enable_payment_notification')) {
                        chama_send_email($customer_email, $supporter_subject, $supporter_message, $headers);
                    }

                }
            }
        }
        die('✔️ Successfully handled failed payment.');
    } catch (Exception $e) {

        die(esc_html($e->getMessage()));
    }
}

function chama_handle_subscription_updated($stripe_subscription)
{
    try {
        $stripe_subscription_status   = $stripe_subscription->status;
        $stripe_subscription_statuses = ["incomplete", "active", "paused"];
        if (! in_array($stripe_subscription_status, $stripe_subscription_statuses)) {
            chama_handle_subscription_deactivation($stripe_subscription, true, $stripe_subscription_status);
        }

        die('✔️ Successfully handled subscription update.');
    } catch (Exception $e) {

        die(esc_html($e->getMessage()));
    }
}
