<?php
/** Provider-specific mappings for the portable form migration format. */

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

/** @param mixed $value */
function wpagent_form_migration_meaningful( $value ): bool {
	return ! in_array( $value, array( null, '', false, 0, '0', array(), 'no', 'none' ), true );
}

/** Numeric zero can be an intentional field constraint and must not be treated as empty. @param mixed $value */
function wpagent_form_migration_constraint_meaningful( $value ): bool {
	return ! in_array( $value, array( null, '', false, array(), 'no', 'none' ), true );
}

/** @param array<string,mixed> $field */
function wpagent_form_migration_issue( array &$field, string $reason ): void {
	$field['normalization_lossy'] = true;
	if ( empty( $field['normalization_reason'] ) ) {
		$field['normalization_reason'] = $reason;
	}
}

/** @param array<string,mixed> $raw @return array<string,mixed> */
function wpagent_form_migration_normalize_fluent_field( array $raw, int $index ): array {
	$settings   = is_array( $raw['settings'] ?? null ) ? $raw['settings'] : array();
	$attributes = is_array( $raw['attributes'] ?? null ) ? $raw['attributes'] : array();
	$type       = wpagent_form_migration_portable_type( 'fluent-forms', (string) ( $raw['element'] ?? '' ) );
	$lossy      = false;
	$choices    = array();
	foreach ( is_array( $settings['advanced_options'] ?? null ) ? $settings['advanced_options'] : array() as $choice ) {
		$choice = is_object( $choice ) ? get_object_vars( $choice ) : ( is_array( $choice ) ? $choice : array() );
		if ( wpagent_form_migration_meaningful( $choice['calc_value'] ?? null ) || wpagent_form_migration_meaningful( $choice['image'] ?? null ) ) {
			$lossy = true;
		}
		unset( $choice['id'], $choice['calc_value'], $choice['image'] );
		$choices[] = $choice;
	}
	$field      = array(
		'index'       => $index,
		'source_type' => sanitize_key( (string) ( $raw['element'] ?? '' ) ),
		'type'        => $type,
		'label'       => wpagent_form_migration_checked_text( $settings['label'] ?? '', 500, $lossy ),
		'key'         => sanitize_key( (string) ( $attributes['name'] ?? '' ) ),
		'description' => wpagent_form_migration_checked_text( $settings['help_message'] ?? '', 5000, $lossy ),
		'placeholder' => wpagent_form_migration_checked_text( $settings['placeholder'] ?? $attributes['placeholder'] ?? '', 1000, $lossy ),
		'default'     => wpagent_form_migration_checked_text( $attributes['value'] ?? '', 5000, $lossy ),
		'required'    => ! empty( $settings['validation_rules']['required']['value'] ),
		'choices'     => wpagent_form_migration_choices( $choices, $lossy ),
		'normalization_lossy' => $lossy,
		'normalization_reason' => '',
	);
	if ( '' === $type ) {
		wpagent_form_migration_issue( $field, 'unsupported_field_type' );
	} elseif ( '' === $field['label'] ) {
		wpagent_form_migration_issue( $field, 'missing_field_label' );
	} elseif ( ! empty( $raw['fields'] ) || ! empty( $raw['columns'] ) ) {
		wpagent_form_migration_issue( $field, 'nested_or_layout_field' );
	} elseif ( ! empty( $settings['conditional_logics'] ) ) {
		wpagent_form_migration_issue( $field, 'conditional_logic' );
	}
	$semantic_settings = array( 'dynamic_default_value', 'enable_image_input', 'calc_value_status', 'calculation_settings', 'multiple' );
	foreach ( $semantic_settings as $key ) {
		if ( wpagent_form_migration_meaningful( $settings[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	if ( ! in_array( $settings['randomize_options'] ?? '', array( '', 'no', false, null ), true ) ) {
		wpagent_form_migration_issue( $field, 'randomized_choices' );
	}
	if ( ! empty( $attributes['multiple'] ) ) {
		wpagent_form_migration_issue( $field, 'multiple_values' );
	}
	foreach ( array( 'min', 'max', 'step', 'minlength', 'maxlength' ) as $key ) {
		if ( wpagent_form_migration_constraint_meaningful( $attributes[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	foreach ( array( 'pattern', 'readonly', 'disabled', 'autocomplete', 'accept' ) as $key ) {
		if ( wpagent_form_migration_meaningful( $attributes[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	$inherent_rules = array( 'required' );
	if ( 'email' === $type ) {
		$inherent_rules[] = 'email';
	} elseif ( 'number' === $type ) {
		$inherent_rules[] = 'numeric';
	}
	foreach ( is_array( $settings['validation_rules'] ?? null ) ? $settings['validation_rules'] : array() as $key => $rule ) {
		if ( ! in_array( $key, $inherent_rules, true ) && wpagent_form_migration_meaningful( is_array( $rule ) ? ( $rule['value'] ?? null ) : $rule ) ) {
			wpagent_form_migration_issue( $field, 'validation_rules' );
		}
	}
	if ( $field['normalization_lossy'] && '' === $field['normalization_reason'] ) {
		$field['normalization_reason'] = 'unsupported_field_value';
	}
	return $field;
}

/** @param array<string,mixed> $raw @return array<string,mixed> */
function wpagent_form_migration_normalize_gravity_field( array $raw, int $index ): array {
	$type    = wpagent_form_migration_portable_type( 'gravity-forms', (string) ( $raw['type'] ?? '' ) );
	$lossy   = false;
	$choices = array();
	foreach ( is_array( $raw['choices'] ?? null ) ? $raw['choices'] : array() as $choice ) {
		$choice = is_object( $choice ) ? get_object_vars( $choice ) : ( is_array( $choice ) ? $choice : array() );
		if ( array_key_exists( 'text', $choice ) && ! array_key_exists( 'label', $choice ) ) {
			$choice['label'] = $choice['text'];
		}
		unset( $choice['text'] );
		$choices[] = $choice;
	}
	$field = array(
		'index'       => $index,
		'source_type' => sanitize_key( (string) ( $raw['type'] ?? '' ) ),
		'type'        => $type,
		'label'       => wpagent_form_migration_checked_text( $raw['label'] ?? '', 500, $lossy ),
		'key'         => sanitize_key( (string) ( $raw['inputName'] ?? '' ) ),
		'description' => wpagent_form_migration_checked_text( $raw['description'] ?? '', 5000, $lossy ),
		'placeholder' => wpagent_form_migration_checked_text( $raw['placeholder'] ?? '', 1000, $lossy ),
		'default'     => wpagent_form_migration_checked_text( $raw['defaultValue'] ?? '', 5000, $lossy ),
		'required'    => ! empty( $raw['isRequired'] ),
		'choices'     => wpagent_form_migration_choices( $choices, $lossy ),
		'normalization_lossy' => $lossy,
		'normalization_reason' => '',
	);
	if ( '' === $type ) {
		wpagent_form_migration_issue( $field, 'unsupported_field_type' );
	} elseif ( '' === $field['label'] ) {
		wpagent_form_migration_issue( $field, 'missing_field_label' );
	} elseif ( ! empty( $raw['conditionalLogic'] ) ) {
		wpagent_form_migration_issue( $field, 'conditional_logic' );
	}
	foreach ( array( 'maxLength', 'rangeMin', 'rangeMax' ) as $key ) {
		if ( wpagent_form_migration_constraint_meaningful( $raw[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	foreach ( array(
		'allowsPrepopulate', 'noDuplicates', 'enableCalculation', 'multiple', 'enablePasswordInput',
		'inputMask', 'inputMaskValue', 'calculationFormula',
		'calculationRounding', 'emailConfirmEnabled', 'adminOnly', 'autocompleteAttribute',
	) as $key ) {
		if ( wpagent_form_migration_meaningful( $raw[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	if ( isset( $raw['visibility'] ) && ! in_array( $raw['visibility'], array( '', 'visible' ), true ) ) {
		wpagent_form_migration_issue( $field, 'field_visibility' );
	}
	if ( $field['normalization_lossy'] && '' === $field['normalization_reason'] ) {
		$field['normalization_reason'] = 'unsupported_field_value';
	}
	return $field;
}

/** @param array<string,mixed> $raw @return array<string,mixed> */
function wpagent_form_migration_normalize_formidable_field( array $raw, int $index ): array {
	$field_options = is_array( $raw['field_options'] ?? null ) ? $raw['field_options'] : array();
	$type          = wpagent_form_migration_portable_type( 'formidable-forms', (string) ( $raw['type'] ?? '' ) );
	$lossy         = false;
	$choices       = array();
	foreach ( is_array( $raw['options'] ?? null ) ? $raw['options'] : array() as $choice ) {
		if ( is_scalar( $choice ) ) {
			$choices[] = array( 'label' => (string) $choice, 'value' => (string) $choice );
		} else {
			$choices[] = $choice;
		}
	}
	$field         = array(
		'index'       => $index,
		'source_type' => sanitize_key( (string) ( $raw['type'] ?? '' ) ),
		'type'        => $type,
		'label'       => wpagent_form_migration_checked_text( $raw['name'] ?? '', 500, $lossy ),
		'key'         => sanitize_key( (string) ( $raw['field_key'] ?? '' ) ),
		'description' => wpagent_form_migration_checked_text( $raw['description'] ?? '', 5000, $lossy ),
		'placeholder' => wpagent_form_migration_checked_text( $field_options['placeholder'] ?? '', 1000, $lossy ),
		'default'     => wpagent_form_migration_checked_text( $raw['default_value'] ?? '', 5000, $lossy ),
		'required'    => ! empty( $raw['required'] ),
		'choices'     => wpagent_form_migration_choices( $choices, $lossy ),
		'normalization_lossy' => $lossy,
		'normalization_reason' => '',
	);
	if ( '' === $type ) {
		wpagent_form_migration_issue( $field, 'unsupported_field_type' );
	} elseif ( '' === $field['label'] ) {
		wpagent_form_migration_issue( $field, 'missing_field_label' );
	}
	foreach ( array( 'limit', 'max_char', 'min', 'max', 'step' ) as $key ) {
		if ( wpagent_form_migration_constraint_meaningful( $field_options[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	foreach ( array(
		'multiple', 'read_only', 'unique', 'format',
		'separate_value', 'image_options', 'clear_on_focus', 'autocomplete', 'visibility',
	) as $key ) {
		if ( wpagent_form_migration_meaningful( $field_options[ $key ] ?? null ) ) {
			wpagent_form_migration_issue( $field, 'unsupported_field_settings' );
		}
	}
	if ( $field['normalization_lossy'] && '' === $field['normalization_reason'] ) {
		$field['normalization_reason'] = 'unsupported_field_value';
	}
	return $field;
}

/** @return string */
function wpagent_form_migration_unique_field_key( array $field, int $index, array &$used ): string {
	$base = sanitize_key( (string) ( $field['key'] ?? '' ) );
	if ( '' === $base ) {
		$base = sanitize_key( sanitize_title( (string) ( $field['label'] ?? '' ) ) );
	}
	if ( '' === $base ) {
		$base = 'field-' . ( $index + 1 );
	}
	$key    = $base;
	$suffix = 2;
	while ( isset( $used[ $key ] ) ) {
		$key = $base . '-' . $suffix++;
	}
	$used[ $key ] = true;
	return $key;
}

/** @param array<string,mixed> $portable @return array<string,mixed> */
function wpagent_form_migration_fluent_target_input( array $portable ): array {
	$type_map = array( 'text' => 'input_text', 'email' => 'input_email', 'textarea' => 'textarea', 'number' => 'input_number', 'checkbox' => 'input_checkbox', 'radio' => 'input_radio', 'select' => 'select' );
	$fields   = array();
	$used     = array();
	foreach ( $portable['fields'] as $index => $field ) {
		$key      = wpagent_form_migration_unique_field_key( $field, $index, $used );
		$element  = $type_map[ $field['type'] ];
		$validation_rules = array( 'required' => array( 'value' => $field['required'], 'message' => 'This field is required' ) );
		if ( 'email' === $field['type'] ) {
			$validation_rules['email'] = array( 'value' => true, 'message' => 'This field must contain a valid email' );
		} elseif ( 'number' === $field['type'] ) {
			$validation_rules['numeric'] = array( 'value' => true, 'message' => 'This field must contain numeric value' );
		}
		$settings = array(
			'label' => $field['label'], 'help_message' => $field['description'],
			'conditional_logics' => array(),
			'validation_rules' => $validation_rules,
		);
		$attribute_types = array( 'text' => 'text', 'email' => 'email', 'number' => 'number', 'checkbox' => 'checkbox', 'radio' => 'radio' );
		$attributes = array( 'name' => $key, 'value' => $field['default'], 'placeholder' => $field['placeholder'] );
		if ( isset( $attribute_types[ $field['type'] ] ) ) {
			$attributes['type'] = $attribute_types[ $field['type'] ];
		}
		if ( in_array( $field['type'], array( 'checkbox', 'radio', 'select' ), true ) ) {
			$settings['advanced_options'] = array_map(
				static fn( array $choice, int $choice_index ): array => array(
					'label' => $choice['label'], 'value' => $choice['value'], 'calc_value' => '', 'id' => $choice_index,
				),
				$field['choices'],
				array_keys( $field['choices'] )
			);
			$settings['randomize_options'] = 'no';
			$settings['enable_image_input'] = false;
			$settings['calc_value_status'] = false;
		}
		if ( 'select' === $field['type'] ) {
			$settings['placeholder'] = $field['placeholder'];
			unset( $attributes['placeholder'] );
		}
		$templates = array( 'text' => 'inputText', 'email' => 'inputText', 'textarea' => 'inputTextarea', 'number' => 'inputText', 'checkbox' => 'inputCheckable', 'radio' => 'inputCheckable', 'select' => 'select' );
		$fields[] = array(
			'index' => $index, 'uniqElKey' => 'wpagently_' . $key . '_' . ( $index + 1 ),
			'element' => $element, 'attributes' => $attributes, 'settings' => $settings,
			'editor_options' => array( 'template' => $templates[ $field['type'] ] ),
		);
	}
	$submit_label = ! empty( $portable['submit_label_portable'] ) ? (string) $portable['submit_label'] : __( 'Submit Form', 'wp-agent-companion' );
	return array(
		'title' => $portable['title'], 'status' => 'published',
		'form_fields' => array(
			'fields' => $fields,
			'submitButton' => array(
				'element' => 'button', 'attributes' => array( 'type' => 'submit' ),
				'settings' => array( 'button_ui' => array( 'type' => 'default', 'text' => $submit_label, 'img_url' => '' ) ),
			),
		),
	);
}

/** @param array<string,mixed> $portable @return array<string,mixed> */
function wpagent_form_migration_gravity_target_input( array $portable ): array {
	$fields = array();
	foreach ( $portable['fields'] as $index => $field ) {
		$field_id = $index + 1;
		$target   = array(
			'id' => $field_id, 'type' => $field['type'], 'label' => $field['label'],
			'description' => $field['description'], 'placeholder' => $field['placeholder'],
			'defaultValue' => $field['default'], 'isRequired' => $field['required'],
		);
		if ( $field['choices'] ) {
			$target['enableChoiceValue'] = true;
			$target['choices'] = array_map(
				static fn( array $choice ): array => array( 'text' => $choice['label'], 'value' => $choice['value'] ),
				$field['choices']
			);
		}
		if ( 'checkbox' === $field['type'] ) {
			$target['inputs'] = array();
			foreach ( $field['choices'] as $choice_index => $choice ) {
				$sequence = $choice_index + 1;
				$decimal  = $sequence + intdiv( $sequence - 1, 9 );
				$target['inputs'][] = array( 'id' => $field_id . '.' . $decimal, 'label' => $choice['label'], 'name' => '' );
			}
		}
		$fields[] = $target;
	}
	$input = array( 'title' => $portable['title'], 'fields' => $fields );
	if ( ! empty( $portable['submit_label_portable'] ) ) {
		$input['submit_label'] = $portable['submit_label'];
	}
	return $input;
}

/** @param array<string,mixed> $portable @return array<string,mixed> */
function wpagent_form_migration_formidable_target_input( array $portable ): array {
	$fields = array();
	$used   = array();
	foreach ( $portable['fields'] as $index => $field ) {
		$target = array(
			'field_key' => wpagent_form_migration_unique_field_key( $field, $index, $used ),
			'name' => $field['label'], 'description' => $field['description'], 'type' => $field['type'],
			'default_value' => $field['default'], 'required' => $field['required'], 'field_order' => $index,
			'field_options' => array(),
		);
		if ( '' !== $field['placeholder'] ) {
			$target['field_options']['placeholder'] = $field['placeholder'];
		}
		if ( $field['choices'] ) {
			$target['options'] = $field['choices'];
		}
		$fields[] = $target;
	}
	return array( 'name' => $portable['title'], 'status' => 'published', 'fields' => $fields );
}

/** Quotes one CF7 form-tag value without changing its text. */
function wpagent_form_migration_cf7_tag_literal( string $value ): string {
	if ( ! str_contains( $value, '"' ) ) {
		return '"' . $value . '"';
	}
	if ( ! str_contains( $value, "'" ) ) {
		return "'" . $value . "'";
	}
	// The preview gate rejects this lossy case. Keep direct helper calls syntactically valid.
	return '"' . str_replace( '"', '&quot;', $value ) . '"';
}

/** @param array<string,mixed> $portable @return array<int,array<string,mixed>> */
function wpagent_form_migration_target_issues( string $provider, array $portable ): array {
	if ( 'contact-form-7' !== $provider ) {
		return array();
	}
	$issues       = array();
	$submit_label = (string) $portable['submit_label'];
	if (
		preg_match( '/[\\\\\[\]\r\n]/', $submit_label )
		|| ( str_contains( $submit_label, '"' ) && str_contains( $submit_label, "'" ) )
	) {
		$issues[] = array(
			'index'           => -1,
			'source_type'     => 'submit',
			'label'           => (string) $portable['submit_label'],
			'reason'          => 'unsafe_submit_label',
			'target_provider' => $provider,
		);
	}
	foreach ( $portable['fields'] as $index => $field ) {
		$reason = '';
		if ( 'radio' === $field['type'] && empty( $field['required'] ) ) {
			$reason = 'radio_always_required';
		} elseif ( '' !== $field['placeholder'] && '' !== $field['default'] ) {
			$reason = 'placeholder_and_default';
		} else {
			$tag_values = array( $field['placeholder'], $field['default'] );
			foreach ( $field['choices'] as $choice ) {
				$tag_values[]  = $choice['label'];
				$tag_values[]  = $choice['value'];
				$choice_literal = (string) $choice['label'] . '|' . (string) $choice['value'];
				if ( str_contains( $choice_literal, '"' ) && str_contains( $choice_literal, "'" ) ) {
					$reason = 'unsafe_tag_syntax';
					break;
				}
			}
			foreach ( '' === $reason ? $tag_values : array() as $value ) {
				$value = (string) $value;
				if (
					preg_match( '/[\\\\\[\]\r\n|]/', $value )
					|| ( str_contains( $value, '"' ) && str_contains( $value, "'" ) )
				) {
					$reason = 'unsafe_tag_syntax';
					break;
				}
			}
		}
		if ( '' !== $reason ) {
			$issues[] = array(
				'index'           => (int) $index,
				'source_type'     => (string) $field['type'],
				'label'           => (string) $field['label'],
				'reason'          => $reason,
				'target_provider' => $provider,
			);
		}
	}
	return $issues;
}

/** @param array<string,mixed> $portable */
function wpagent_form_migration_cf7_markup( array $portable ): string {
	$rows = array();
	$used = array();
	foreach ( $portable['fields'] as $index => $field ) {
		$base = sanitize_key( (string) ( $field['key'] ?? '' ) );
		if ( '' === $base ) {
			$base = sanitize_key( sanitize_title( (string) $field['label'] ) );
		}
		if ( '' === $base ) {
			$base = 'field-' . ( $index + 1 );
		}
		$name   = $base;
		$suffix = 2;
		while ( isset( $used[ $name ] ) ) {
			$name = $base . '-' . $suffix++;
		}
		$used[ $name ] = true;
		$type_map = array( 'text' => 'text', 'email' => 'email', 'textarea' => 'textarea', 'number' => 'number', 'checkbox' => 'checkbox', 'radio' => 'radio', 'select' => 'select' );
		$type = $type_map[ $field['type'] ];
		if ( ! empty( $field['required'] ) && 'radio' !== $type ) {
			$type .= '*';
		}
		$parts = array( $type, $name );
		if ( in_array( $field['type'], array( 'checkbox', 'radio', 'select' ), true ) ) {
			if ( 'select' === $field['type'] && '' !== $field['placeholder'] ) {
				$parts[] = 'first_as_label';
				$parts[] = wpagent_form_migration_cf7_tag_literal( (string) $field['placeholder'] );
			}
			if ( in_array( $field['type'], array( 'checkbox', 'radio' ), true ) ) {
				$parts[] = 'use_label_element';
			}
			foreach ( $field['choices'] as $choice ) {
				$parts[] = wpagent_form_migration_cf7_tag_literal( (string) $choice['label'] . '|' . (string) $choice['value'] );
			}
		} elseif ( '' !== $field['placeholder'] ) {
			$parts[] = 'placeholder';
			$parts[] = wpagent_form_migration_cf7_tag_literal( (string) $field['placeholder'] );
		} elseif ( '' !== $field['default'] ) {
			$parts[] = wpagent_form_migration_cf7_tag_literal( (string) $field['default'] );
		}
		$tag = '[' . implode( ' ', $parts ) . ']';
		if ( in_array( $field['type'], array( 'checkbox', 'radio' ), true ) ) {
			$row = '<fieldset class="wpagently-field"><legend>' . esc_html( (string) $field['label'] ) . '</legend>' . $tag;
			$closing = '</fieldset>';
		} else {
			$row = '<p class="wpagently-field"><label>' . esc_html( (string) $field['label'] ) . ' ' . $tag . '</label>';
			$closing = '</p>';
		}
		if ( '' !== $field['description'] ) {
			$row .= '<small class="wpagently-field-description">' . esc_html( (string) $field['description'] ) . '</small>';
		}
		$rows[] = $row . $closing;
	}
	$submit_label = ! empty( $portable['submit_label_portable'] ) ? (string) $portable['submit_label'] : __( 'Senden', 'wp-agent-companion' );
	$rows[] = '[submit ' . wpagent_form_migration_cf7_tag_literal( $submit_label ) . ']';
	return implode( "\n", $rows );
}
