<?php
/**
 * Class WooCommerceDHLPolskaSettingsFields
 *
 * @package DhlPolska\WooCommerceSettings
 */

namespace DhlPolska\WooCommerceSettings;

use DhlPolska\CheckConnectionStatus;
use DhlPolska\SettingsFields;
use DhlPolska\Shipment\ShipmentData;
use DhlPolska\Shipment\ShipmentTypes;
use DhlPolska\WooCommerceSettings\Templates\TemplatesRepository;
use DhlPolska\WooCommerceSettings\Field\ConnectionStatusField;

/**
 * DHL Polska Settings Fields.
 */
class WooCommerceDHLPolskaSettingsFields implements SettingsFields {

	public const SHIPPING_METHOD_ID = 'dhl_polska';

	public const FIELD_TITLE      = self::SHIPPING_METHOD_ID . '_title';
	public const OPTION_TEST_MODE = self::SHIPPING_METHOD_ID . '_test_mode';

	public const OPTION_WEBAPI_LOGIN      = self::SHIPPING_METHOD_ID . '_webapi_login';
	public const OPTION_WEBAPI_PASSWORD   = self::SHIPPING_METHOD_ID . '_webapi_password';
	public const OPTION_WEBAPI_SAP_NUMBER = self::SHIPPING_METHOD_ID . '_webapi_sap_number';

	public const OPTION_TEST_WEBAPI_LOGIN      = self::SHIPPING_METHOD_ID . '_test_webapi_login';
	public const OPTION_TEST_WEBAPI_PASSWORD   = self::SHIPPING_METHOD_ID . '_test_webapi_password';
	public const OPTION_TEST_WEBAPI_SAP_NUMBER = self::SHIPPING_METHOD_ID . '_test_webapi_sap_number';

	public const OPTION_WEBAPI_CONNECTION_STATUS = self::SHIPPING_METHOD_ID . '_webapi_connection_status';

	public const OPTION_LABEL_MODE            = self::SHIPPING_METHOD_ID . '_label_mode';
	public const OPTION_EMAIL_TRACKING_NUMBER = self::SHIPPING_METHOD_ID . '_email_tracking_number';
	public const OPTION_DEFAULT_TEMPLATE_ID   = self::SHIPPING_METHOD_ID . '_default_template_id';

	public const OPTION_SENDER_NAME         = self::SHIPPING_METHOD_ID . '_sender_name';
	public const OPTION_SENDER_STREET       = self::SHIPPING_METHOD_ID . '_sender_street';
	public const OPTION_SENDER_HOUSE_NUMBER = self::SHIPPING_METHOD_ID . '_sender_house_number';
	public const OPTION_SENDER_POSTCODE     = self::SHIPPING_METHOD_ID . '_sender_postcode';
	public const OPTION_SENDER_CITY         = self::SHIPPING_METHOD_ID . '_sender_city';
	public const OPTION_SENDER_PHONE        = self::SHIPPING_METHOD_ID . '_sender_phone';
	public const OPTION_SENDER_EMAIL        = self::SHIPPING_METHOD_ID . '_sender_email';

	public const OPTION_AUTO_SHIPMENT_STATUS = self::SHIPPING_METHOD_ID . '_auto_shipment_status';
	public const OPTION_AUTO_COURIER_STATUS  = self::SHIPPING_METHOD_ID . '_auto_courier_status';
	public const OPTION_COURIER_PICKUP_START = self::SHIPPING_METHOD_ID . '_courier_pickup_start';
	public const OPTION_COURIER_PICKUP_END   = self::SHIPPING_METHOD_ID . '_courier_pickup_end';
	public const OPTION_SHIPMENT_DATE_CUTOFF = self::SHIPPING_METHOD_ID . '_shipment_date_cutoff';
	public const OPTION_COURIER_DATE_CUTOFF  = self::SHIPPING_METHOD_ID . '_courier_date_cutoff';

	public const OPTION_RETURN_SHIPMENT_TYPE    = self::SHIPPING_METHOD_ID . '_return_shipment_type';
	public const OPTION_RETURN_LABEL_EXPIRATION = self::SHIPPING_METHOD_ID . '_return_label_expiration';
	public const OPTION_LOGGING_ENABLED         = self::SHIPPING_METHOD_ID . '_logging_enabled';

