<?php

trait Wcmlim_Backend_Location_Functions{

public function wcmlim_display_location_backend_only_mode(){
    $display_stock = get_option('wcmlim_backend_display_stock');
    
    if($display_stock != 'on') {
      return; // Early return if display stock is disabled
    }

    $stock_view = get_option('wcmlim_backend_display_stock_view');
    $valid_views = [
      'card_view', 'list_view', 'select_view', 
      'circular_view', 'table_view', 'expanded_view', 'simple_text_view', 'twocol_view', 'threecol_view'
    ];
    
    if(in_array($stock_view, $valid_views)) {
      $template_path = plugin_dir_path(__DIR__);
      $template_path = dirname($template_path); 
      $template_path = dirname($template_path);


      if(file_exists($template_path)) {
        include $template_path . '/public/controller/shop/wcmlim-display-location.php';
      }
    }

  }

  public function get_location_array_for_cart_add($product_location, $product_location_termid, $product_location_qty, $product_location_key) {
    return [
      'select_location' => [
        'location_name' => $product_location,
        'location_key' => (int)$product_location_key,
        'location_qty' => (int)$product_location_qty,
        'location_termId' => (int)$product_location_termid
      ]
    ];
  }

  /**
   * Makes a request to Google Distance Matrix API 
   * and processes the response
   */
  public function get_nearby_distance_by_api($dis_unit, $prepare_destination_address_string, $destination, $google_api_key) {
    // Don't proceed if essential params are missing
    if(empty($prepare_destination_address_string) || empty($destination) || empty($google_api_key)) {
      return [];
    }
    
    // Prepare API URL with proper encoding
    $api_url = add_query_arg(
      [
        'units' => 'metrics',
        'origins' => $prepare_destination_address_string,
        'destinations' => $destination,
        'key' => $google_api_key
      ],
      'https://maps.googleapis.com/maps/api/distancematrix/json'
    );
    
    // Make the API request
    $response = wp_remote_get(esc_url_raw($api_url));
    
    // Handle errors
    if(is_wp_error($response)) {
      return [];
    }
    
    // Parse response
    $response_body = wp_remote_retrieve_body($response);
    $response_arr = json_decode($response_body);
    
    // Handle API errors
    if(isset($response_arr->error_message)) {
      return [];
    }
    
    $distance = [];
    
    // Process successful responses
    if(!empty($response_arr->rows)) {
      foreach($response_arr->rows as $row) {
        foreach($row->elements as $key => $element) {
          if($element->status == "OK") {
            $plaindis = str_replace(',', '', explode(" ", $element->distance->text)[0]);
            
            // Convert distance based on unit preference
            if($dis_unit == "miles") {
              $converted_distance = round($plaindis * 0.621, 1);
              $dis_in_un = $converted_distance . ' miles';
              $dis = $converted_distance;
            } else {
              // For kilometers or no preference
              $dis_in_un = $element->distance->text;
              $dis = $plaindis;
            }
            
            $distance[] = [
              "value" => $plaindis,
              "location" => $response_arr->destination_addresses[$key],
              "key" => $key,
              "distance" => $dis,
              "dis_in_un" => $dis_in_un
            ];
          }
        }
      }
    }
    
    return $distance;
  }

  public function getLocationServiceRadius($distanceKey) {
    if(empty($distanceKey)) {
      return null;
    }

    // Get locations excluding any that should be filtered out
    $ExcLoc = get_option("wcmlim_exclude_locations_from_frontend");
    $args = [
      'taxonomy' => 'locations', 
      'hide_empty' => false, 
      'parent' => 0
    ];
    
    if(!empty($ExcLoc)) {
      $args['exclude'] = $ExcLoc;
    }
    
    $terms = get_terms($args);
    
    // Return service radius if found
    if(!empty($terms) && isset($terms[$distanceKey])) {
      return get_term_meta($terms[$distanceKey]->term_id, 'wcmlim_service_radius_for_location', true);
    }
    
    return null;
  }

