<?php
function wcmlim_local_shipping_init()
{
 
  if (!class_exists('Wcmlim_Pickup_Shipping_Method')) {

    class Wcmlim_Pickup_Shipping_Method extends WC_Shipping_Method
    {
      /**
       * Constructor.
       *
       * @param int $instance_id
       */
      public function __construct($instance_id = 0)
      {
        
        $this->id = 'wcmlim_pickup_location';
        $this->instance_id = absint($instance_id);
        $this->method_title = __("Pickup Location", 'wcmlim');
        $this->supports = array(
          'shipping-zones',
          'instance-settings',
          'instance-settings-modal',
        );
        $this->init();
      }

      /**
       * Initialize custom shiping method.
       */
      public function init()
      {

        // Load the settings.
        $this->init_form_fields();
        $this->init_settings();

        // Define user set variables
        $this->title = $this->get_option('title');

        // Actions
        add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
      }

      /**
       * Calculate custom shipping method.
       *
       * @param array $package
       *
       * @return void
       */
      public function calculate_shipping($package = array())
      {
        $this->add_rate(array(
          'label' => $this->title,
          'package' => $package,
        ));
      }

      /**
       * Init form fields.
       */
      public function init_form_fields()
      {
        $this->instance_form_fields = array(
          'title' => array(
            'title' => __('Pickup Location', 'wcmlim'),
            'type' => 'text',
            'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
            'default' => __('Pickup Location', 'wcmlim'),
            'desc_tip' => true,
          ),
        );
      }
    }
  }
}
// show address in below local-pickup selection on checkout page -codeinit

function details($pickup_location_term)
{
  if(get_option('wcmlim_allow_local_pickup') == 'on' && (get_option('wcmlim_allow_only_backend') == 'on' || get_option('wcmlim_allow_only_backend') != 'on')){
    ?>
    <p class="local_pickup_address"></p>
    <?php
  }
}
// show address in below local-pickup selection on checkout page -codeend

// ajax call back and hook to show local pickup address on checkout page -codeinit
add_action('wp_ajax_wcmlim_show_address',  'wcmlim_show_address_on_checkout');
add_action('wp_ajax_nopriv_wcmlim_show_address', 'wcmlim_show_address_on_checkout');
function wcmlim_show_address_on_checkout()
{
  if(empty($_POST['location_id']))
  {
    wp_die();
  }

  $term_id = sanitize_text_field($_POST['location_id']);
  $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
  
  foreach ($terms as $term) {
    if ($term_id == $term->term_id) {
      $term_meta = array(
        'street_address' => get_term_meta($term->term_id, 'wcmlim_street_number', true),
        'wcmlim_city' => $term->name,
        'wcmlim_postcode' => get_term_meta($term_id, 'wcmlim_postal_code', true),
        'wcmlim_state_code' => $wcmlim_state_code ?? '',
        'wcmlim_state' => ucwords(get_term_meta($term_id, 'wcmlim_administrative_area_level_1', true)),
        'wcmlim_country_state' => get_term_meta($term_id, 'wcmlim_country', true),
        'wcmlim_email' => get_term_meta($term_id, 'wcmlim_email', true),
        'wcmlim_phone' => get_term_meta($term_id, 'wcmlim_phone', true),
      );
      
      $error_prep = '';
      foreach (WC()->cart->get_cart() as $cart_item) {  
        $cart_product_id = $cart_item['variation_id'] ?: $cart_item['product_id'];
        $wc_product = wc_get_product($cart_product_id);
        $wc_item_name = $wc_product->get_name();
        
        if(!empty($cart_product_id)) {
          $loc_stock = intval(get_post_meta($cart_product_id, "wcmlim_stock_at_$term_id", true));
          $postmeta_backorders_product = get_post_meta($cart_product_id, '_backorders', true);
          
          if(($loc_stock <= 0 || $loc_stock === '') && $postmeta_backorders_product != "yes") {
            $error_prep .= "<br /> The Item <i>$wc_item_name</i> could not be Pickup at <i>$term->name</i>";
          }          
        }
      }

      if(!empty($error_prep)) {
        wc_clear_notices();
        wc_add_notice($error_prep, 'error');
        do_action('woocommerce_set_cart_cookies', true);
      }
      
      echo json_encode($term_meta);
      wp_die();
    }
  }
  wp_die();
}
// ajax call back and hook to show local pickup address on checkout page -codeend

