<?php

/**
 * WooCommerce Support
 */
add_action('after_setup_theme', function () {
    add_theme_support('woocommerce');
    add_theme_support('wc-product-gallery-zoom');
    add_theme_support('wc-product-gallery-lightbox');
    add_theme_support('wc-product-gallery-slider');
    remove_action('woocommerce_before_main_content', 'woocommerce_breadcrumb', 20, 0);

    /* Disable all payment gateways at checkout */
    add_filter('woocommerce_cart_needs_payment', '__return_false');

    // Disable different woocommerce notifications
    add_filter('woocommerce_cart_item_removed_notice_type', '__return_false');
    add_filter('wc_add_to_cart_message_html', '__return_false');

    // when a new item gets added to the cart, empty the cart of previous items
    // and purge add ons
    add_filter('woocommerce_add_to_cart_validation', function ($passed, $product_id, $quantity) {
        if (!WC()->cart->is_empty()) {
            WC()->cart->empty_cart();
        }
        $_SESSION["addOns"] = [];
        $_SESSION["one-time"] = [];
        return $passed;
    }, 20, 3);


    add_filter('woocommerce_checkout_fields', function ($fields) {
        // $fields['order']['order_comments']['placeholder'] = 'My new placeholder';
        return $fields;
    });
});

// WooCommerce Fee Stuff
// first, wordpress doesn't use sessions, so let's enable those
add_action('init', function () {
    if (!session_id()) {
        session_start();
    }
});
// and clean up sessions on logout
add_action('wp_logout', function () {
    session_destroy();
});

/**
 * Allow only one coupon per order in WooCommerce.
 */
add_filter('woocommerce_apply_individual_use_coupon', 'only_one_coupon_allowed', 10, 2);
function only_one_coupon_allowed($apply, $coupon) {
    // Check if a coupon is already applied
    if (WC()->cart->has_discount()) {
        // Remove other applied coupons except the current one
        WC()->cart->empty_discounts();
        WC()->cart->apply_coupon($coupon->get_code());
        return false; // Do not apply the new coupon
    }
    return $apply;
}

add_filter('woocommerce_add_error', 'customize_coupon_error_message', 10, 1);
function customize_coupon_error_message($error) {
    // Check if the error message is related to a coupon already applied
    if (strpos($error, 'Coupon code already applied!') !== false) {
        return '';
    }
    return $error;
}

function get_current_shipping_comment() {
    // Get the chosen shipping methods from the cart
    $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods');
    if (empty($chosen_shipping_methods)) {
        return null;
    }

    foreach ($chosen_shipping_methods as $chosen_method) {
        $method_parts = explode(':', $chosen_method); // Split method ID and instance ID
        $shipping_method_id = $method_parts[0];
        $instance_id = isset($method_parts[1]) ? $method_parts[1] : '';

        // Build the option name for the instance-specific settings
        $option_name = 'woocommerce_' . $shipping_method_id . '_' . $instance_id . '_settings';
        $instance_settings = get_option($option_name);

        // Check if `shipping_comment` exists
        if (!empty($instance_settings) && isset($instance_settings['shipping_comment'])) {
            return $instance_settings['shipping_comment']; // Return the first found Salesforce ID
        }
    }

    return null; // No `shipping_comment` found
}

/**
 * Generates a cart summary with accurate total calculation and full details
 *
 * @param bool $showCheckoutButton Whether to show the checkout button
 * @return string Rendered cart summary
 */
