<?php

declare( strict_types=1 );

namespace Automattic\WooCommerce\Gateways\PayPal;

/**
 * Class AddressRequirements
 *
 * This helper class checks country-specific address requirements.
 * This was built based on {@see https://developer.paypal.com/api/rest/reference/orders/v2/country-address-requirements/}
 */
class AddressRequirements {
	/**
	 * The single instance of the class.
	 *
	 * @var AddressRequirements
	 */
	protected static $instance = null;

	/**
	 * Countries that require a city in the address.
	 *
	 * @var array
	 */
	private const COUNTRIES_REQUIRING_CITY = array(
		'AD',
		'AE',
		'AF',
		'AG',
		'AI',
		'AL',
		'AM',
		'AN',
		'AO',
		'AQ',
		'AR',
		'AS',
		'AT',
		'AU',
		'AW',
		'AZ',
		'BA',
		'BB',
		'BD',
		'BE',
		'BF',
		'BG',
		'BH',
		'BI',
		'BJ',
		'BM',
		'BN',
		'BO',
		'BR',
		'BS',
		'BT',
		'BV',
		'BW',
		'BY',
		'BZ',
		'CA',
		'CC',
		'CD',
		'CF',
		'CG',
		'CH',
		'CI',
		'CK',
		'CL',
		'CM',
		'CN',
		'CO',
		'CR',
		'CS',
		'CU',
		'CV',
		'CX',
		'CY',
		'CZ',
		'DE',
		'DJ',
		'DK',
		'DM',
		'DO',
		'DZ',
		'EC',
		'EE',
		'EG',
		'EH',
		'ER',
		'ES',
		'ET',
		'FI',
		'FJ',
		'FK',
		'FM',
		'FO',
		'FR',
		'GA',
		'GB',
		'GD',
		'GE',
		'GF',
		'GG',
		'GH',
		'GI',
		'GL',
		'GM',
		'GN',
		'GP',
		'GQ',
		'GR',
		'GS',
		'GT',
		'GU',
		'GW',
		'GY',
		'HK',
		'HM',
		'HN',
		'HR',
		'HT',
		'HU',
		'ID',
		'IE',
		'IL',
		'IM',
		'IN',
		'IO',
		'IQ',
		'IR',
		'IS',
		'IT',
		'JE',
		'JM',
		'JO',
		'JP',
		'KE',
		'KG',
		'KH',
		'KI',
		'KM',
		'KN',
		'KR',
		'KW',
		'KY',
		'KZ',
		'LA',
		'LB',
		'LC',
		'LI',
		'LK',
		'LR',
		'LS',
		'LT',
		'LU',
		'LV',
		'LY',
		'MA',
		'MC',
		'MD',
		'ME',
		'MG',
		'MH',
		'MK',
		'ML',
		'MM',
		'MN',
		'MO',
		'MP',
		'MQ',
		'MR',
		'MS',
		'MT',
		'MU',
		'MV',
		'MW',
		'MX',
		'MY',
		'MZ',
		'NA',
		'NC',
		'NE',
		'NF',
		'NG',
		'NI',
		'NL',
		'NO',
		'NP',
		'NR',
		'NU',
		'NZ',
		'OM',
		'PA',
		'PE',
		'PF',
		'PG',
		'PH',
		'PK',
		'PL',
		'PM',
		'PN',
		'PR',
		'PS',
		'PT',
		'PW',
		'PY',
		'QA',
		'RE',
		'RO',
		'RS',
		'RU',
		'RW',
		'SA',
		'SB',
		'SC',
		'SD',
		'SE',
		'SG',
		'SH',
		'SI',
		'SJ',
		'SK',
		'SL',
		'SM',
		'SN',
		'SO',
		'SR',
		'ST',
		'SV',
		'SY',
		'SZ',
		'TC',
		'TD',
		'TF',
		'TG',
		'TH',
		'TJ',
		'TL',
		'TM',
		'TN',
		'TO',
		'TP',
		'TR',
		'TT',
		'TV',
		'TW',
		'TZ',
		'UA',
		'UG',
		'UM',
		'US',
		'UY',
		'UZ',
		'VA',
		'VC',
		'VE',
		'VG',
		'VI',
		'VN',
		'VU',
		'WF',
		'WS',
		'YE',
		'YT',
		'YU',
		'ZA',
		'ZM',
		'ZW',
		'ZR',
		'C2',
	);

	/**
	 * Countries that require a postal code in the address.
	 *
	 * @var array
	 */
	private const COUNTRIES_REQUIRING_POSTAL_CODE = array(
		'AR',
		'AT',
		'AU',
		'BR',
		'BT',
		'CA',
		'C2',
		'CC',
		'CH',
		'CN',
		'DE',
		'DK',
		'EH',
		'ES',
		'FK',
		'FM',
		'FO',
		'FR',
		'GB',
		'GL',
		'GM',
		'IT',
		'JP',
		'KG',
		'KI',
		'KM',
		'MR',
		'MX',
		'NE',
		'NL',
		'NO',
		'NR',
		'NU',
		'NF',
		'PL',
		'PM',
		'PN',
		'SE',
		'SG',
		'SH',
		'SJ',
		'SM',
		'SR',
		'TF',
		'TH',
		'TK',
		'TV',
		'UM',
		'US',
		'VA',
		'WF',
		'YT',
	);

	/**
	 * Get class instance.
	 *
	 * @return AddressRequirements Instance.
	 */
	final public static function instance() {
		if ( null === static::$instance ) {
			static::$instance = new static();
		}
		return static::$instance;
	}

	/**
	 * Check if a country requires a city in the address.
	 *
	 * @param string $country_code The ISO 3166-1 alpha-2 country code.
	 * @return bool
	 */
	public function country_requires_city( string $country_code ) {
		return in_array( strtoupper( $country_code ), self::COUNTRIES_REQUIRING_CITY, true );
	}

	/**
	 * Check if a country requires a postal code in the address.
	 *
	 * @param string $country_code The ISO 3166-1 alpha-2 country code.
	 * @return bool
	 */
	public function country_requires_postal_code( string $country_code ) {
		return in_array( strtoupper( $country_code ), self::COUNTRIES_REQUIRING_POSTAL_CODE, true );
	}
}