	public const LABEL_BLP     = 'BLP';
	public const LABEL_LBLP    = 'LBLP';
	public const LABEL_ZBLP    = 'ZBLP';
	public const LABEL_ZBLP300 = 'ZBLP300';

	private TemplatesRepository $templates_repository;

	private ShipmentTypes $shipment_types;

	public function __construct( ?TemplatesRepository $templates_repository = null, ?ShipmentTypes $shipment_types = null ) {
		$this->shipment_types       = $shipment_types ?? new ShipmentTypes();
		$this->templates_repository = $templates_repository ?? new TemplatesRepository( new WooCommerceDHLPolskaSettings(), $this->shipment_types );
	}

	/**
	 * @return array<int|string, array<string, array<string, float|int|string>|bool|float|int|string>>
	 */
	public function get_settings_fields(): array {
		return [
			'section_general_settings'                => [
				'title' => __( 'Ogólne', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_TEST_MODE                    => [
				'id'       => self::OPTION_TEST_MODE,
				'title'    => __( 'Tryb testowy', 'dhl-polska' ),
				'type'     => 'checkbox',
				'desc'     => __( 'Włącz tryb testowy', 'dhl-polska' ),
				'class'    => 'js--environment-field',
				'desc_tip' => sprintf(
				// Translators: open strong tag, close strong tag.
					__( 'Jeśli %1$sTryb testowy%2$s został włączony, wypełnij poniższe pola danymi dostępowymi do konta testowego DHL.', 'dhl-polska' ),
					'<strong>',
					'</strong>'
				),
			],
			[
				'type' => 'sectionend',
			],
			'section_auth_webapi'                     => [
				'title' => __( 'DHL24 WebAPI v2 (kurier i punkty)', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_WEBAPI_LOGIN                 => [
				'id'                => self::OPTION_WEBAPI_LOGIN,
				'type'              => 'text',
				'title'             => __( 'Login WebAPI', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--production-field',
				'desc_tip'          => __( 'Wprowadź login do konta DHL WebAPI v2.', 'dhl-polska' ),

			],
			self::OPTION_WEBAPI_PASSWORD              => [
				'id'                => self::OPTION_WEBAPI_PASSWORD,
				'type'              => 'password',
				'title'             => __( 'Hasło WebAPI', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--production-field',
				'desc_tip'          => __( 'Wprowadź hasło do konta DHL WebAPI v2.', 'dhl-polska' ),
			],
			self::OPTION_WEBAPI_SAP_NUMBER            => [
				'id'                => self::OPTION_WEBAPI_SAP_NUMBER,
				'type'              => 'text',
				'title'             => __( 'Numer SAP WebAPI', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--production-field',
				'desc_tip'          => __( 'Wprowadź numer SAP (klienta) dla DHL WebAPI v2.', 'dhl-polska' ),
			],
			self::OPTION_TEST_WEBAPI_LOGIN            => [
				'id'                => self::OPTION_TEST_WEBAPI_LOGIN,
				'type'              => 'text',
				'title'             => __( 'Login WebAPI (test)', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--sandbox-field',
				'desc_tip'          => __( 'Wprowadź login do testowego konta DHL WebAPI v2.', 'dhl-polska' ),
			],
			self::OPTION_TEST_WEBAPI_PASSWORD         => [
				'id'                => self::OPTION_TEST_WEBAPI_PASSWORD,
				'type'              => 'password',
				'title'             => __( 'Hasło WebAPI (test)', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--sandbox-field',
				'desc_tip'          => __( 'Wprowadź hasło do testowego konta DHL WebAPI v2.', 'dhl-polska' ),
			],
			self::OPTION_TEST_WEBAPI_SAP_NUMBER       => [
				'id'                => self::OPTION_TEST_WEBAPI_SAP_NUMBER,
				'type'              => 'text',
				'title'             => __( 'Numer SAP WebAPI (test)', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'class'             => 'js--sandbox-field',
				'desc_tip'          => __( 'Wprowadź numer SAP (klienta) dla testowego DHL WebAPI v2.', 'dhl-polska' ),
			],
			self::OPTION_WEBAPI_CONNECTION_STATUS     => [
				'id'    => self::OPTION_WEBAPI_CONNECTION_STATUS,
				'type'  => ConnectionStatusField::FIELD_TYPE,
				'title' => __( 'Status połączenia', 'dhl-polska' ),
				'ajax'  => [
					'action' => CheckConnectionStatus::AJAX_ACTION_WEBAPI,
					'nonce'  => wp_create_nonce( CheckConnectionStatus::AJAX_ACTION_WEBAPI ),
					'url'    => admin_url( 'admin-ajax.php' ),
				],
			],
			[
				'type' => 'sectionend',
			],
			'section_sender_settings'                 => [
				'title' => __( 'Dane nadawcy', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_SENDER_NAME                  => [
				'id'                => self::OPTION_SENDER_NAME,
				'type'              => 'text',
				'title'             => __( 'Nazwa', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
			],
			self::OPTION_SENDER_STREET                => [
				'id'                => self::OPTION_SENDER_STREET,
				'type'              => 'text',
				'title'             => __( 'Ulica', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
			],
			self::OPTION_SENDER_HOUSE_NUMBER          => [
				'id'                => self::OPTION_SENDER_HOUSE_NUMBER,
				'type'              => 'text',
				'title'             => __( 'Numer domu', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
			],
			self::OPTION_SENDER_POSTCODE              => [
				'id'                => self::OPTION_SENDER_POSTCODE,
				'type'              => 'text',
				'title'             => __( 'Kod pocztowy', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
			],
			self::OPTION_SENDER_CITY                  => [
				'id'                => self::OPTION_SENDER_CITY,
				'type'              => 'text',
				'title'             => __( 'Miasto', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
			],
			self::OPTION_SENDER_PHONE                 => [
				'id'    => self::OPTION_SENDER_PHONE,
				'type'  => 'text',
				'title' => __( 'Telefon', 'dhl-polska' ),
			],
			self::OPTION_SENDER_EMAIL                 => [
				'id'    => self::OPTION_SENDER_EMAIL,
				'type'  => 'email',
				'title' => __( 'Email', 'dhl-polska' ),
			],
			[
				'type' => 'sectionend',
			],
			'section_automation_settings'             => [
				'title' => __( 'Automatyzacja', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_DEFAULT_TEMPLATE_ID          => [
				'id'       => self::OPTION_DEFAULT_TEMPLATE_ID,
				'title'    => __( 'Domyślny szablon przesyłki', 'dhl-polska' ),
				'type'     => 'select',
				'options'  => $this->get_default_template_options(),
				'desc_tip' => __( 'Wybierz szablon przesyłki używany domyślnie.', 'dhl-polska' ),
			],
			self::OPTION_AUTO_SHIPMENT_STATUS         => [
				'id'       => self::OPTION_AUTO_SHIPMENT_STATUS,
				'type'     => 'multiselect',
				'title'    => __( 'Automatyczne tworzenie przesyłek', 'dhl-polska' ),
				'desc'     => __( 'Wybierz statusy zamówienia, dla których przesyłki będą tworzone automatycznie.', 'dhl-polska' ),
				'options'  => $this->get_order_statuses(),
				'class'    => 'wc-enhanced-select',
				'desc_tip' => true,
			],
			self::OPTION_AUTO_COURIER_STATUS          => [
				'id'       => self::OPTION_AUTO_COURIER_STATUS,
				'type'     => 'multiselect',
				'title'    => __( 'Automatyczne zamawianie kuriera', 'dhl-polska' ),
				'desc'     => __( 'Wybierz statusy zamówienia, dla których kurier będzie zamawiany automatycznie.', 'dhl-polska' ),
				'options'  => $this->get_order_statuses(),
				'class'    => 'wc-enhanced-select',
				'desc_tip' => true,
			],
			self::OPTION_SHIPMENT_DATE_CUTOFF         => [
				'id'                => self::OPTION_SHIPMENT_DATE_CUTOFF,
				'type'              => 'text',
				'title'             => __( 'Godzina, po której nastąpi zmiana daty nadania na następny dzień roboczy', 'dhl-polska' ),
				'placeholder'       => 'HH:MM',
				'custom_attributes' => [
					'inputmode' => 'numeric',
					'maxlength' => '5',
					'pattern'   => '^([01][0-9]|2[0-3]):[0-5][0-9]$',
				],
			],
			self::OPTION_COURIER_DATE_CUTOFF          => [
				'id'                => self::OPTION_COURIER_DATE_CUTOFF,
				'type'              => 'text',
				'title'             => __( 'Godzina, po której nastąpi zmiana daty zamówienia kuriera na następny dzień roboczy', 'dhl-polska' ),
				'placeholder'       => 'HH:MM',
				'custom_attributes' => [
					'inputmode' => 'numeric',
					'maxlength' => '5',
					'pattern'   => '^([01][0-9]|2[0-3]):[0-5][0-9]$',
				],
			],
			self::OPTION_COURIER_PICKUP_START         => [
				'id'                => self::OPTION_COURIER_PICKUP_START,
				'type'              => 'text',
				'title'             => __( 'Początek okna odbioru przez kuriera', 'dhl-polska' ),
				'default'           => '10:00',
				'placeholder'       => 'HH:MM',
				'custom_attributes' => [
					'inputmode' => 'numeric',
					'maxlength' => '5',
					'pattern'   => '^([01][0-9]|2[0-3]):[0-5][0-9]$',
				],
			],
			self::OPTION_COURIER_PICKUP_END           => [
				'id'                => self::OPTION_COURIER_PICKUP_END,
				'type'              => 'text',
				'title'             => __( 'Koniec okna odbioru przez kuriera', 'dhl-polska' ),
				'default'           => '16:00',
				'placeholder'       => 'HH:MM',
				'custom_attributes' => [
					'inputmode' => 'numeric',
					'maxlength' => '5',
					'pattern'   => '^([01][0-9]|2[0-3]):[0-5][0-9]$',
				],
			],
			[
				'type' => 'sectionend',
			],
			'section_returns_settings'                => [
				'title' => __( 'Przesyłki zwrotne', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_RETURN_SHIPMENT_TYPE         => [
				'id'      => self::OPTION_RETURN_SHIPMENT_TYPE,
				'type'    => 'select',
				'title'   => __( 'Typ zwrotu', 'dhl-polska' ),
				'desc'    => __( 'Ustawienia zwrotów dotyczą wyłącznie zwrotów krajowych. Zwroty zagraniczne są możliwe tylko przez nadanie w punkcie.', 'dhl-polska' ),
				'options' => [
					'point'   => __( 'Punkt odbioru', 'dhl-polska' ),
					'courier' => __( 'Punkt odbioru lub kurier', 'dhl-polska' ),
				],
			],
			self::OPTION_RETURN_LABEL_EXPIRATION      => [
				'id'                => self::OPTION_RETURN_LABEL_EXPIRATION,
				'type'              => 'number',
				'title'             => __( 'Ważność etykiety zwrotnej (dni)', 'dhl-polska' ),
				'default'           => 14,
				'custom_attributes' => [
					'min'  => 1,
					'step' => 1,
				],
			],
			[
				'type' => 'sectionend',
			],
			'section_other_settings'                  => [
				'title' => __( 'Etykiety', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_LABEL_MODE                   => [
				'id'                => self::OPTION_LABEL_MODE,
				'type'              => 'select',
				'title'             => __( 'Format etykiety', 'dhl-polska' ) . '*',
				'custom_attributes' => [
					'required' => 'required',
				],
				'options'           => $this->get_label_mode_options(),
				'desc_tip'          => __( 'Wybierz format etykiety wysyłkowej z dostępnych opcji.', 'dhl-polska' ),
			],
			self::OPTION_EMAIL_TRACKING_NUMBER        => [
				'id'    => self::OPTION_EMAIL_TRACKING_NUMBER,
				'title' => __( 'Numer śledzenia', 'dhl-polska' ),
				'type'  => 'checkbox',
				'desc'  => __( 'Dodaj numer nadania DHL wraz z linkiem do śledzenia do wiadomości e-mail WooCommerce oraz szczegółów zamówienia.', 'dhl-polska' ),
			],
			'section_general_settings_end'            => [
				'type' => 'sectionend',
			],
			'section_advanced_settings'               => [
				'title' => __( 'Zaawansowane', 'dhl-polska' ),
				'type'  => 'title',
			],
			self::OPTION_LOGGING_ENABLED              => [
				'id'    => self::OPTION_LOGGING_ENABLED,
				'title' => __( 'Zapis zdarzeń', 'dhl-polska' ),
				'type'  => 'checkbox',
				'desc'  => sprintf(
				// Translators: link to WooCommerce logs.
					__( 'Włącz zapis zdarzeń do logów.%1$sZapis zdarzeń należy włączać tylko podczas diagnozowania problemów. Zdarzenia zapisywane są w %2$s.%3$s', 'dhl-polska' ),
					'<br/><p class="description">',
					'<a href="' . admin_url( 'admin.php?page=wc-status&tab=logs' ) . '">' . __( 'dzienniku WooCommerce', 'dhl-polska' ) . '</a>',
					'</p>'
				),
			],
			'section_advanced_settings_end'           => [
				'type' => 'sectionend',
			],
		];
	}

	/**
	 * @return array<string, string>
	 */
	public function get_order_statuses(): array {
		if ( function_exists( 'wc_get_order_statuses' ) ) {
			return (array) wc_get_order_statuses();
		}

		return [];
	}

	/**
	 * @return array<string, string>
	 */
	public function get_label_mode_options(): array {
		return [
			self::LABEL_BLP     => __( 'BLP – etykieta PDF 10x15cm', 'dhl-polska' ),
			self::LABEL_LBLP    => __( 'LBLP – etykieta PDF A4', 'dhl-polska' ),
			self::LABEL_ZBLP    => __( 'ZBLP – etykieta ZPL', 'dhl-polska' ),
			self::LABEL_ZBLP300 => __( 'ZBLP300 – etykieta ZPL 300dpi', 'dhl-polska' ),
		];
	}

	/**
	 * @return array<string, string>
	 */
	private function get_default_template_options(): array {
		$options = [
			'' => __( 'Brak', 'dhl-polska' ),
		];

		$templates = $this->templates_repository->get_templates();
		foreach ( $templates as $template ) {
			if ( ! isset( $template['id'], $template['name'] ) ) {
				continue;
			}

			$options[ (string) $template['id'] ] = $this->format_template_option_label( $template );
		}

		return $options;
	}

	/**
	 * @param array<string, mixed> $template .
	 */
	private function format_template_option_label( array $template ): string {
		$weight_unit    = get_option( 'woocommerce_weight_unit', 'kg' );
		$dimension_unit = get_option( 'woocommerce_dimension_unit', 'cm' );
		$weight         = wc_format_decimal( (string) ( $template['weight'] ?? '' ) );
		$type_labels    = $this->shipment_types->get_type_labels();
		$type_label     = $type_labels[ (string) ( $template['type'] ?? '' ) ] ?? (string) ( $template['type'] ?? '' );
		$dimensions     = sprintf(
			'%sx%sx%s',
			(string) ( $template['dimensions']['length'] ?? '' ),
			(string) ( $template['dimensions']['width'] ?? '' ),
			(string) ( $template['dimensions']['height'] ?? '' )
		);
		$cod            = (bool) ( $template['services'][ ShipmentData::TEMPLATE_SERVICE_COD ] ?? false );
		$insurance      = (bool) ( $template['services'][ ShipmentData::TEMPLATE_SERVICE_INSURANCE ] ?? false );

		$details = [
			$type_label,
			trim( $weight . ' ' . $weight_unit ),
			trim( $dimensions . ' ' . $dimension_unit ),
		];

		if ( $cod ) {
			$details[] = __( 'Pobranie', 'dhl-polska' );
		}

		if ( $insurance ) {
			$details[] = __( 'Ubezpieczenie', 'dhl-polska' );
		}

		return sprintf(
			'%s (%s)',
			(string) ( $template['name'] ?? '' ),
			implode( ', ', $details )
		);
	}
}