function generateCartSummary($showCheckoutButton = true) {
    global $product;

    // Ensure WooCommerce calculates all totals
    WC()->cart->calculate_totals();

    $cartItem = getFirstCartItem();
    $parentName = $cartItem['data']->get_parent_data()['title'];
    $product = getProductDetails($cartItem["product_id"]);

    $ratePlan = getRatePlan();
    $rateMultiplier = ($ratePlan === 'Annually') ? 12 : (($ratePlan === 'Semi-Annually') ? 6 : 1);

    // Base product pricing
    $basePrice = $cartItem['data']->get_regular_price();
    $isSmartwatch = ($parentName === "Smartwatch");

    // Setup fee setup
    $setupFeeName = $isSmartwatch ? "Device Fee" : "Setup Fee";
    $setupFee = $isSmartwatch ? 159.00 : 99.95;


    $isAarpMember = WC()->session->get('aarp_discount') === true;
    $activationDiscount = 0;

    if ($isAarpMember && !$isSmartwatch) {
        $discountedMonthlyRate = round($base_price * 0.85, 2);
        $setupFee = 99.95;
        $activationDiscount = 50.00;
    } else {
        $discountedMonthlyRate = $base_price;
    }
    // Apply AARP discount if eligible
    $discountedMonthlyRate = $isAarpMember ? round($basePrice * 0.85, 2) : $basePrice;
    $variable_price = round($discountedMonthlyRate * $rateMultiplier, 2);

    // Setup Fee & Activation Discount
    //$setupFee = 99.95;
    $activationDiscount = ($isAarpMember && $parentName !== 'Smartwatch') ? 50.00 : 0;

    // Professional Install Check and Cost
    $professionalInstallLabel = $_SESSION['one-time']['Professional Install']['label'] ?? '';
    $professionalInstallCost = $_SESSION['one-time']['Professional Install']['price'] ?? 0;

    // Add-ons and their total price calculation
    $totalAddonPrice = 0;
    $adjustedAddons = [];
    $addonLabels = [];
    if (isset($_SESSION['addOns']) && is_array($_SESSION['addOns'])) {
        foreach ($_SESSION['addOns'] as $addOn) {
            $addOnLabel = $addOn['label'];
            $addOnPrice = ($addOnLabel === 'Key Lockbox' && $ratePlan === 'Annually') ? 0 : $addOn['price'] * $rateMultiplier;
            if (!in_array($addOnLabel, $addonLabels)) {
                $adjustedAddons[] = ['name' => $addOnLabel, 'price' => $addOnPrice];
                $addonLabels[] = $addOnLabel;
                $totalAddonPrice += $addOnPrice;
            }
        }
    }

    // Determine if free shipping applies
    $defaultShippingCost = 29.95;
    $freeShippingApplied = $isAarpMember || ($ratePlan === 'Annually' || $ratePlan === 'Semi-Annually') || $professionalInstallCost > 0;
    $finalShippingCost = $freeShippingApplied ? 0 : $defaultShippingCost;

    // Calculate total cart value
    $totalCart = round($variable_price + $setupFee + $professionalInstallCost + $totalAddonPrice + $finalShippingCost - $activationDiscount, 2);

    // Retrieve applied coupons
    $couponSummary = [];
    $couponDescription = [];
    foreach (WC()->cart->get_applied_coupons() as $coupon_code) {
        $coupon = new WC_Coupon($coupon_code);
        $couponSummary[] = $coupon_code;
        $couponDescription[] = $coupon->get_description();
    }

    // Render with original structure and components
    return site()->render("cart_summary", array_merge($product, [
        "variation"             => $ratePlan,
        'variable_price'        => $variable_price,
        'addonPrice'            => $totalAddonPrice,
        'adjustedAddons'        => $adjustedAddons,
        'fallDetectionLabel'    => getAddonLabel('Fall Detection'),
        'fallDetectionPrice'    => getAddonPrice('Fall Detection') * $rateMultiplier,
        'protectionPlan'        => getAddonLabel('Protection Plan'),
        'protectionPlanprice'   => getAddonPrice('Protection Plan') * $rateMultiplier,
        'keyLockboxlabel'       => getAddonLabel('Key Lockbox'),
        'keylockboxprice'       => ($ratePlan === 'Annually') ? 0 : getAddonPrice('Key Lockbox') * $rateMultiplier,
        'one-time'              => $professionalInstallLabel,
        'pro-one-time'          => $professionalInstallCost,
        'setupFeeName'          => $setupFeeName,
        'activationFeeAmount'   => $setupFee,
        'activationDiscount'    => $activationDiscount > 0 ? -$activationDiscount : null,
        'defaultShipping'       => $defaultShippingCost,
        'freeShipping'          => $freeShippingApplied ? $defaultShippingCost : null,
        'totalDue'              => $totalCart,
        'couponList'            => implode(', ', $couponSummary),
        'couponDescription'     => implode('<br>', array_filter($couponDescription)),
        'showCheckoutButton'    => $showCheckoutButton,
    ]));
}

/**
 * Add custom fees to WooCommerce order based on cart items and conditions.
 *
 * @param WC_Order $order WooCommerce order object.
 * @param array $data Additional data for the order.
 */
function add_custom_meta_to_order($order, $data) {
    $existingFees = array_map(function ($fee) {
        return sanitize_title($fee->get_name());
    }, $order->get_items('fee'));

    $cartItem = getFirstCartItem();
    if (!$cartItem) return;

    $parentName = $cartItem['data']->get_parent_data()['title'];
    $isSmartwatch = ($parentName === "Smartwatch");

    // Determine fee name and amount
    $feeName = $isSmartwatch ? "Device Fee" : "Setup Fee";
    $feeAmount = $isSmartwatch ? 159.00 : 99.95;

    // Add Device/Setup Fee
    if (!in_array(sanitize_title($feeName), $existingFees)) {
        $feeItem = new WC_Order_Item_Fee();
        $feeItem->set_name($feeName);
        $feeItem->set_total($feeAmount);
        $order->add_item($feeItem);
    }

    // Professional Install Fee
    $proInstall = $_SESSION["one-time"]["Professional Install"] ?? null;
    if ($proInstall && !in_array(sanitize_title("Professional Install"), $existingFees)) {
        $installFeeItem = new WC_Order_Item_Fee();
        $installFeeItem->set_name("Professional Install");
        $installFeeItem->set_total(99.00); // Specific fee amount
        $order->add_item($installFeeItem);
    }

    // Recalculate order totals after adding fees
    $order->calculate_totals();
}

add_action('woocommerce_checkout_create_order', 'add_custom_meta_to_order', 20, 2);

/**
 * Retrieves the default title and cost for the "Shipping" flat rate method from WooCommerce settings.
 *
 * @return array|null Array containing 'title' and 'cost' if found, or null if not found.
 */
function get_default_shipping_info() {
    $zones = WC_Shipping_Zones::get_zones();
    $shipping_info = [
        'title' => null,
        'cost'  => null,
    ];

    // Iterate over each zone to find the 'flat_rate' method titled 'Shipping'
    foreach ($zones as $zone) {
        foreach ($zone['shipping_methods'] as $method) {
            if ($method->id === 'flat_rate' && $method->title === 'Shipping') {
                $shipping_info['title'] = $method->title;

                // Try to retrieve the cost directly from the method's instance options
                if (method_exists($method, 'get_instance_option')) {
                    $cost = $method->get_instance_option('cost');
                    if (!empty($cost)) {
                        $shipping_info['cost'] = $cost;
                        error_log("Shipping Method Title: {$shipping_info['title']}");
                        error_log("Shipping Method Default Cost: {$shipping_info['cost']}");
                    }
                }

                // Fallback if cost retrieval fails
                $shipping_info['cost'] = 'N/A';
                error_log("Shipping Method Cost not found using get_instance_option; using fallback 'N/A'.");
                return $shipping_info;
            }
        }
    }

    return null;
}