add_action('woocommerce_after_checkout_validation', 'wcmlim_after_checkout_validation', 10, 2);

function wcmlim_after_checkout_validation($fields, $errors) {
  // Only proceed if shipping method is our pickup location
  $wcmlim_get_shipping_method = explode(':', $fields['shipping_method'][0]);
  if($wcmlim_get_shipping_method[0] !== 'wcmlim_pickup_location') {
    return;
  }
  
  $error_prep = '';
  $wcmlim_selected_pickup_location = isset($_POST['wcmlim_pickup']) ? $_POST['wcmlim_pickup'] : '';
  
  // Check if pickup location is selected
  if($wcmlim_selected_pickup_location == '-1') {
    $errors->add('validation', "It seems the Pickup Location has not been selected, Please Select Location and try again");
    return;
  }
  
  // Get pickup location term
  $pickup_location_id = 0;
  $pickup_location_name = '';
  $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
  foreach ($terms as $term) {
    if($term->name == $wcmlim_selected_pickup_location) {
      $pickup_location_name = $term->name;
      $pickup_location_id = $term->term_id;
      break;
    }
  }
  
  if(!empty($pickup_location_id)) {
    // Check each cart item for stock availability at selected location
    foreach (WC()->cart->get_cart() as $cart_item) {
      $cart_product_id = $cart_item['variation_id'] ?: $cart_item['product_id'];
      $wc_product = wc_get_product($cart_product_id);
      $wc_item_quantity = intval($cart_item['quantity']);
      $wc_item_name = $wc_product->get_name();
     
      if(!empty($cart_product_id)) {
        $loc_stock = intval(get_post_meta($cart_product_id, "wcmlim_stock_at_$pickup_location_id", true));
        $postmeta_backorders_product = get_post_meta($cart_product_id, '_backorders', true);
        
        // Check if product is out of stock at this location
        if(($loc_stock <= 0 || $loc_stock === '') && $postmeta_backorders_product == 'no') {
          $error_prep .= "<br /> The Item <i>$wc_item_name</i> could not be Pickup at <i>$pickup_location_name</i>";
        }
        // Check if there's enough stock for the requested quantity
        else if($loc_stock > 0 && $loc_stock < $wc_item_quantity && $postmeta_backorders_product == 'no') {
          $error_prep .= "<br /> The Item <i>$wc_item_name</i>'s quantity <i>$wc_item_quantity</i> is not be available for Pickup location [<i>$pickup_location_name</i>]";
        }
      }
    }
  }
  
  if(!empty($error_prep)) {
    $errors->add('validation', $error_prep);
  }
}

add_action('woocommerce_shipping_init', 'wcmlim_local_shipping_init');

function wcmlim_local_shipping_method($methods)
{
  $methods['wcmlim_pickup_location'] = 'Wcmlim_Pickup_Shipping_Method';
  return $methods;
}
add_filter('woocommerce_shipping_methods', 'wcmlim_local_shipping_method');


/**
 * Set message on cart page
 * @version 1.6.1
 */

