<?php
/** Bounded native Contact Form 7 source adapter for migration preflights. */

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

const WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_FIELDS  = 200;
const WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_CHOICES = 201;
const WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_OPTIONS = 100;

/** @return WP_Error */
function wpagent_form_migration_cf7_source_error( string $field ): WP_Error {
	return new WP_Error(
		'wpagent_form_migration_source_too_large',
		__( 'Die native Contact-Form-7-Quelle überschreitet die sichere Migrationsgrenze.', 'wp-agent-companion' ),
		array( 'status' => 413, 'field' => $field )
	);
}

/** @return string|WP_Error */
function wpagent_form_migration_cf7_source_text( $value, int $maximum, string $field ) {
	if ( ! is_string( $value ) || strlen( $value ) > $maximum || wp_check_invalid_utf8( $value, true ) !== $value ) {
		return wpagent_form_migration_cf7_source_error( $field );
	}
	return $value;
}

/** @return array<int,string>|WP_Error */
function wpagent_form_migration_cf7_source_strings( $value, int $maximum, string $field ): array|WP_Error {
	if ( ! is_array( $value ) || ! array_is_list( $value ) || count( $value ) > $maximum ) {
		return wpagent_form_migration_cf7_source_error( $field );
	}
	$result = array();
	foreach ( $value as $index => $item ) {
		$text = wpagent_form_migration_cf7_source_text( $item, WPAGENT_FORMS_PUBLIC_MAX_TEXT, $field . '.' . $index );
		if ( is_wp_error( $text ) ) {
			return $text;
		}
		$result[] = $text;
	}
	return $result;
}

/**
 * Public CF7 reads reject values beyond their 100-choice output contract.
 * Migration uses this separate, internal projection only to identify the
 * bounded 201st value and refuse a lossy transfer before any target write.
 * No raw source object reaches the public migration response.
 *
 * @return array{title:string,form:string,fields:array<int,array<string,mixed>>}|WP_Error
 */
function wpagent_form_migration_cf7_read_source( int $form_id ) {
	$form = wpagent_cf7_get_authorized_form( array( 'form_id' => $form_id ), 'wpcf7_read_contact_forms' );
	if ( is_wp_error( $form ) ) {
		return $form;
	}
	$markup = wpagent_form_migration_cf7_source_text( $form->prop( 'form' ), WPAGENT_CF7_MAX_FORM_BYTES, 'form' );
	$title  = wpagent_form_migration_cf7_source_text( $form->title(), WPAGENT_CF7_MAX_TITLE_BYTES, 'title' );
	$tags   = $form->scan_form_tags();
	if ( is_wp_error( $markup ) || is_wp_error( $title ) ) {
		return is_wp_error( $markup ) ? $markup : $title;
	}
	if ( ! is_array( $tags ) || count( $tags ) > WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_FIELDS ) {
		return wpagent_form_migration_cf7_source_error( 'fields' );
	}
	$fields = array();
	foreach ( array_values( $tags ) as $index => $tag ) {
		if ( ! $tag instanceof WPCF7_FormTag ) {
			return wpagent_form_migration_cf7_source_error( 'fields.' . $index );
		}
		$type = wpagent_form_migration_cf7_source_text( $tag->type, 128, 'fields.' . $index . '.type' );
		$base = wpagent_form_migration_cf7_source_text( $tag->basetype, 128, 'fields.' . $index . '.basetype' );
		$name = wpagent_form_migration_cf7_source_text( $tag->name, 128, 'fields.' . $index . '.name' );
		$options = wpagent_form_migration_cf7_source_strings( $tag->options, WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_OPTIONS, 'fields.' . $index . '.options' );
		$values = wpagent_form_migration_cf7_source_strings( $tag->raw_values, WPAGENT_FORM_MIGRATION_CF7_MAX_SOURCE_CHOICES, 'fields.' . $index . '.raw_values' );
		foreach ( array( $type, $base, $name, $options, $values ) as $value ) {
			if ( is_wp_error( $value ) ) {
				return $value;
			}
		}
		$fields[] = array( 'type' => $type, 'basetype' => $base, 'name' => $name, 'options' => $options, 'raw_values' => $values );
	}
	return array( 'title' => $title, 'form' => $markup, 'fields' => $fields );
}