/**
 * Calculate the variable price based on the rate plan
 *
 * @param float $basePrice The base price of the product
 * @param string|null $ratePlan The rate plan (e.g., "Monthly", "Semi-Annually", "Annually")
 * @return float The adjusted price based on the rate plan
 */
function calculateVariablePrice($basePrice, $ratePlan) {
    if (!is_numeric($basePrice)) {
        return 0;  // Prevent non-numeric value issues
    }

    switch ($ratePlan) {
        case 'Annually':
            return $basePrice * 12;  // Annual plan = monthly price * 12
        case 'Semi-Annually':
            return $basePrice * 6;   // Semi-annual plan = monthly price * 6
        case 'Monthly':
        default:
            return $basePrice;       // Monthly plan = base price
    }
}

/**
 * Get the first item in the cart
 */
function getFirstCartItem() {
    foreach (WC()->cart->get_cart() as $item) {
        return $item;
    }
}

/**
 * Retrieve product details based on ID
 */
function getProductDetails($productId) {
    // Ensure regular price is fetched correctly
    return site()->getPost($productId, [
        "title",
        "thumbnail",
        "acf.activation_fee",
        "acf.fee_type",
        "meta._regular_price",  // This field might not be necessary anymore
        "shipCoupon",
        "shipCouponName",
        "defaultShipping",
        "shippingName",
        "couponList",
        "couponTotal",
        "activationFeeName",
        "activationFeeAmount",
        "defaultshippingTitle",
        "defaultshippingCost",
    ]);
}

/**
 * Calculate the monthly costs of the cart
 */
function calculateMonthlyCosts($cartContents) {
    $total = 0;
    foreach ($cartContents as $item) {
        $total += $item['data']->get_regular_price();
    }
    return $total;
}

/**
 * Retrieve the rate plan from the cart item's variation attributes
 *
 * @return string|null The rate plan, or null if not found
 */
function getRatePlan() {
    $cart = WC()->cart;
    foreach ($cart->get_cart() as $cart_item) {
        if (isset($cart_item['variation']['attribute_rate-plan'])) {
            return $cart_item['variation']['attribute_rate-plan'];
        }
    }
    return null; // Return null if no rate plan is found
}

/**
 * Retrieve applied coupons and their details
 */
function getAppliedCoupons() {
    $appliedCoupons = WC()->cart->get_applied_coupons();
    $couponDetails = [
        'coupon_title' => '',
        'coupon_amount' => 0,
        'couponSummary' => '',
        'coupon_description' => ''
    ];

    foreach ($appliedCoupons as $couponCode) {
        $coupon = new WC_Coupon($couponCode);
        $couponDetails['coupon_title'] = $coupon->get_code();
        $couponDetails['coupon_amount'] += $coupon->get_amount();
        $couponDetails['coupon_description'] = $coupon->get_description();
    }

    return $couponDetails;
}

/**
 * Calculate the total cart value based on product, monthly costs, and applied coupons
 */
function calculateTotalCart($basePrice, $activationFee, $finalShippingCost, $ratePlan) {
    // Define multipliers based on the rate plan
    $rateMultiplier = 1;
    if ($ratePlan === "Annually") {
        $rateMultiplier = 12;
    } elseif ($ratePlan === "Semi-Annually") {
        $rateMultiplier = 6;
    }

    $variablePrice = $basePrice * $rateMultiplier;
    $totalCart = $variablePrice + $activationFee + $finalShippingCost;

    return $totalCart;
}

/**
 * Get the label for a specific add-on
 */
function getAddonLabel($label) {
    return $_SESSION["addOns"][$label]["label"];
}

/**
 * Get the price for a specific add-on
 */
function getAddonPrice($label) {
    return $_SESSION["addOns"][$label]["price"];
}

/**
 * Calculate the total price for all add-ons
 */
function calculateAddonPrices() {
    // Check if addOns is set and is an array
    if (!isset($_SESSION["addOns"]) || !is_array($_SESSION["addOns"])) {
        //error_log("Warning: \$_SESSION['addOns'] is not set or is not an array.");
        return 0;  // Return default price if addOns is missing or invalid
    }

    // Calculate total price from add-ons
    $addonPrices = 0;
    foreach ($_SESSION["addOns"] as $addOn) {
        // Ensure each addOn has a price
        if (isset($addOn["price"])) {
            $addonPrices += $addOn["price"];
        } else {
            //error_log("Warning: Add-on missing 'price' key.");
        }
    }

    return $addonPrices;
}

/**
 * Retrieve the selected shipping type
 */
function getShippingType() {
    $shippingMethodId = WC()->session->get('chosen_shipping_methods')[0];
    return get_title_shipping_method_from_method_id($shippingMethodId);
}

/**
 * Get the cost of shipping, providing free shipping for annual or semi-annual plans
 *
 * @param string|null $ratePlan The selected rate plan
 * @return float Shipping cost
 */
function getShippingCost($ratePlan = null) {
    // Check for Professional Install add-on in the session or cart
    $proInstallSelected = isset($_SESSION["one-time"]["Professional Install"]);

    // Apply free shipping for annual and semi-annual rate plans or if Professional Install is selected
    if ($ratePlan === 'Annually' || $ratePlan === 'Semi-Annually' || $proInstallSelected) {
        WC()->session->set('chosen_shipping_methods', ['free_shipping']);
        return 0.00;
    }

    $packages = WC()->shipping->get_packages();

    // Check if we have shipping packages
    if (!empty($packages)) {
        // Get the chosen shipping method ID
        $chosen_method = WC()->session->get('chosen_shipping_methods')[0] ?? '';

        // Get the first package (there might be multiple in some setups)
        $package = $packages[0];

        // Check if the shipping method exists in the package rates
        if (isset($package['rates'][$chosen_method])) {
            return $package['rates'][$chosen_method]->cost;
        }
    }

    // Fallback shipping price if none is found
    return 29.95;
}

