<?php
/**
 * includes/class-distance.php
 * Distance calculator (prefixed + BC + caching + filters) — SERVER KEY aware
 */
if ( ! defined( 'ABSPATH' ) ) exit;

if ( ! class_exists( 'EXECVITR_Distance_Calculator' ) ) {

	class EXECVITR_Distance_Calculator {

		/**
		 * Calculate distance & duration via Google Distance Matrix API.
		 *
		 * @param string $origin      Address from form
		 * @param string $destination Address to form
		 * @return array|WP_Error ['distance_km'=>float, 'duration'=>string] or WP_Error
		 */
		public function calculate_distance( $origin, $destination ) {
			$origin      = trim( wp_strip_all_tags( (string) $origin ) );
			$destination = trim( wp_strip_all_tags( (string) $destination ) );

			if ( $origin === '' || $destination === '' ) {
				return new WP_Error( 'execvitr_invalid_params', __( 'Origin or destination is empty.', 'executive-vip-transfer-service' ) );
			}

			/**
			 * Key selection order:
			 * 1) execvitr_google_server_key  (server-restricted key; önerilen)
			 * 2) execvitr_google_api_key     (browser key; referer kısıtlı olabilir)
			 * 3) vts_google_api_key          (BC)
			 */
			$server_key = get_option( 'execvitr_google_server_key', '' );
			$api_key    = $server_key ?: get_option( 'execvitr_google_api_key', get_option( 'vts_google_api_key', '' ) );

			if ( ! $api_key ) {
				return new WP_Error( 'execvitr_missing_api_key', __( 'Google API key is missing.', 'executive-vip-transfer-service' ) );
			}

			$country = get_option( 'execvitr_country', get_option( 'vts_country', 'TR' ) );
			$locale  = get_locale(); // e.g. tr_TR
			$lang    = substr( $locale, 0, 2 ); // 'tr', 'en', ...

			// Basic cache to avoid quota overuse
			$cache_key = 'execvitr_distance_' . md5( strtolower( $origin ) . '|' . strtolower( $destination ) . '|' . $country . '|' . $lang );
			$cached    = get_transient( $cache_key );
			if ( is_array( $cached ) && isset( $cached['distance_km'], $cached['duration'] ) ) {
				return apply_filters( 'execvitr_distance_parsed_result', $cached, $origin, $destination );
			}

			// Build URL
			$base = 'https://maps.googleapis.com/maps/api/distancematrix/json';
			$args = [
				'units'        => 'metric',
				'mode'         => 'driving',
				'origins'      => $origin,
				'destinations' => $destination,
				'key'          => $api_key,
				'language'     => $lang,
			];
			if ( $country ) {
				$args['region']     = strtolower( $country );
				$args['components'] = 'country:' . strtoupper( $country );
			}

			$url = add_query_arg( $args, $base );

			/**
			 * Filter: request args before the HTTP call.
			 */
			$request = apply_filters( 'execvitr_distance_request_args', [
				'timeout'     => 15,
				'redirection' => 3,
				'headers'     => [ 'Accept' => 'application/json' ],
			], $url, $origin, $destination );

			$response = wp_remote_get( $url, $request );
			if ( is_wp_error( $response ) ) {
				return $response;
			}

			$code = (int) wp_remote_retrieve_response_code( $response );
			$body_raw = wp_remote_retrieve_body( $response );
			$body     = json_decode( $body_raw, true );

			// HTTP error
			if ( 200 !== $code ) {
				// Özel durum: Referer kısıtlı key ile server call — genelde 403 + mesaj
				if ( $code === 403 && is_array( $body ) ) {
					$em = strtolower( (string) ( $body['error_message'] ?? '' ) );
					if ( strpos( $em, 'referer' ) !== false || strpos( $em, 'referrer' ) !== false ) {
						return new WP_Error(
							'execvitr_restricted_key',
							__( 'API keys with referrer restrictions cannot be used server-side. Please add a Server (IP-restricted) key in settings (execvitr_google_server_key).', 'executive-vip-transfer-service' )
						);
					}
				}
				return new WP_Error(
					'execvitr_api_http_code',
					sprintf(
						/* translators: %d: unexpected HTTP status code returned by the API */
						__( 'Unexpected HTTP code: %d', 'executive-vip-transfer-service' ),
						$code
					)
				);
			}

			if ( ! is_array( $body ) ) {
				return new WP_Error( 'execvitr_api_body', __( 'Invalid API response.', 'executive-vip-transfer-service' ) );
			}

			// API-level error
			$status = (string) ( $body['status'] ?? '' );
			if ( $status !== 'OK' ) {
				$err_msg = (string) ( $body['error_message'] ?? '' );

				// Özel mesaj: Referer kısıtlı key hatası
				$em = strtolower( $err_msg );
				if ( strpos( $em, 'referer' ) !== false || strpos( $em, 'referrer' ) !== false ) {
					return new WP_Error(
						'execvitr_restricted_key',
						__( 'API keys with referrer restrictions cannot be used with this API. Set a Server key (no HTTP referrer restriction) in plugin settings.', 'executive-vip-transfer-service' )
					);
				}

				return new WP_Error(
					'execvitr_api_status',
					$err_msg !== '' ? $err_msg : __( 'Distance data could not be retrieved.', 'executive-vip-transfer-service' )
				);
			}

			$elem = $body['rows'][0]['elements'][0] ?? null;
			if ( ! is_array( $elem ) || ( $elem['status'] ?? '' ) !== 'OK' ) {
				$elem_status = is_array( $elem ) && isset( $elem['status'] ) ? $elem['status'] : 'UNKNOWN';
				return new WP_Error(
					'execvitr_elem_status',
					sprintf(
						/* translators: %s: Element status string returned by the API. */
						__( 'Element status: %s', 'executive-vip-transfer-service' ),
						$elem_status
					)
				);
			}

			if ( empty( $elem['distance']['value'] ) || empty( $elem['duration']['text'] ) ) {
				return new WP_Error( 'execvitr_missing_fields', __( 'Distance or duration is missing in API response.', 'executive-vip-transfer-service' ) );
			}

			$result = [
				'distance_km' => round( floatval( $elem['distance']['value'] ) / 1000, 2 ),
				'duration'    => (string) $elem['duration']['text'],
			];

			// Cache for 5 minutes
			set_transient( $cache_key, $result, 5 * MINUTE_IN_SECONDS );

			return apply_filters( 'execvitr_distance_parsed_result', $result, $origin, $destination );
		}
	}
}

/**
 * BC class alias for older references.
 */
if ( ! class_exists( 'Vts_DistanceCalculator' ) && class_exists( 'EXECVITR_Distance_Calculator' ) ) {
	class Vts_DistanceCalculator extends EXECVITR_Distance_Calculator {}
}
