<?php
/**
 * Shared Contact Form 7 adapter helpers.
 *
 * All reads and writes go through Contact Form 7's public object API. Raw
 * post-meta writes are deliberately forbidden because they bypass its
 * sanitizers, lifecycle hooks and configuration validator.
 *
 * @package WPAgentCompanion
 */

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

function wpagent_cf7_available(): bool {
	return class_exists( 'WPCF7_ContactForm' ) && function_exists( 'wpcf7_contact_form' );
}

function wpagent_cf7_missing_error(): WP_Error {
	return new WP_Error(
		'wpagent_cf7_missing',
		__( 'Contact Form 7 ist nicht aktiv oder nicht vollständig geladen.', 'wp-agent-companion' ),
		array( 'status' => 400 )
	);
}

/** @param mixed $input */
function wpagent_perm_cf7_read( $input = null ): bool {
	return current_user_can( 'wpcf7_read_contact_forms' );
}

/** @param mixed $input */
function wpagent_perm_cf7_edit( $input = null ): bool {
	return current_user_can( 'wpcf7_edit_contact_forms' );
}

/**
 * @param mixed  $input
 * @param string $capability
 * @return WPCF7_ContactForm|WP_Error
 */
function wpagent_cf7_get_authorized_form( $input, string $capability ) {
	if ( ! wpagent_cf7_available() ) {
		return wpagent_cf7_missing_error();
	}
	$input   = is_array( $input ) ? $input : array();
	$form_id = (int) ( $input['form_id'] ?? 0 );
	if ( $form_id <= 0 ) {
		return new WP_Error( 'wpagent_bad_form_id', __( 'form_id muss eine positive Ganzzahl sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$form = wpcf7_contact_form( $form_id );
	if ( ! $form ) {
		return new WP_Error( 'wpagent_cf7_not_found', __( 'Contact-Form-7-Formular nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( ! current_user_can( $capability, $form_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung für dieses Formular.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	return $form;
}

/** @return array<int,array<string,mixed>> */
function wpagent_cf7_fields( WPCF7_ContactForm $form ): array {
	$fields = array();
	foreach ( $form->scan_form_tags() as $tag ) {
		$fields[] = array(
			'type'       => (string) $tag->type,
			'basetype'   => (string) $tag->basetype,
			'name'       => (string) $tag->name,
			'options'    => array_values( array_map( 'strval', (array) $tag->options ) ),
			'raw_values' => array_values( array_map( 'strval', (array) $tag->raw_values ) ),
			'labels'     => array_values( array_map( 'strval', (array) $tag->labels ) ),
			'values'     => array_values( array_map( 'strval', (array) $tag->values ) ),
			'content'    => (string) $tag->content,
		);
	}
	return $fields;
}

/** @return array<string,mixed> */
function wpagent_cf7_config_errors( WPCF7_ContactForm $form ): array {
	if ( ! class_exists( 'WPCF7_ConfigValidator' ) || ! function_exists( 'wpcf7_validate_configuration' ) || ! wpcf7_validate_configuration() ) {
		return array();
	}
	$validator = new WPCF7_ConfigValidator( $form );
	$validator->validate();
	$errors = $validator->collect_error_messages( array( 'decodes_html_entities' => true ) );
	return is_array( $errors ) ? $errors : array();
}

/** @return mixed */
function wpagent_cf7_canonicalize( $value ) {
	if ( ! is_array( $value ) ) {
		return $value;
	}
	if ( ! array_is_list( $value ) ) {
		ksort( $value, SORT_STRING );
	}
	foreach ( $value as $key => $item ) {
		$value[ $key ] = wpagent_cf7_canonicalize( $item );
	}
	return $value;
}

/** @return array{title:string,locale:string,properties:array<string,mixed>} */
function wpagent_cf7_logical_state( WPCF7_ContactForm $form ): array {
	return array(
		'title'      => (string) $form->title(),
		'locale'     => (string) $form->locale(),
		'properties' => $form->get_properties(),
	);
}

function wpagent_cf7_state_hash( WPCF7_ContactForm $form ): string {
	$state = wpagent_cf7_canonicalize( wpagent_cf7_logical_state( $form ) );
	return hash( 'sha256', (string) wp_json_encode( $state, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) );
}

/** @param mixed $value */
function wpagent_cf7_string_map( $value ): array {
	$result = array();
	foreach ( is_array( $value ) ? $value : array() as $key => $item ) {
		if ( is_string( $key ) && is_scalar( $item ) ) {
			$result[ $key ] = (string) $item;
		}
	}
	return $result;
}

/** @return array{reply_to:string,advanced:bool} */
function wpagent_cf7_safe_reply_to( string $headers ): array {
	$reply_to = '';
	$advanced = false;
	$seen     = false;
	foreach ( preg_split( '/\r\n|\r|\n/', $headers ) ?: array() as $line ) {
		$line = trim( $line );
		if ( '' === $line ) {
			continue;
		}
		if ( preg_match( '/^Reply-To\s*:\s*(.+)$/i', $line, $matches ) && ! $seen ) {
			$reply_to = trim( $matches[1] );
			$seen     = true;
			continue;
		}
		$advanced = true;
	}
	return array( 'reply_to' => $reply_to, 'advanced' => $advanced );
}

/** @param mixed $value @return array<string,mixed> */
function wpagent_cf7_safe_mail_payload( $value, bool $primary ): array {
	$mail    = is_array( $value ) ? $value : array();
	$headers = wpagent_cf7_safe_reply_to( (string) ( $mail['additional_headers'] ?? '' ) );
	return array(
		'active'                   => $primary ? true : ! empty( $mail['active'] ),
		'subject'                  => (string) ( $mail['subject'] ?? '' ),
		'sender'                   => (string) ( $mail['sender'] ?? '' ),
		'recipient'                => (string) ( $mail['recipient'] ?? '' ),
		'body'                     => (string) ( $mail['body'] ?? '' ),
		'reply_to'                 => $headers['reply_to'],
		'exclude_blank'             => ! empty( $mail['exclude_blank'] ),
		'format'                    => ! empty( $mail['use_html'] ) ? 'html' : 'plain',
		'attachments_present'       => '' !== trim( (string) ( $mail['attachments'] ?? '' ) ),
		'advanced_headers_present'  => $headers['advanced'],
	);
}

/** @return array<string,mixed> */
function wpagent_cf7_form_payload( WPCF7_ContactForm $form ): array {
	$properties = $form->get_properties();
	return array(
		'id'                          => (int) $form->id(),
		'hash'                        => (string) $form->hash(),
		'state_hash'                  => wpagent_cf7_state_hash( $form ),
		'slug'                        => (string) $form->name(),
		'title'                       => (string) $form->title(),
		'locale'                      => (string) $form->locale(),
		'shortcode'                   => (string) $form->shortcode(),
		'form'                        => (string) ( $properties['form'] ?? '' ),
		'fields'                      => wpagent_cf7_fields( $form ),
		'mail'                        => wpagent_cf7_safe_mail_payload( $properties['mail'] ?? array(), true ),
		'mail_2'                      => wpagent_cf7_safe_mail_payload( $properties['mail_2'] ?? array(), false ),
		'messages'                    => wpagent_cf7_string_map( $properties['messages'] ?? array() ),
		'additional_settings_present' => '' !== trim( (string) ( $properties['additional_settings'] ?? '' ) ),
		'config_errors'               => wpagent_cf7_config_errors( $form ),
	);
}

/** @return array<string,mixed> */
function wpagent_cf7_safe_mail_output_schema(): array {
	return array(
		'type'                 => 'object',
		'additionalProperties' => false,
		'properties'           => array(
			'active' => array( 'type' => 'boolean' ), 'subject' => array( 'type' => 'string' ),
			'sender' => array( 'type' => 'string' ), 'recipient' => array( 'type' => 'string' ),
			'body' => array( 'type' => 'string' ), 'reply_to' => array( 'type' => 'string' ),
			'exclude_blank' => array( 'type' => 'boolean' ), 'format' => array( 'type' => 'string', 'enum' => array( 'plain', 'html' ) ),
			'attachments_present' => array( 'type' => 'boolean' ), 'advanced_headers_present' => array( 'type' => 'boolean' ),
		),
	);
}

/** @return array<string,mixed> */
function wpagent_cf7_form_output_schema(): array {
	return array(
		'type'       => 'object',
		'additionalProperties' => false,
		'properties' => array(
			'id'                  => array( 'type' => 'integer' ),
			'hash'                => array( 'type' => 'string' ),
			'state_hash'          => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			'slug'                => array( 'type' => 'string' ),
			'title'               => array( 'type' => 'string' ),
			'locale'              => array( 'type' => 'string' ),
			'shortcode'           => array( 'type' => 'string' ),
			'form'                => array( 'type' => 'string' ),
			'fields'              => array( 'type' => 'array', 'items' => array( 'type' => 'object' ) ),
			'mail'                => wpagent_cf7_safe_mail_output_schema(),
			'mail_2'              => wpagent_cf7_safe_mail_output_schema(),
			'messages'            => array( 'type' => 'object', 'additionalProperties' => array( 'type' => 'string' ) ),
			'additional_settings_present' => array( 'type' => 'boolean' ),
			'config_errors'       => array( 'type' => 'object' ),
		),
	);
}