/**
 * Get the discount applied through shipping coupons
 */
function getShippingDiscount() {
    return WC()->cart->get_coupon_discount_totals()['shipping'] ?? 0;
}

/**
 * Get the free shipping name, if any
 */
function getFreeShippingName() {
    foreach (WC()->cart->get_applied_coupons() as $couponCode) {
        $coupon = new WC_Coupon($couponCode);
        if ($coupon->get_free_shipping()) {
            return "Free Shipping";
        }
    }
    return "";
}

/**
 * Get the cost of professional install
 */
function getProfessionalInstallCost() {
    return $_SESSION["one-time"]["Professional Install"]["price"] ?? 99.00;
}

function get_title_shipping_method_from_method_id( $method_rate_id = '' ){
    if( ! empty( $method_rate_id ) ){
        $method_key_id = str_replace( ':', '_', $method_rate_id );
        $option_name = 'woocommerce_'.$method_key_id.'_settings';
        return get_option( $option_name, true )['title'];

    } else {
        return false;
    }
}
function add_administration_fees() {
    WC()->cart->add_fee( 'Processing Fee', 2.5 );
}

/**
 * custom woocommerce order fields
 */
$additionalWooFields = [
    "subscriber_first_name" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "First Name",
        "required" => true,
    ],
    "subscriber_last_name" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Last Name",
        "required" => true,
    ],
    "subscriber_address_1" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Address 1",
        "required" => true,
    ],
    "subscriber_address_2" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Address 2 (Apt, Suite, etc.)",
    ],
    "subscriber_zip" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Zip Code",
        "required" => true,
    ],
    "subscriber_city" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "City",
        "required" => true,
    ],
    "subscriber_state" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "State",
        "required" => true,
    ],
    "subscriber_email" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Email Address",
    ],
    "subscriber_phone" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Phone Number",
    ],
    "caregiver_relation" => [
        "type" => "select",
        "label" => "Relation",
        "options" => [
            "Brother" => "Brother",
            "Daughter" => "Daughter",
            "Father" => "Father",
            "Friend" => "Friend",
            "Granddaughter" => "Granddaughter",
            "Grandson" => "Grandson",
            "In-law" => "In-law",
            "Mother" => "Mother",
            "Neighbor" => "Neighbor",
            "Relative" => "Relative",
            "Sister" => "Sister",
            "Son" => "Son",
            "Spouse" => "Spouse",
            "Other" => "Other",
        ],
        "required" => true,
    ],
    "caregiver_first_name" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "First Name",
        "required" => true,
    ],
    "caregiver_last_name" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Last Name",
        "required" => true,
    ],
    "caregiver_email" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Email Address",
    ],
    "caregiver_phone" => [
        "type" => "text",
        "label" => "",
        "placeholder" => "Phone Number",
    ],
    "card_number" => [
        "type" => "number",
        "label" => "Credit Card",
        "required" => true,
    ],
    "ccv" => [
        "type" => "number",
        "label" => "CCV",
        "required" => true,
    ],
    "expiration_month" => [
        "type" => "number",
        "label" => "Expiration Month",
        "required" => true,
        "attrs" => ["min" => 1, "max" => 12, "step" => 1]
    ],
    "expiration_year" => [
        "type" => "number",
        "label" => "Expiration Year",
        "required" => true,
        "attrs" => ["min" => 2022, "max" => 2032, "step" => 1]
    ],
    "SESSpromoid" => [
        "type" => "hidden",
        "label" => "Promotion ID",
    ],
    "SESSpromotion_description" => [
        "type" => "hidden",
        "label" => "Promotion Description",
    ],
    "SESScoupon_code" => [
        "type" => "hidden",
        "label" => "Coupon Code",
    ],
];

add_action('woocommerce_before_checkout_billing_form', function ($checkout) use ($additionalWooFields) {
    $dto = [];
    foreach ($additionalWooFields as $key => $field) {
        ob_start();
        $customAttributes = ["v-model" => $key];
        if ($field["attrs"]) {
            $customAttributes = array_merge($customAttributes, $field["attrs"]);
        }
        woocommerce_form_field($key, [
            'type' => $field["type"],
            'class' => $field["classes"] ?? ['my-field-class orm-row-wide'],
            'input_class' => $field["input_classes"] ?? [],
            'label_class' => $field["label_classes"] ?? [],
            'label' => $field["label"] ?? $key,
            'required' => $field["placeholder"] ?? false,
            'placeholder' => $field["placeholder"] ?? "",
            'options' => $field["options"] ?? [],
            'custom_attributes' => $customAttributes,
        ], $checkout->get_value($key));
        $fieldHTML = ob_get_contents();
        ob_end_clean();

        $dto[$key] = $fieldHTML;
    }

    echo site()->render("checkout-step-1", $dto);
});

function showCardFields()
{
    global $additionalWooFields;
    $dto = [];
    foreach ($additionalWooFields as $key => $field) {
        if (!in_array($key, ["card_number", "ccv", "expiration_month", "expiration_year"])) {
            continue;
        }
        ob_start();
        $customAttributes = ["v-model" => $key];
        if ($field["attrs"]) {
            $customAttributes = array_merge($customAttributes, $field["attrs"]);
        }
        woocommerce_form_field($key, [
            'type' => $field["type"],
            'class' => $field["classes"] ?? ['my-field-class orm-row-wide'],
            'input_class' => $field["input_classes"] ?? [],
            'label_class' => $field["label_classes"] ?? [],
            'label' => $field["label"] ?? $key,
            'required' => $field["placeholder"] ?? false,
            'placeholder' => $field["placeholder"] ?? "",
            'options' => $field["options"] ?? [],
            'custom_attributes' => $customAttributes,
        ], null);
        $fieldHTML = ob_get_contents();
        ob_end_clean();

        $dto[$key] = $fieldHTML;
    }
    echo site()->render("card-fields", $dto);
}

