<?php
/**
 * Kit Transformer
 *
 * Custom transformer for Kit (formerly ConvertKit) integration
 * Handles pre-processing: create subscriber and apply tag before final form addition
 *
 * @package SureForms
 * @since 1.13.0
 */

namespace SRFM_Pro\Inc\Pro\Native_Integrations\Transformers;

use SRFM\Inc\Helper;
use SRFM_Pro\Inc\Pro\Database\Tables\Integrations;
use SRFM_Pro\Inc\Pro\Native_Integrations\Interfaces\Payload_Transformer;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Kit Transformer class.
 *
 * @since 1.13.0
 */
class Kit_Transformer implements Payload_Transformer {
	/**
	 * Integration name
	 *
	 * @var string
	 */
	private $integration_name = 'kit';

	/**
	 * Get integration name this transformer handles
	 *
	 * @return string Integration name.
	 * @since 1.13.0
	 */
	public function get_integration_name() {
		return $this->integration_name;
	}

	/**
	 * Transform payload for Kit integration
	 *
	 * Since only the "Create and Add Subscriber to Form" action uses provider: "kit",
	 * any call to this transformer means we need to do preprocessing:
	 * 1. Execute create subscriber API call
	 * 2. Execute add tag API call (if tag_id provided)
	 * 3. Return simplified payload for final "add to form" API call
	 *
	 * @param array $form_data Original form data.
	 * @param array $field_mappings Field mappings configuration.
	 * @param array $context Additional context data.
	 * @return array Transformed payload for final API call.
	 * @since 1.13.0
	 */
	public function transform( $form_data, $field_mappings = [], $context = [] ) {
		// The variables are not used anywhere further but are required in the interface.
		unset( $field_mappings );
		unset( $context );
		// Execute pre-processing steps (create subscriber + apply tag).
		$this->execute_preprocessing( $form_data );

		// Return simplified payload for final "Add to Form" API call.
		// Only include fields needed for the form addition endpoint.
		$final_payload = [
			'email_address' => $form_data['email_address'] ?? '',
		];

		if ( ! empty( $form_data['first_name'] ) ) {
			$final_payload['first_name'] = $form_data['first_name'];
		}

		return $final_payload;
	}

	/**
	 * Prepare test payload with sample data
	 *
	 * @param array $workflow_fields Fields from the workflow configuration.
	 * @param array $field_definitions Field definitions from the action configuration.
	 * @return array Test payload.
	 * @since 1.13.0
	 */
	public function prepare_test_payload( $workflow_fields, $field_definitions ) {
		$payload = [];

		// Generate test payload.
		foreach ( $field_definitions as $field_def ) {
			$field_key = $field_def['key'] ?? '';

			if ( empty( $field_key ) ) {
				continue;
			}

			// Skip fields that are excluded from payload.
			$exclude_from_payload = $field_def['exclude_from_payload'] ?? false;
			if ( $exclude_from_payload ) {
				continue;
			}

			// Get field value or generate test data.
			if ( isset( $workflow_fields[ $field_key ] ) && ! empty( $workflow_fields[ $field_key ] ) ) {
				$payload[ $field_key ] = $workflow_fields[ $field_key ];
			} else {
				$payload[ $field_key ] = $this->generate_test_value( $field_def );
			}
		}

		// Handle custom fields - move to nested 'fields' object.
		$custom_fields = [];
		foreach ( $payload as $key => $value ) {
			if ( ! in_array( $key, [ 'email_address', 'first_name', 'form_id', 'tag_id' ], true ) ) {
				$custom_fields[ $key ] = $value;
				unset( $payload[ $key ] );
			}
		}

		if ( ! empty( $custom_fields ) ) {
			$payload['fields'] = $custom_fields;
		}

		return $payload;
	}

	/**
	 * Execute preprocessing steps (create subscriber and add tag)
	 *
	 * @param array $form_data Form data.
	 * @return void
	 * @since 1.13.0
	 */
	private function execute_preprocessing( $form_data ) {
		$credentials = $this->get_integration_credentials();

		if ( ! $credentials ) {
			return;
		}

		try {
			// Step 1: Create/update subscriber.
			$subscriber_result = $this->create_subscriber( $form_data, $credentials );

			if ( ! $subscriber_result['success'] ) {
				return;
			}

			// Step 2: Apply tag if provided.
			$tag_id = $form_data['tag_id'] ?? '';
			if ( ! empty( $tag_id ) ) {
				$this->apply_tag_to_subscriber( $form_data['email_address'], $tag_id, $credentials );
			}
		} catch ( \Exception $e ) {
			return;
		}
	}