function wcmlim_wc_cart_totals_before_order_total()
{
  if (!is_wcmlim_chosen_shipping_method()) {
    return;
  }
  
  global $woocommerce;
  $cart = $woocommerce->cart->cart_contents;
  $pickup_valid = get_option('wcmlim_pickup_valid');
  $isClearCart = get_option('wcmlim_clear_cart');
  
  // Check if conflicting plugin is active
  if (in_array('local-pickup-for-woocommerce/local-pickup.php', apply_filters('active_plugins', get_option('active_plugins'))) ||  
      (is_array(get_site_option('active_sitewide_plugins')) && !array_key_exists('local-pickup-for-woocommerce/local-pickup.php', get_site_option('active_sitewide_plugins')))) {
    update_option($this->option_name . '_allow_local_pickup', '');
  }
      
  // Display pickup locations on cart page
  if (get_option('wcmlim_allow_local_pickup') == 'on' && get_option('wcmlim_allow_only_backend') != 'on') {
    $locAdd = array();
    $pickupAdd = array();
    $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
    $cart_message = '';
    
    foreach ($cart as $array_item) {       
      if (isset($array_item['select_location']['location_name'])) {
        foreach ($terms as $term) {
          if ($term->name == $array_item['select_location']['location_name']) {
            $term_id = $term->term_id;
            $streetNumber = get_term_meta($term_id, 'wcmlim_street_number', true);
            $route = get_term_meta($term_id, 'wcmlim_route', true);
            $locality = get_term_meta($term_id, 'wcmlim_locality', true);
            $state = get_term_meta($term_id, 'wcmlim_administrative_area_level_1', true);
            $postal_code = get_term_meta($term_id, 'wcmlim_postal_code', true);
            $country = get_term_meta($term_id, 'wcmlim_country', true);
            $pickup = get_term_meta($term_id, 'wcmlim_allow_pickup', true);
            
            $arrayloc = $streetNumber . " " . $locality . " " . $state . " " . $route;
            
            if(!in_array($arrayloc, $locAdd) && $pickup == "on") {
              $addressParts = array_filter([
                $streetNumber ? $streetNumber.' ,' : '',
                $route ? $route.' ,' : '',
                $locality ? $locality.' ,' : '',
                $state ? $state.' ,' : '',
                $postal_code ? $postal_code.' ,' : '',
                $country ? $country : ''
              ]);
              
              $cart_message .= "Pickup Address : " . implode(" ", $addressParts) . "<br/>";
              array_push($locAdd, $arrayloc);
              array_push($pickupAdd, false);
            } else if(!in_array($arrayloc, $locAdd) && $pickup == null && !$isClearCart) {     
              $cart_message .= $term->name . " " . $pickup_valid . "<br>"; 
              array_push($pickupAdd, true);
              array_push($locAdd, $arrayloc);
            }
          } 
        } 
      }
    }
    
    if (!empty($cart_message)) {
      echo $cart_message;
    }
  } elseif (get_option('wcmlim_allow_only_backend') == 'on') {
    $cart_message = 'Locations for pickup your order are available on the Checkout page.';
    if (!empty($cart_message)) {
      ?>
      <tr class="shipping-pickup-store">
        <td colspan="2">
          <p class="message"><?= $cart_message ?></p>
        </td>
      </tr>
      <?php
    }
  }
}
add_action('woocommerce_cart_totals_before_order_total', 'wcmlim_wc_cart_totals_before_order_total');

/**
 * Get chosen shipping method
 */
function wcmlim_get_chosen_shipping_method()
{
  $chosen_methods = WC()->session->get('chosen_shipping_methods');
  return $chosen_methods[0] ?? '';
}

/**
 * Check is chosen shipping is wcmlim_local_shipping
 * @version 1.6.1
 * @return bool True is chosen shipping is wcmlim_local_shipping
 */
function is_wcmlim_chosen_shipping_method()
{
  $chosen_shipping = wcmlim_get_chosen_shipping_method();
  $chosen_shipping = explode(":", $chosen_shipping);
  return ($chosen_shipping[0] == "wcmlim_pickup_location");
}

/**
 ** Returns the main instance for wcmlim_local_shipping class
 **/
function wcmlim()
{
  return new Wcmlim_Pickup_Shipping_Method();
}

/**
 * Store table row layout
 */