add_action('woocommerce_checkout_update_order_meta', function ($orderID) use ($additionalWooFields) {
    foreach ($additionalWooFields as $key => $field) {
        if (isset($_POST[$key])) {
            $value = esc_attr($_POST[$key]);
            if ($key === "card_number") {
                $parts = str_split($value);
                $output = "";
                for ($i = 0; $i < count($parts); $i++) {
                    if ($i < count($parts) - 4) {
                        $output .= "*";
                    } else {
                        $output .= $parts[$i];
                    }
                }
                $value = $output;
            }
            update_post_meta($orderID, $key, $value);
        }
    }
});

add_action('woocommerce_admin_order_data_after_shipping_address', function ($order) use ($additionalWooFields) {
    $dto = [
        "subscriber-data" => [],
        "caregiver-data" => [],
    ];
    foreach ($additionalWooFields as $key => $field) {
        $meta = get_post_meta($order->get_id(), $key, true);
        $dataType = (substr($key, 0, 10) === "subscriber") ? "subscriber-data" : "caregiver-data";
        $dto[$dataType][] = [
            "label" => $field["label"] ? $field["label"] : $field["placeholder"],
            "value" => $meta ?: "",
        ];
    }
    echo site()->render("order_details_in_admin", $dto);
});

add_filter( 'woocommerce_order_shipping_to_display_shipped_via', '__return_false' );

/**
 * Update order emails to include all the extra stuff
 */
add_filter('woocommerce_email_order_meta_fields', function ($fields, $sent_to_admin, $order) use ($additionalWooFields) {
    foreach ($additionalWooFields as $key => $value) {
        $fields[$key] = [
            'label' => strlen($value["label"]) ? $value["label"] : $value["placeholder"],
            'value' => get_post_meta($order->get_id(), $key, true),
        ];
    }

    if (count($order->get_coupon_codes())) {
        $fields["applied_coupons"] = [
            "label" => "Applied Coupons",
            "value" => implode(", ", $order->get_coupon_codes()),
        ];
    }
    return $fields;
}, 10, 3);

// Apply Rate Multiplier and AARP Discount to Each Cart Item
add_action('woocommerce_before_calculate_totals', 'apply_multiplier_and_discount_to_cart_items', 10, 1);
function apply_multiplier_and_discount_to_cart_items($cart) {
    // Exit if in the admin area or cart is empty
    if (is_admin() || !did_action('woocommerce_before_calculate_totals') || $cart->is_empty()) {
        return;
    }

    // Determine the rate plan and AARP discount status
    $rate_plan = getRatePlan();
    $is_aarp_discount = WC()->session->get('aarp_discount') === true;

    // Define the rate multiplier based on the rate plan
    $rate_multiplier = 1;
    if ($rate_plan === 'Annually') {
        $rate_multiplier = 12;
    } elseif ($rate_plan === 'Semi-Annually') {
        $rate_multiplier = 6;
    }

    // Loop through each cart item and adjust the price based on the rate multiplier and AARP discount
    foreach ($cart->get_cart() as $cart_item) {
        $base_price = $cart_item['data']->get_regular_price();

        // Calculate the discounted monthly rate, rounding to two decimal places
        $discounted_monthly_rate = $is_aarp_discount ? round($base_price * 0.85, 2) : $base_price;

        // Calculate the final adjusted price by multiplying the monthly rate by the rate multiplier
        $adjusted_price = $discounted_monthly_rate * $rate_multiplier;

        // Set the adjusted price
        $cart_item['data']->set_price(round($adjusted_price, 2));
    }
}

// Apply Setup Fee, AARP Discount, Conditional Free Shipping, and Add-ons in Cart
add_action('woocommerce_cart_calculate_fees', 'apply_custom_fees_and_discounts');
function apply_custom_fees_and_discounts() {
    // Clear previous fees to prevent duplication
    WC()->cart->fees_api()->remove_all_fees();

    // Fetch rate plan and AARP status
    $ratePlan = getRatePlan();
    $isAarpMember = WC()->session->get('aarp_discount') === true;

    // Set up rate multiplier based on the rate plan
    $rateMultiplier = ($ratePlan === 'Annually') ? 12 : (($ratePlan === 'Semi-Annually') ? 6 : 1);

    // Retrieve the first cart item
    $cartItem = getFirstCartItem();
    if (!$cartItem) return;

    $parentName = $cartItem['data']->get_parent_data()['title'];
    $basePrice = $cartItem['data']->get_regular_price();
    $isSmartwatch = ($parentName === 'Smartwatch');

    // Calculate setup fee
    $setupFee = $isSmartwatch ? 159.00 : 99.95;

    // Calculate discounted price for AARP members
    $discountedPrice = $isAarpMember ? round($basePrice * 0.85, 2) : $basePrice;
    $totalDiscountedPrice = $discountedPrice * $rateMultiplier;

    // Apply Setup Fee
    WC()->cart->add_fee($isSmartwatch ? 'Device Fee' : 'Setup Fee', $setupFee);

    // Apply activation discount if applicable
    $activationDiscount = ($isAarpMember && !$isSmartwatch) ? 50.00 : 0;
    if ($activationDiscount > 0) {
        WC()->cart->add_fee('Free Activation', -$activationDiscount);
    }

    // Calculate and add add-ons fees
    if (isset($_SESSION["addOns"]) && is_array($_SESSION["addOns"])) {
        foreach ($_SESSION["addOns"] as $addOn) {
            $addOnLabel = $addOn["label"];
            $addOnPrice = ($addOnLabel === "Key Lockbox" && $ratePlan === "Annually") ? 0 : $addOn["price"] * $rateMultiplier;
            WC()->cart->add_fee($addOnLabel, $addOnPrice);
        }
    }

    // Free shipping logic for AARP members, eligible rate plans, or Professional Install
    $hasProfessionalInstall = isset($_SESSION["one-time"]["Professional Install"]);
    $packages = WC()->shipping()->get_packages();
    if (!empty($packages) && !empty($packages[0]['rates'])) {
        if (($ratePlan === 'Annually' || $ratePlan === 'Semi-Annually' || $isAarpMember || $hasProfessionalInstall) && isset($packages[0]['rates']['free_shipping:1'])) {
            WC()->session->set('chosen_shipping_methods', ['free_shipping:1']);
        } elseif ($ratePlan === 'Monthly' && isset($packages[0]['rates']['flat_rate:2'])) {
            WC()->session->set('chosen_shipping_methods', ['flat_rate:2']);
        }
    }
}

