<?php
/**
 * ETYKIETOWNIK carrier detection and configuration.
 *
 * Detects carrier from _ps_carrier meta (preferred) or auto-detect via regex (fallback).
 * Returns carrier-specific config: service_id, dimensions, tracking URL, requirements.
 *
 * @package ParcelSelector
 * @since   3.4.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Parcselect_Label_Carrier {

	/**
	 * Detect carrier for an order.
	 * Priority: 1. _ps_carrier meta  2. auto-detect from locker name regex  3. default 'inpost'
	 *
	 * @param WC_Order $order WooCommerce order.
	 * @return string Carrier slug (always 'inpost' — InPost Paczkomaty, Poland only).
	 */
	public static function detect( $order ) {
		// 1. Explicit carrier from ParcelSelector (best).
		$carrier = $order->get_meta( '_ps_carrier', true );
		if ( ! empty( $carrier ) ) {
			return sanitize_key( $carrier );
		}

		// 2. Auto-detect from locker name (fallback).
		$locker = $order->get_meta( '_ps_locker_name', true );
		if ( ! empty( $locker ) ) {
			$detected = self::detect_from_name( $locker );
			if ( $detected ) {
				return $detected;
			}
		}

		// 3. Default.
		return 'inpost';
	}

	/**
	 * Auto-detect carrier from locker/point name using regex patterns.
	 * Verified against real shipping provider point IDs (30.03.2026).
	 *
	 * @param string $name Locker/point name.
	 * @return string|false Carrier slug or false if unknown.
	 */
	public static function detect_from_name( $name ) {
		$name = trim( $name );

		// InPost Paczkomat point ID: KRA01A, WAR01M, POZ12B (3 letters + 2 digits +
		// optional letter) and the longer format like KRA01APP, ADXM01M.
		if ( preg_match( '/^[A-Z]{3,5}\d{2}[A-Z]{0,4}$/i', $name ) ) {
			return 'inpost';
		}

		return false;
	}

	/**
	 * Get carrier config from country config file.
	 *
	 * @param string $carrier Carrier slug.
	 * @param string $country Country code (default: PL).
	 * @return array|false Carrier config or false.
	 */
	public static function get_config( $carrier, $country = 'PL' ) {
		$country = strtoupper( preg_replace( '/[^a-zA-Z]/', '', substr( $country, 0, 2 ) ) );
		if ( ! preg_match( '/^[A-Z]{2}$/', $country ) ) {
			return false;
		}
		$config_file = PARCSELECT_LABEL_DIR . 'config/' . $country . '.php';
		if ( ! file_exists( $config_file ) ) {
			return false;
		}

		$config = include $config_file;
		if ( ! isset( $config['carriers'][ $carrier ] ) ) {
			return false;
		}

		return $config['carriers'][ $carrier ];
	}

	/**
	 * Get service_id for a carrier.
	 * Checks per-carrier option first, falls back to global service_id.
	 *
	 * @param string $carrier Carrier slug.
	 * @return int Service ID or 0 if not configured.
	 */
	public static function get_service_id( $carrier ) {
		// Per-carrier service_id (from admin panel or auto-fetch).
		$per_carrier = get_option( 'parcselect_label_service_' . $carrier, '' );
		if ( ! empty( $per_carrier ) ) {
			return (int) $per_carrier;
		}

		// Fallback: global service_id (legacy single-carrier mode).
		return (int) get_option( 'parcselect_label_service_id', 0 );
	}

	/**
	 * Get available sizes for a carrier with dimensions.
	 *
	 * @param string $carrier Carrier slug.
	 * @param string $country Country code.
	 * @return array Sizes array [ 'A' => ['width'=>64, 'height'=>8, ...], ... ]
	 */
	public static function get_sizes( $carrier, $country = 'PL' ) {
		$config = self::get_config( $carrier, $country );
		if ( ! $config || empty( $config['sizes'] ) ) {
			// Fallback: InPost sizes.
			return array(
				'A' => array( 'width' => 64, 'height' => 8,  'depth' => 38, 'label' => 'A (8x38x64 cm)' ),
				'B' => array( 'width' => 64, 'height' => 19, 'depth' => 38, 'label' => 'B (19x38x64 cm)' ),
				'C' => array( 'width' => 64, 'height' => 41, 'depth' => 38, 'label' => 'C (41x38x64 cm)' ),
			);
		}

		return $config['sizes'];
	}

	/**
	 * Get tracking URL for a carrier.
	 *
	 * @param string $carrier         Carrier slug.
	 * @param string $tracking_number Tracking number.
	 * @param string $country         Country code.
	 * @return string Full tracking URL.
	 */
	public static function get_tracking_url( $carrier, $tracking_number, $country = 'PL' ) {
		$config = self::get_config( $carrier, $country );
		$base   = isset( $config['tracking_url'] ) ? $config['tracking_url'] : 'https://parcelselector.com/track/';
		return $base . $tracking_number;
	}

	/**
	 * Get the configured sender drop-off pickup point (InPost-only in the free version).
	 *
	 * @param string $carrier Carrier slug.
	 * @return string Pickup point ID or empty.
	 */
	public static function get_pickup_point( $carrier ) {
		return get_option( 'parcselect_label_pickup_' . $carrier, '' );
	}

	/**
	 * Check if carrier needs a pickup point from sender.
	 *
	 * @param string $carrier Carrier slug.
	 * @return bool
	 */
	public static function needs_pickup_point( $carrier ) {
		// InPost Paczkomaty: no sender pickup point required.
		return false;
	}
}