function wcmlim_location_row_layout()
{
  if (!is_wcmlim_chosen_shipping_method()) {
    return;
  }
  
  global $woocommerce;
  $cart = $woocommerce->cart->cart_contents;
  
  if (get_option('wcmlim_allow_local_pickup') == 'on' && get_option('wcmlim_allow_only_backend') != 'on') {
    // Cache terms to avoid multiple queries
    $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
    $term_data = [];
    
    // Pre-process terms for lookup
    foreach ($terms as $term) {
      $term_data[$term->name] = [
        'id' => $term->term_id,
        'name' => $term->name,
        'streetNumber' => get_term_meta($term->term_id, 'wcmlim_street_number', true),
        'route' => get_term_meta($term->term_id, 'wcmlim_route', true),
        'locality' => get_term_meta($term->term_id, 'wcmlim_locality', true),
        'state' => get_term_meta($term->term_id, 'wcmlim_administrative_area_level_1', true),
        'postal_code' => get_term_meta($term->term_id, 'wcmlim_postal_code', true),
        'country' => get_term_meta($term->term_id, 'wcmlim_country', true),
        'email' => get_term_meta($term->term_id, 'wcmlim_email', true),
        'phone' => get_term_meta($term->term_id, 'wcmlim_phone', true),
        'pickup' => get_term_meta($term->term_id, 'wcmlim_allow_pickup', true)
      ];
    }

    // Process cart items
    foreach ($cart as $array_item) {
      $pid = ($array_item['variation_id'] != '0') ? $array_item['variation_id'] : $array_item['product_id'];
      $product_obj = wc_get_product($pid);
      $product_obj_name = $product_obj->get_name();
      
      if (isset($array_item['select_location']['location_name']) && isset($term_data[$array_item['select_location']['location_name']])) {
        $location = $term_data[$array_item['select_location']['location_name']];
        
        // Build address string
        $address_parts = [];
        if(!empty($location['streetNumber'])) $address_parts[] = $location['streetNumber'] . ',';
        if(!empty($location['route'])) $address_parts[] = $location['route'] . ',';
        if(!empty($location['locality'])) $address_parts[] = $location['locality'] . ',';
        if(!empty($location['state'])) $address_parts[] = $location['state'] . ',';
        if(!empty($location['postal_code'])) $address_parts[] = $location['postal_code'] . ',';
        if(!empty($location['country'])) $address_parts[] = $location['country'];
        
        $new_address = implode(' ', $address_parts);
        
        if(!empty($location['email'])) {
          $new_address .= ' ' . "<br>" . " <b>Email Address:</b> " . $location['email'];
        }
        if(!empty($location['phone'])) {
          $new_address .= ' ' . "<br>" . " <b>Phone No:</b> " . $location['phone'];
        }
        
        $cart_message = "<b>Product " . $product_obj_name . " </b><br /> <small>Pickup Address for {$location['name']}: </small>" . $new_address . "<br/>";
        ?>
        <tr class="shipping-pickup-store">
          <td colspan="2">
            <p class="message"><?= $cart_message ?></p>
          </td>
        </tr>
        <?php
      }
    }
  } elseif (get_option('wcmlim_allow_only_backend') == 'on') { ?>
    <tr class="shipping-pickup-store">
      <th><strong><?php echo "Pickup Location"; ?></strong></th>
      <td>
        <select name="wcmlim_pickup" id="wcmlim_pickup" class="wcmlim_pickup" style="width: fit-content;">
        <option value="-1">-Select-</option>
          <?php
          // Only fetch terms if cart has items
          if (!empty(WC()->cart->get_cart())) {
            $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
            foreach ($terms as $key => $term) { ?>
              <option data-termid="<?php esc_html_e($term->term_id); ?>" value="<?php esc_html_e($term->name); ?>"><?php echo $term->name; ?></option>
            <?php }
          } ?>
        </select>
      </td>
    </tr>
    <tr>
      <td colspan="2">
        <p class="local_pickup_address"></p>
      </td>
    </tr>
  <?php
  }
}
add_action('woocommerce_review_order_after_shipping', 'wcmlim_location_row_layout');

/**
 ** Save the Location meta.
 **/
function wcmlim_location_save_order_meta($order_id)
{
  if (empty($order_id) || empty($_POST['wcmlim_pickup'])) {
    return;
  }
  
  $order = wc_get_order($order_id);
  $location = sanitize_text_field($_POST['wcmlim_pickup']);
  
  // Cache terms for better performance
  $terms = get_terms(array('taxonomy' => 'locations', 'hide_empty' => false, 'parent' => 0));
  foreach ($terms as $key => $term) {
    if ($term->name == $location) {
      // Only proceed if order fulfillment edit option is not enabled
      $wcmlim_order_fulfil_edit = get_option('wcmlim_order_fulfil_edit');
      if ($wcmlim_order_fulfil_edit != "on") {
        foreach ($order->get_items() as $item_id => $item) {
          wc_add_order_item_meta($item_id, "Location", $term->name);
          wc_add_order_item_meta($item_id, "_selectedLocTermId", $term->term_id);
          wc_add_order_item_meta($item_id, "_selectedLocationKey", $key);
        }
      }
      break;
    }
  }
}
$fulfilment_rule = get_option("wcmlim_order_fulfilment_rules");
if($fulfilment_rule == "nearby_instock")
{
  $fulfilment_rule = "clcsadd";
}

add_action('woocommerce_checkout_update_order_meta', 'wcmlim_location_save_order_meta');