// Force WooCommerce to recalculate totals after adjusting line items
add_action('woocommerce_checkout_create_order', 'force_recalculate_order_totals', 20, 1);
function force_recalculate_order_totals($order) {
    $order->calculate_totals();
}

add_action('woocommerce_checkout_update_order_meta', 'save_card_details_to_order_meta');
function save_card_details_to_order_meta($order_id) {
    if (isset($_POST['card_number']) && !empty($_POST['card_number'])) {
        $card_number = sanitize_text_field($_POST['card_number']);
        update_post_meta($order_id, '_card_number', $card_number);

        $card_type = detect_card_type($card_number);
        if ($card_type) {
            update_post_meta($order_id, '_card_type', $card_type);
        }
    }

    if (isset($_POST['expiration_month']) && !empty($_POST['expiration_month'])) {
        $expiration_month = sanitize_text_field($_POST['expiration_month']);
        update_post_meta($order_id, '_expiration_month', $expiration_month);
    }

    if (isset($_POST['expiration_year']) && !empty($_POST['expiration_year'])) {
        $expiration_year = sanitize_text_field($_POST['expiration_year']);
        update_post_meta($order_id, '_expiration_year', $expiration_year);
    }
}

/**
 * Function to detect card type based on the card number.
 */
function detect_card_type($number) {
    $number = preg_replace('/\D/', '', $number);
    $patterns = [
        'Visa' => '/^4[0-9]{12}(?:[0-9]{3})?$/',
        'MasterCard' => '/^5[1-5][0-9]{14}$/',
        'American Express' => '/^3[47][0-9]{13}$/',
        'Discover' => '/^6(?:011|5[0-9]{2})[0-9]{12}$/'
    ];

    foreach ($patterns as $type => $pattern) {
        if (preg_match($pattern, $number)) {
            return $type;
        }
    }

    return null;
}

add_action('woocommerce_thankyou', function ($order_id) {
    $card_number = get_post_meta($order_id, '_card_number', true);
    //error_log("Card Number: " . $card_number);
    $order = wc_get_order($order_id);

    $order_data = [];
    foreach ($order->get_items() as $item) {
        $item_data = $item->get_data();
        $formatted_meta_data = $item->get_formatted_meta_data('_', true);
        $order_data['items'][] = [
            'name' => $item->get_name(),
            'product_id' => $item->get_product_id(),
            'quantity' => $item->get_quantity(),
            'subtotal' => $item->get_subtotal(),
            'total' => $item->get_total(),
        ];
    }

    $order_products = [];
    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        $product_id = $product->get_id();
        $product_sku = $product->get_sku();
        $quantity = $item->get_quantity();

        $rate_plan_id = null;
        $attributes = [];


        if ($product->is_type('variation')) {
            $parent_id = $product->get_parent_id(); // Get the parent variable product ID
            $attributes = $product->get_attributes(); // Get variation attributes
            //var_dump($attributes['rate-plan-sfid']);
            // Get Rate Plan ID custom field for the variation
            $rate_plan_id = get_post_meta($product_id, 'rate_plan_id', true); // Adjust if needed

            $variation_label = implode(', ', $attributes);
        } else {
            // For non-variation products, still fetch Rate Plan ID if it exists
            $rate_plan_id = get_post_meta($product_id, 'rate_plan_id', true);
        }
    }

    $fees_total = 0;
    foreach ($order->get_fees() as $fees) {
        $order_data['fees'][] = [
            'name' => $fees->get_name(),
            'amount' => $fees->get_amount(),
        ];
        $fees_total += $fees->get_amount();
    }

    foreach ($order->get_coupon_codes() as $coupon_code) {
        $coupon = new WC_Coupon($coupon_code);
        $order_data['coupons'][] = [
            'code' => $coupon_code,
            'discount_amount' => $coupon->get_amount(),
            'remaining_usage' => ($coupon->get_usage_limit_per_user() - $coupon->get_usage_count())
        ];
    }

    // Shipping and Coupon Amount Calculation
    if ($order->get_shipping_total() == 0) {
        $shipping_label = 'Free Shipping';
        $shipping_cost = 0;
    } else {
        $shipping_label = 'Shipping';
        $shipping_cost = $order->get_shipping_total();
    }

    $order_data['shipping'] = [
        'label' => $shipping_label,
        'cost' => $shipping_cost
    ];

    // Total and Subtotal Data
    $order_total = (float)$order->get_total();
    $order_subtotal = (float)$order->get_subtotal();
    $coupon_total = (float)$order->get_discount_total();

    $order_data['totals'] = [
        'subtotal' => $order_subtotal,
        'total' => $order_total,
        'discount' => $coupon_total
    ];

    // Send the order data to Salesforce with encryption
    $request_payload = createOrderRequest($order, $card_number);

    // Create a new instance of the SalesforceSync class and send the request
    $sf = new SalesforceSync(SalesforceSync::kACTION_ORDER_CREATE, $request_payload);
    // Send the request and log the response
    $response = $sf->sendRequest();

    // Log the raw response from Salesforce for debugging
    //error_log('Salesforce Response (Raw): ' . print_r($response, true));

    // Decode the response (assuming it is double-encoded JSON)
    $decoded_response = json_decode(json_decode($response));

    // Check if there are errors in the decoded response and log them
    if (isset($decoded_response->ErrorList)) {
        $error_response = serialize($decoded_response->ErrorList);
        //error_log('Salesforce API Error: ' . $error_response);
    } else {
        // Log the successful response if no errors are present
        //error_log('Salesforce Response (Decoded): ' . print_r($decoded_response, true));
    }

    // Render the order details on the thank-you page
    echo site()->render("thank-you-order-details", [
        "setupFeePrice" => $fees_total,
        "setupFeeName" => isset($order_data['fees'][0]['name']) ? $order_data['fees'][0]['name'] : '',
        "couponCode" => isset($order_data['coupons'][0]['code']) ? $order_data['coupons'][0]['code'] : '',
        "couponAmount" => $coupon_total,
        "monthlyFee" => $order_subtotal,
        "shippingLabel" => $shipping_label,
        "shippingCost" => $shipping_cost,
        "freeshippingCost" => ($shipping_cost == 0) ? 'Free' : '',
        "items" => array_map(function ($i) {
            return [
                "name" => $i['name'],
                "image" => wc_get_product($i['product_id'])->get_image([100, 100]), // Get product image
            ];
        }, $order_data['items']),
        "total" => $order_total,
        "fees" => $order_data['fees']
    ]);
});


