<?php
/**
 * Location-Based Coupon Restrictions
 *
 * This file handles custom location restrictions for WooCommerce coupons.
 * It integrates with the 'locations' taxonomy and WCMLIM plugin.
 *
 * @package WCMLIM
 */

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

/**
 * Helper function to log coupon validation debug info
 */
function wcmlim_log_coupon_debug( $message, $data = array() ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return;
}
$log_message = '[WCMLIM Coupon] ' . $message;
if ( ! empty( $data ) ) {
$log_message .= ' | Data: ' . print_r( $data, true );
}
error_log( $log_message );
}

/**
 * Render the location restrictions meta box content
 */
function wcmlim_coupon_location_meta_box_content( $post ) {
wp_nonce_field( 'wcmlim_save_coupon_locations', 'wcmlim_coupon_locations_nonce' );
$saved_locations = get_post_meta( $post->ID, 'coupon_location_ids', true );
if ( ! is_array( $saved_locations ) ) {
$saved_locations = array();
}
$locations = get_terms( array(
'taxonomy'   => 'locations',
'hide_empty' => false,
) );
if ( is_wp_error( $locations ) || empty( $locations ) ) {
echo '<p class="form-field"><em>' . esc_html__( 'No locations found. Please create locations in your taxonomy first.', 'wcmlim' ) . '</em></p>';
return;
}

// Use WooCommerce's field wrapper for consistency
echo '<div class="options_group">';
echo '<p class="form-field"><strong>' . esc_html__( 'Select locations where this coupon can be used:', 'wcmlim' ) . '</strong></p>';
echo '<div class="form-field" style="padding-left: 20px;">';

foreach ( $locations as $location ) {
$checked = in_array( $location->term_id, $saved_locations, true ) ? 'checked="checked"' : '';
echo '<label style="display: block; margin-bottom: 8px;">';
echo '<input type="checkbox" name="coupon_location_ids[]" value="' . esc_attr( $location->term_id ) . '" ' . $checked . ' />';
echo ' ' . esc_html( $location->name ) . ' <span style="color: #999;">(ID: ' . esc_html( $location->term_id ) . ')</span>';
echo '</label>';
}

echo '</div>';
echo '</div>';
}

/**
 * Add location restrictions to WooCommerce coupon usage restriction tab
 */
function wcmlim_render_coupon_locations_in_usage_tab() {
global $post;

$saved_locations = get_post_meta( $post->ID, 'coupon_location_ids', true );
if ( ! is_array( $saved_locations ) ) {
$saved_locations = array();
}

$locations = get_terms( array(
'taxonomy'   => 'locations',
'hide_empty' => false,
) );

$location_options = array();
if ( ! is_wp_error( $locations ) && ! empty( $locations ) ) {
foreach ( $locations as $location ) {
$location_options[ $location->term_id ] = $location->name;
}
}

// Add nonce field
wp_nonce_field( 'wcmlim_save_coupon_locations', 'wcmlim_coupon_locations_nonce' );

// Use WooCommerce's woocommerce_wp_select with multiple option
?>
<p class="form-field">
<label for="coupon_location_ids"><?php esc_html_e( 'Location restrictions', 'wcmlim' ); ?></label>
<select id="coupon_location_ids" name="coupon_location_ids[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any location', 'wcmlim' ); ?>">
<?php
foreach ( $location_options as $location_id => $location_name ) {
$selected = in_array( $location_id, $saved_locations, true ) ? 'selected="selected"' : '';
echo '<option value="' . esc_attr( $location_id ) . '" ' . $selected . '>' . esc_html( $location_name ) . '</option>';
}
?>
</select>
<?php echo wc_help_tip( __( 'Leave blank to allow this coupon for all locations. Select specific locations to restrict where this coupon can be used.', 'wcmlim' ) ); ?>
</p>
<?php
}
add_action( 'woocommerce_coupon_options_usage_restriction', 'wcmlim_render_coupon_locations_in_usage_tab', 10 );

/**
 * Save coupon location restrictions
 */
