<?php

declare( strict_types=1 );

namespace DocketConnector\Docket;

use DocketConnector\Common\Settings\Choices;
use DocketConnector\PluginData;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Abort if this file is called directly.
}

if ( ! class_exists( Api::class ) ) {
	/**
	 * The Docket API information.
	 */
	class Api {

		/** @var Choices */
		private $choices;

		/** @var string */
		private static $which = '';

		/** @var string */
		private static $api_key = '';

		/** @var bool */
		private static $staging;

		/**
		 * Api constructor.
		 *
		 * @param string $which   Which API URL/endpoint to use. Example: 'invoice'.
		 * @param string $api_key The API key to use.
		 * @param bool   $staging Whether to use the staging version of the specified API/endpoint.
		 */
		public function __construct(
			string $which,
			string $api_key,
			bool $staging = false
		) {
			$this->choices   = new Choices();
			static::$which   = sanitize_key( $which );
			static::$api_key = $this->choices->sanitize_docket_api_key( $api_key );
			static::$staging = (bool) $staging;
		}

		/**
		 * The list of APIs and their supported URLs.
		 *
		 * @return string[][]
		 */
		private function get_api_url_map(): array {
			return [
				'invoice' => [
					'prod'    => 'https://app.yourdocket.com/httpApiCreateInvoice',
					'staging' => 'https://app.docket.works/CreateInvoice',
				],
			];
		}

		/**
		 * Whether to use the staging version of the specified Docket API/endpoint.
		 *
		 * @return bool
		 */
		private function use_docket_staging_api(): bool {
			/**
			 * Whether to use Docket's staging URL instead of production. Consult Docket Support before enabling!
			 *
			 * @since 1.0.0
			 *
			 * @param bool $staging Whether to use staging URLs for API calls.
			 *
			 * @return bool
			 */
			return (bool) apply_filters( PluginData::plugin_text_domain_underscores() . '_' . __FUNCTION__, static::$staging );
		}

		/**
		 * Get the base URL.
		 *
		 * @return string The unescaped base URL. Empty if bad setup.
		 */
		private function get_url_base(): string {
			$urls = $this->get_api_url_map();

			if ( $this->use_docket_staging_api() ) {
				$use = 'staging';
			} else {
				$use = 'prod';
			}

			if ( isset( $urls[ static::$which ][ $use ] ) ) {
				return $urls[ static::$which ][ $use ];
			}

			return '';
		}

		/**
		 * Get the unescaped Docket API URL for the specified API/endpoint and API key.
		 *
		 * Example: https://app.yourdocket.com/httpApiCreateInvoice?api_key=abc123
		 *
		 * @return string The unescaped URL (including API key) to send Docket data. Empty if bad setup.
		 */
		public function get_api_url(): string {
			if ( ! $this->choices->is_valid_format_docket_api_key( static::$api_key ) ) {
				return '';
			}

			$base = $this->get_url_base();

			if ( empty( $base ) ) {
				return '';
			}

			return add_query_arg( [ $this->choices->slug_api_key => static::$api_key ], $base );
		}
	}
}