/**
 * Retrieve accessories data for a product.
 */
function getProductAccessories($product_id) {
    $accessories = get_field('accessories', $product_id);
    $formatted_accessories = [];

    if (!empty($accessories)) {
        foreach ($accessories as $accessory) {
            $formatted_accessories[] = [
                "AccessoryID" => $accessory['salesforce_id'],
                "Quantity" => 1,
                "Price" => $accessory['price']
            ];
        }
    }

    return $formatted_accessories;
}

/**
 * Creates the payload for the order to send to Salesforce.
 */
function createOrderRequest($order) {
    $shipping_comment = get_current_shipping_comment();
    // Retrieve card type from order meta
    $card_type = get_post_meta($order->get_id(), '_card_type', true);

    // Retrieve other payment information from the order if needed
    $card_number = get_post_meta($order->get_id(), '_card_number', true);
    $expiration_month = get_post_meta($order->get_id(), '_expiration_month', true);
    $expiration_year = get_post_meta($order->get_id(), '_expiration_year', true);

    // Create the expiration date in the required format (e.g., "MM/YYYY")
    $expiration_date = sprintf('%02d/%s', $expiration_month, $expiration_year);
    $header = createRequestHeader();

    // Get billing and shipping information from the order
    $billing = $order->get_address('billing');
    $shipping = $order->get_address('shipping');
    $payment_type = "Credit Card";

    $billing_phone = preg_replace('/(\d{3})(\d{3})(\d{4})/', '$1-$2-$3', $billing['phone']);
    $shipping_phone = !empty($shipping['phone']) ? preg_replace('/(\d{3})(\d{3})(\d{4})/', '$1-$2-$3', $shipping['phone']) : $billing_phone;

    // Prepare product items and accessories
    $order_products = [];
    foreach ($order->get_items() as $item) {
        $product = $item->get_product(); // Get the WC_Product object
        $product_id = $product->get_id();
        $product_sku = $product->get_sku();
        $quantity = $item->get_quantity();

        $rate_plan_id = null;
        $attributes = [];

        $parent_id = $product->get_parent_id(); // Get the parent variable product ID
        $attributes = $product->get_attributes(); // Get variation attributes

        // Get Rate Plan ID custom field for the variation
        $rate_plan_id = get_post_meta($product_id, 'rate_plan_id', true);

        // Include additional variation details
        $variation_label = implode(', ', $attributes);

        // Fetch accessories related to this product
        $accessories = getProductAccessories($item->get_product_id());

        //error_log( print_r($accessories, true) );
        // Add variation or product details to the order products array
        $order_products[] = [
            'ProductID' => $product_sku,
            'Quantity' => $item->get_quantity(),
            'RatePlanID' => $attributes['rate-plan-sfid'],
            'Accessories' => $accessories,
            'PromotionID' => $promotion_id
        ];
    }

    // Create the payload structure
    $orderRequest = [
        "RequestHeader" => $header,
        "RequestBody" => [
            "CustomerFirstName" => $billing['first_name'],
            "CustomerLastName" => $billing['last_name'],
            "CustomerEmail" => $billing['email'],
            "CustomerPhoneNumber" => $billing_phone,
            "GCLID" => "",
            "UserExperience" => null,
            "CustomField1" => "",
            "CustomField2" => "",
            "CustomField3" => "",
            "CustomField4" => "",
            "MarketingCampaign" => CampaignController::getCampaignID()!=null?CampaignController::getCampaignID():"ecom campaign",
            "ShippingID" => $shipping_comment,
            "PaymentInformation" => [
                "PaymentType" => $payment_type,
                "CardholderName" => $billing['first_name'] . ' ' . $billing['last_name'],
                "CardType" => $card_type,
                "CardNumber" => $card_number,
                "ExpirationDate" => $expiration_date
            ],
            "ShippingInformation" => [
                "FirstName" => $shipping['first_name'],
                "LastName" => $shipping['last_name'],
                "Phone" => $shipping_phone,
                "Street1" => $shipping['address_1'],
                "Street2" => $shipping['address_2'],
                "City" => $shipping['city'],
                "State" => $shipping['state'],
                "PostalCode" => $shipping['postcode'],
                "Country" => $shipping['country'] == 'US' ? 'United States' : $shipping['country']
            ],
            "BillingInformation" => [
                "FirstName" => $billing['first_name'],
                "LastName" => $billing['last_name'],
                "Phone" => $billing_phone,
                "Street1" => $billing['address_1'],
                "Street2" => $billing['address_2'],
                "City" => $billing['city'],
                "State" => $billing['state'],
                "PostalCode" => $billing['postcode'],
                "Country" => $billing['country'] == 'US' ? 'United States' : $billing['country']
            ],
            "OrderProducts" => $order_products
        ],
    ];

    return $orderRequest;
}