  /**
   * Finds the second nearest location with stock
   */
  public function getSecondNearestLocation($addresses, $dis_unit, $product_id) {
    if(empty($addresses) || empty($dis_unit)) {
      return [];
    }

    // Get the distances array
    $distances = array_column($addresses, 'value');
    
    // Find the second smallest distance
    if(count($distances) < 2) {
      return [];
    }
    
    // Sort distances and get second smallest
    sort($distances, SORT_NUMERIC);
    $second_smallest = $distances[1];
    
    // Find location with second smallest distance
    $second_near_location = null;
    foreach($addresses as $index => $address) {
      if($address['value'] == $second_smallest) {
        $second_near_location = $index;
        break;
      }
    }
    
    if($second_near_location === null) {
      return [];
    }
    
    // Get locations
    $ExcLoc = get_option("wcmlim_exclude_locations_from_frontend");
    $args = [
      'taxonomy' => 'locations', 
      'hide_empty' => false, 
      'parent' => 0
    ];
    
    if(!empty($ExcLoc)) {
      $args['exclude'] = $ExcLoc;
    }
    
    $terms = get_terms($args);
    
    // Build result array
    $result = [];
    
    if(isset($terms[$second_near_location])) {
      $result[] = $terms[$second_near_location]->name;
      
      // Format distance based on unit
      if($dis_unit == "miles") {
        $formatted_distance = round($addresses[$second_near_location]['value'] * 0.621, 1) . ' miles';
      } else {
        $formatted_distance = $addresses[$second_near_location]['dis_in_un'];
      }
      
      $result[] = $formatted_distance;
      $result[] = $second_near_location;
    }
    
    return $result;
  }

  /**
   * Gets a location's full address based on term ID
   */
  public function wcmlim_get_locations_address($termid) {
    if(empty($termid)) {
      return '';
    }
    
    // Get address components and build address string
    $address_parts = [
      get_term_meta($termid, 'wcmlim_street_number', true),
      get_term_meta($termid, 'wcmlim_route', true),
      get_term_meta($termid, 'wcmlim_locality', true),
      get_term_meta($termid, 'wcmlim_administrative_area_level_1', true),
      get_term_meta($termid, 'wcmlim_postal_code', true),
      get_term_meta($termid, 'wcmlim_country', true)
    ];
    
    // Filter out empty parts and format address
    $filtered_parts = array_filter($address_parts);
    return implode('+', $filtered_parts);
  }

  /**
   * Calculates distance between two coordinate points
   */
  function distance_between_coordinates($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
    // Don't calculate if any coordinate is invalid
    if(!is_numeric($latitude1) || !is_numeric($longitude1) || 
       !is_numeric($latitude2) || !is_numeric($longitude2)) {
      return 0;
    }
    
    $theta = $longitude1 - $longitude2;
    $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + 
                (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
    $distance = acos($distance);
    $distance = rad2deg($distance);
    $distance = $distance * 60 * 1.1515;
    $distance = round($distance, 2);
    
    // Convert to requested unit
    $dis_unit = get_option("wcmlim_show_location_distance", true);
    if($unit == 'kilometers') {
      $distance *= 1.609344;
    }
    
    return $distance;
  }
    
  /**
   * Gets latitude and longitude for an address and updates term meta
   */
  function wcmlim_get_lat_lng($address, $termid){
    if(empty($address) || empty($termid)) {
      return json_encode(['latitude' => 0, 'longitude' => 0]);
    }
    
    $api_key = get_option('wcmlim_google_api_key');
    if(empty($api_key)) {
      return json_encode(['latitude' => 0, 'longitude' => 0]);
    }
    
    // Prepare API URL with proper encoding
    $api_url = add_query_arg(
      [
        'address' => urlencode($address),
        'sensor' => 'false',
        'key' => $api_key
      ],
      'https://maps.googleapis.com/maps/api/geocode/json'
    );
    
    // Make the API request
    $response = wp_remote_get(esc_url_raw($api_url));
    
    // Handle errors
    if(is_wp_error($response)) {
      return json_encode(['latitude' => 0, 'longitude' => 0]);
    }
    
    // Parse response
    $response_body = wp_remote_retrieve_body($response);
    $output = json_decode($response_body);
    
    // Extract coordinates
    $latitude = 0;
    $longitude = 0;
    if(isset($output->results[0]->geometry->location->lat)) {
      $latitude = $output->results[0]->geometry->location->lat;
      $longitude = $output->results[0]->geometry->location->lng;
    }
    
    // Update term meta
    update_term_meta($termid, 'wcmlim_lat', $latitude);
    update_term_meta($termid, 'wcmlim_lng', $longitude);
    
    return json_encode([
      'latitude' => $latitude,
      'longitude' => $longitude
    ]);
  }
}
?>