function wcmlim_save_coupon_location_meta( $post_id ) {
if ( ! isset( $_POST['wcmlim_coupon_locations_nonce'] ) || 
     ! wp_verify_nonce( $_POST['wcmlim_coupon_locations_nonce'], 'wcmlim_save_coupon_locations' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( 'shop_coupon' !== get_post_type( $post_id ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( isset( $_POST['coupon_location_ids'] ) && is_array( $_POST['coupon_location_ids'] ) ) {
$location_ids = array_map( 'intval', $_POST['coupon_location_ids'] );
update_post_meta( $post_id, 'coupon_location_ids', $location_ids );
} else {
delete_post_meta( $post_id, 'coupon_location_ids' );
}
}
add_action( 'save_post', 'wcmlim_save_coupon_location_meta' );

/**
 * Validate coupon based on product locations
 * Allows coupon if at least one product matches the allowed locations
 */
function wcmlim_validate_coupon_location( $valid, $coupon, $discount ) {
if ( ! $valid ) {
return $valid;
}

$allowed_location_ids = get_post_meta( $coupon->get_id(), 'coupon_location_ids', true );

wcmlim_log_coupon_debug( 'Validating coupon: ' . $coupon->get_code(), array(
'coupon_id' => $coupon->get_id(),
'allowed_locations' => $allowed_location_ids,
) );

// If no location restrictions, allow coupon for all products
if ( empty( $allowed_location_ids ) || ! is_array( $allowed_location_ids ) ) {
wcmlim_log_coupon_debug( 'No location restrictions - coupon valid for all' );
return $valid;
}

$cart = WC()->cart;
if ( ! $cart ) {
wcmlim_log_coupon_debug( 'No cart found' );
return $valid;
}

$cart_items = $cart->get_cart();
if ( empty( $cart_items ) ) {
wcmlim_log_coupon_debug( 'Cart is empty' );
// Get first allowed location name for error message
$location_term = get_term( $allowed_location_ids[0], 'locations' );
$location_name = $location_term && ! is_wp_error( $location_term ) ? $location_term->name : 'the specified location';

throw new Exception( sprintf( __( 'This coupon requires products from %s in your cart.', 'wcmlim' ), $location_name ) );
}

// Check if at least ONE product in cart is from an allowed location
$has_matching_product = false;
$matching_count = 0;
$total_count = 0;
$debug_cart_info = array();

foreach ( $cart_items as $cart_item_key => $cart_item ) {
$total_count++;
$selected_location_id = null;

// Check for WCMLIM location data
if ( isset( $cart_item['select_location']['location_termId'] ) && ! empty( $cart_item['select_location']['location_termId'] ) ) {
$selected_location_id = intval( $cart_item['select_location']['location_termId'] );

$debug_cart_info[] = array(
'product_id' => $cart_item['product_id'],
'selected_location' => $selected_location_id,
);

// Check if this product's location is in the allowed list
if ( in_array( $selected_location_id, $allowed_location_ids, true ) ) {
$has_matching_product = true;
$matching_count++;
}
}
}

wcmlim_log_coupon_debug( 'Cart validation results', array(
'total_products' => $total_count,
'matching_products' => $matching_count,
'cart_details' => $debug_cart_info,
) );

// If at least one product matches, allow the coupon
// The per-item discount filter will handle applying discount only to matching products
if ( $has_matching_product ) {
wcmlim_log_coupon_debug( 'Coupon valid - at least one product from allowed locations' );
return $valid;
}

// No products from allowed locations - reject coupon
wcmlim_log_coupon_debug( 'Coupon invalid - no products from allowed locations' );
$location_names = array();
foreach ( $allowed_location_ids as $loc_id ) {
$term = get_term( $loc_id, 'locations' );
if ( $term && ! is_wp_error( $term ) ) {
$location_names[] = $term->name;
}
}
$location_list = implode( ', ', $location_names );

throw new Exception( sprintf( __( 'This coupon requires products from %s in your cart.', 'wcmlim' ), $location_list ) );
}
add_filter( 'woocommerce_coupon_is_valid', 'wcmlim_validate_coupon_location', 10, 3 );

/**
 * Filter discount amount per cart item based on location
 * This ensures discounts only apply to products from allowed locations
 */
function wcmlim_filter_coupon_discount_per_item( $discount, $discounting_amount, $cart_item, $single, $coupon ) {
$allowed_location_ids = get_post_meta( $coupon->get_id(), 'coupon_location_ids', true );

// If no location restrictions, apply discount normally
if ( empty( $allowed_location_ids ) || ! is_array( $allowed_location_ids ) ) {
return $discount;
}

// Check if cart item has location data from WCMLIM plugin
if ( ! isset( $cart_item['select_location']['location_termId'] ) ) {
wcmlim_log_coupon_debug( 'No location data for product - skipping discount', array(
'product_id' => $cart_item['product_id'],
) );
return 0; // No discount if no location data
}

$selected_location_id = intval( $cart_item['select_location']['location_termId'] );

// Check if product's location is in allowed list
if ( in_array( $selected_location_id, $allowed_location_ids, true ) ) {
wcmlim_log_coupon_debug( 'Applying discount to product', array(
'product_id' => $cart_item['product_id'],
'location_id' => $selected_location_id,
'discount' => $discount,
) );
return $discount; // Apply full discount
}

// Product is not from an allowed location - no discount
wcmlim_log_coupon_debug( 'Skipping discount for product', array(
'product_id' => $cart_item['product_id'],
'location_id' => $selected_location_id,
'reason' => 'Not from allowed location',
) );

return 0; // No discount
}
add_filter( 'woocommerce_coupon_get_discount_amount', 'wcmlim_filter_coupon_discount_per_item', 10, 5 );

/**
 * Add custom column to coupons list table
 */
function wcmlim_display_coupon_location_column( $columns ) {
$columns['coupon_locations'] = __( 'Locations', 'wcmlim' );
return $columns;
}
add_filter( 'manage_edit-shop_coupon_columns', 'wcmlim_display_coupon_location_column' );

/**
 * Populate the custom locations column
 */
function wcmlim_populate_coupon_location_column( $column, $post_id ) {
if ( 'coupon_locations' === $column ) {
$location_ids = get_post_meta( $post_id, 'coupon_location_ids', true );

if ( empty( $location_ids ) || ! is_array( $location_ids ) ) {
echo '<span style="color: #999;">' . esc_html__( 'All locations', 'wcmlim' ) . '</span>';
return;
}

$location_names = array();
foreach ( $location_ids as $location_id ) {
$term = get_term( $location_id, 'locations' );
if ( $term && ! is_wp_error( $term ) ) {
$location_names[] = $term->name;
}
}

if ( ! empty( $location_names ) ) {
echo esc_html( implode( ', ', $location_names ) );
} else {
echo '<span style="color: #999;">' . esc_html__( 'All locations', 'wcmlim' ) . '</span>';
}
}
}
add_action( 'manage_shop_coupon_posts_custom_column', 'wcmlim_populate_coupon_location_column', 10, 2 );