	/**
	 * Create or update subscriber in Kit
	 *
	 * @param array $form_data Form data (already transformed with custom fields in 'fields' object).
	 * @param array $credentials Integration credentials.
	 * @return array API response.
	 * @since 1.13.0
	 */
	private function create_subscriber( $form_data, $credentials ) {
		$encoded_data = wp_json_encode( $form_data );
		$args         = [
			'method'  => 'POST',
			'headers' => [
				'Content-Type'  => 'application/json',
				'X-Kit-Api-Key' => $credentials['api_key'] ?? '',
				'Accept'        => 'application/json',
				'User-Agent'    => 'SureForms Pro/' . SRFM_PRO_VER,
			],
			'body'    => $encoded_data ? $encoded_data : '',
			'timeout' => 30,
		];

		$response = wp_remote_post( 'https://api.kit.com/v4/subscribers', $args );

		return $this->process_api_response( $response, 'subscriber creation' );
	}

	/**
	 * Apply tag to subscriber
	 *
	 * @param string $email_address Subscriber email.
	 * @param string $tag_id Tag ID.
	 * @param array  $credentials Integration credentials.
	 * @return array API response.
	 * @since 1.13.0
	 */
	private function apply_tag_to_subscriber( $email_address, $tag_id, $credentials ) {
		$payload = wp_json_encode(
			[
				'email_address' => Helper::get_string_value( $email_address ),
			]
		);

		$args = [
			'method'  => 'POST',
			'headers' => [
				'Content-Type'  => 'application/json',
				'X-Kit-Api-Key' => $credentials['api_key'] ?? '',
				'Accept'        => 'application/json',
				'User-Agent'    => 'SureForms Pro/' . SRFM_PRO_VER,
			],
			'body'    => $payload ? $payload : '',
			'timeout' => 30,
		];

		$url      = "https://api.kit.com/v4/tags/{$tag_id}/subscribers";
		$response = wp_remote_post( $url, $args );

		return $this->process_api_response( $response, 'tag application' );
	}

	/**
	 * Process API response
	 *
	 * @param array|\WP_Error $response API response.
	 * @param string          $operation Operation name for error messages.
	 * @return array Processed response.
	 * @since 1.13.0
	 */
	private function process_api_response( $response, $operation ) {
		if ( is_wp_error( $response ) ) {
			return [
				'success' => false,
				'message' => sprintf(
					/* translators: %1$s: operation name, %2$s: error message */
					__( 'Kit %1$s failed: %2$s', 'sureforms-pro' ),
					$operation,
					$response->get_error_message()
				),
			];
		}

		$status_code   = wp_remote_retrieve_response_code( $response );
		$response_body = wp_remote_retrieve_body( $response );
		$response_data = json_decode( $response_body, true );

		if ( $status_code >= 200 && $status_code < 300 ) {
			return [
				'success' => true,
				'message' => sprintf(
					/* translators: %s: operation name */
					__( 'Kit %s completed successfully.', 'sureforms-pro' ),
					$operation
				),
				'data'    => $response_data,
			];
		}

		// Handle error response.
		$error_message = '';
		if ( is_array( $response_data ) ) {
			$error_message = $response_data['message'] ?? $response_data['error'] ?? '';
		}

		if ( empty( $error_message ) ) {
			$error_message = sprintf(
				/* translators: %d: HTTP status code */
				__( 'HTTP %d error', 'sureforms-pro' ),
				$status_code
			);
		}

		return [
			'success' => false,
			'message' => sprintf(
				/* translators: %1$s: operation name, %2$s: error message */
				__( 'Kit %1$s failed: %2$s', 'sureforms-pro' ),
				$operation,
				$error_message
			),
			'data'    => $response_data,
		];
	}

	/**
	 * Get Kit integration credentials
	 *
	 * @return array|false Credentials array or false if not found.
	 * @since 1.13.0
	 */
	private function get_integration_credentials() {
		$integration_data = Integrations::get_by_type( $this->integration_name );

		if ( empty( $integration_data ) || empty( $integration_data['data'] ) ) {
			return false;
		}

		return Integrations::decrypt_sensitive_data( Helper::get_array_value( $integration_data['data'] ) );
	}

	/**
	 * Generate test value for field definition
	 *
	 * @param array $field_def Field definition.
	 * @return mixed Test value.
	 * @since 1.13.0
	 */
	private function generate_test_value( $field_def ) {
		$field_type = $field_def['type'] ?? 'text';
		$field_key  = $field_def['key'] ?? '';

		// Special handling for email fields.
		if ( false !== strpos( $field_key, 'email' ) || 'email' === $field_type ) {
			return 'noreply@sureforms.com';
		}

		// Special handling for name fields.
		if ( false !== strpos( $field_key, 'name' ) ) {
			return 'Test User';
		}

		switch ( $field_type ) {
			case 'email':
				return 'noreply@sureforms.com';

			case 'number':
				return 123;

			case 'textarea':
				return 'This is a test Kit integration from SureForms.';

			case 'text':
			default:
				return 'Test Value';
		}
	}
}