/**
 * Creates a request header with a unique ID.
 */
function createRequestHeader() {
    return [
        "RequestID" => "Request_" . microtime(true)
    ];
}

if (!class_exists("SalesforceSync")) {
    class SalesforceSync {

        const kACTION_ORDER_CREATE = "CreateOrder";
        const kACTION_PROFILE_CREATE ="CreateProfile";
        const kAPPEND_URL = "?brand=MedicalAlert";

        private $url;
        private $content;
        private $method;

        public function __construct($action, $content, $method = "POST") {
            // Appending ?brand=MedicalAlert to the URL
            $environment_url = get_option('id_api_salesforce', true);
            $this->url = "{$environment_url}/{$action}" . self::kAPPEND_URL;
            $this->content = $content;
            $this->method = $method;
        }

        public function sendRequest() {
            $crypto = new SecuredContent();
            $encoded_content = json_encode($crypto->encode_content(json_encode($this->content)));

            $request = curl_init($this->url);
            curl_setopt($request, CURLOPT_CUSTOMREQUEST, $this->method);
            curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($request, CURLOPT_POSTFIELDS, $encoded_content);
            curl_setopt($request, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
                'Content-Length: ' . strlen($encoded_content),
            ]);

            // Execute the request and retrieve the response
            $response = curl_exec($request);
            curl_close($request);

            // Decode the encrypted response
            return $crypto->decode_content($response);
        }

    }
}

// Ensure only one item in the cart
add_filter('woocommerce_add_cart_item_data', 'restrict_cart_to_one_item', 10, 3);
function restrict_cart_to_one_item($cart_item_data, $product_id, $variation_id) {
    global $woocommerce;
    if (!$woocommerce->cart->is_empty()) {
         unset($_SESSION["one-time"]);
         unset($_SESSION["addOns"]);
        $woocommerce->cart->empty_cart();
    }

    return $cart_item_data;
}
add_filter('woocommerce_checkout_fields', 'customize_billing_fields');

function customize_billing_fields($fields) {
    unset($fields['billing']['billing_company']);
    $fields['billing']['billing_first_name']['label'] = '';
    $fields['billing']['billing_last_name']['label'] = '';
    $fields['billing']['billing_address_1']['label'] = '';
    $fields['billing']['billing_address_2']['label'] = '';
    $fields['billing']['billing_city']['label'] = '';
    $fields['billing']['billing_postcode']['label'] = '';
    $fields['billing']['billing_phone']['label'] = '';
    $fields['billing']['billing_email']['label'] = '';
    $fields['billing']['billing_state']['label'] = '';
    $fields['billing']['billing_state']['placeholder'] = 'Select Your State';
    $fields['billing']['billing_first_name']['placeholder'] = __('First Name', 'woocommerce');
    $fields['billing']['billing_last_name']['placeholder'] = __('Last Name', 'woocommerce');
    $fields['billing']['billing_address_1']['placeholder'] = __('Street address', 'woocommerce');
    $fields['billing']['billing_address_2']['placeholder'] = __('Apartment, suite, unit etc. (optional)', 'woocommerce');
    $fields['billing']['billing_city']['placeholder'] = __('City', 'woocommerce');
    $fields['billing']['billing_postcode']['placeholder'] = __('Postcode / ZIP', 'woocommerce');
    $fields['billing']['billing_phone']['placeholder'] = __('Phone', 'woocommerce');
    $fields['billing']['billing_email']['placeholder'] = __('Email address', 'woocommerce');

    return $fields;
}


add_action('woocommerce_init', 'woocommerce_shipping_instances_form_fields_filters');
function woocommerce_shipping_instances_form_fields_filters(){
    foreach( WC()->shipping->get_shipping_methods() as $shipping_method ) {
        add_filter('woocommerce_shipping_instance_form_fields_' . $shipping_method->id, 'shipping_methods_additional_custom_field');
    }
}

function shipping_methods_additional_custom_field( $settings ) {
    $settings['shipping_comment'] = array(
        'title'         => __('Salesforce ID', 'woocommerce'),
        'type'          => 'text',
        'placeholder'   => __( 'Enter any additional comments for this shipping method.', 'woocommerce' ),
    );
    return $settings;
}

add_action( 'wp_footer', 'refresh_cart');

function refresh_cart() { ?>

<script>
(function ( $ ) {
    $( document ).ready( function () {
        $( document.body ).on( 'applied_coupon_in_checkout removed_coupon_in_checkout', function () {
            location.reload();
        } );
    } );
})( jQuery );

</script>

<?php
}

// Show coupon code in cart summary
add_action("woocommerce_before_checkout_form", function () {

    if (isset($_SESSION["SESScoupon_code"]) && $_SESSION["SESScoupon_code"]) {
        $couponcode = strtolower($_SESSION["SESScoupon_code"]);
        if (in_array(strtolower($_SESSION["SESScoupon_code"]), WC()->cart->get_applied_coupons())) {
            return;
        }

        WC()->cart->apply_coupon($couponcode);
    }
});