<?php
/**
 * WPForms.
 *
 * @package TextTango
 */

declare( strict_types=1 );

namespace TextTango\Forms;

defined( 'ABSPATH' ) || exit;

/**
 * WPForms submissions (spec §21).
 *
 * WPForms keys its submitted values by numeric field id and carries the label
 * alongside, so the field a merchant picked in the settings screen — where they
 * saw labels — has to be matched back by label rather than by key.
 */
final class WPForms implements Provider {

	/**
	 * {@inheritDoc}
	 */
	public static function slug(): string {
		return 'wpforms';
	}

	/**
	 * {@inheritDoc}
	 */
	public static function label(): string {
		return __( 'WPForms', 'texttango' );
	}

	/**
	 * {@inheritDoc}
	 */
	public static function is_active(): bool {
		return function_exists( 'wpforms' );
	}

	/**
	 * {@inheritDoc}
	 *
	 * @return array<string, string>
	 */
	public static function forms(): array {
		if ( ! self::is_active() ) {
			return array();
		}

		$found = wpforms()->form->get( '', array( 'orderby' => 'title' ) );

		if ( ! is_array( $found ) ) {
			return array();
		}

		$forms = array();

		foreach ( $found as $form ) {
			if ( isset( $form->ID, $form->post_title ) ) {
				$forms[ (string) $form->ID ] = (string) $form->post_title;
			}
		}

		return $forms;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @param string $form_id Form id.
	 * @return string[]
	 */
	public static function fields( string $form_id ): array {
		if ( ! self::is_active() ) {
			return array();
		}

		$form = wpforms()->form->get( (int) $form_id, array( 'content_only' => true ) );

		if ( ! is_array( $form ) || ! isset( $form['fields'] ) || ! is_array( $form['fields'] ) ) {
			return array();
		}

		$names = array();

		foreach ( $form['fields'] as $field ) {
			$label = is_array( $field ) ? trim( (string) ( $field['label'] ?? '' ) ) : '';

			if ( '' !== $label ) {
				$names[] = $label;
			}
		}

		return array_values( array_unique( $names ) );
	}

	/**
	 * {@inheritDoc}
	 */
	public function register(): void {
		add_action( 'wpforms_process_complete', array( $this, 'submitted' ), 10, 3 );
	}

	/**
	 * Normalise a submission and hand it on.
	 *
	 * @param array<int, array<string, mixed>> $fields    Submitted fields.
	 * @param array<string, mixed>             $entry     Raw entry.
	 * @param array<string, mixed>             $form_data The form.
	 */
	public function submitted( $fields, $entry, $form_data ): void {
		if ( ! is_array( $fields ) || ! is_array( $form_data ) ) {
			return;
		}

		$values = array();

		foreach ( $fields as $field ) {
			if ( ! is_array( $field ) ) {
				continue;
			}

			$name = trim( (string) ( $field['name'] ?? '' ) );

			if ( '' === $name ) {
				continue;
			}

			$value = $field['value'] ?? '';

			$values[ $name ] = is_scalar( $value ) ? (string) $value : '';
		}

		Forms::handle(
			new Submission(
				self::slug(),
				(string) ( $form_data['id'] ?? '' ),
				(string) ( $form_data['settings']['form_title'] ?? '' ),
				$values
			)
		);
	}
}
