<?php
/**
 * Server-side validation for play save payloads.
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

final class PlayValidator {

	/**
	 * @param array<string, mixed> $data Sanitized play fields.
	 * @return true|\WP_Error
	 */
	public static function validate( array $data ) {
		$name = trim( (string) ( $data['name'] ?? '' ) );
		if ( '' === $name ) {
			return new \WP_Error( 'cartcue_play_name', __( 'Give this automation a name.', 'cartcue-sales-automation' ) );
		}

		$trigger_slug = (string) ( $data['trigger_slug'] ?? '' );
		if ( '' === $trigger_slug ) {
			return new \WP_Error( 'cartcue_play_trigger', __( 'Choose a trigger before saving.', 'cartcue-sales-automation' ) );
		}

		$actions = $data['actions'] ?? [];
		if ( ! is_array( $actions ) || empty( $actions ) ) {
			return new \WP_Error( 'cartcue_play_actions', __( 'Add at least one action before saving.', 'cartcue-sales-automation' ) );
		}

		foreach ( $actions as $action ) {
			if ( ! is_array( $action ) || empty( $action['type'] ) ) {
				return new \WP_Error( 'cartcue_play_action_type', __( 'Each action must have a type.', 'cartcue-sales-automation' ) );
			}
		}

		$sequence = is_array( $data['sequence'] ?? null ) ? $data['sequence'] : [];
		$branch_validation = self::validate_sequence_branches( $sequence );
		if ( is_wp_error( $branch_validation ) ) {
			return $branch_validation;
		}
		$indices  = self::action_indices_to_validate( $actions, $sequence );

		foreach ( $indices as $idx ) {
			if ( ! isset( $actions[ $idx ] ) || ! is_array( $actions[ $idx ] ) ) {
				return new \WP_Error(
					'cartcue_play_sequence_action',
					sprintf(
						/* translators: %d: 1-based step number in the sequence */
						__( 'Follow-up step %d is missing its action.', 'cartcue-sales-automation' ),
						self::step_label_for_index( $sequence, $idx )
					)
				);
			}

			$step_label = self::step_label_for_index( $sequence, (int) $idx );
			$error      = self::validate_message_action( $actions[ $idx ], $step_label );
			if ( is_wp_error( $error ) ) {
				return $error;
			}
		}

		return true;
	}

	/**
	 * @param array<int, array<string, mixed>> $actions
	 * @param array<int, array<string, mixed>> $sequence
	 * @return int[]
	 */
	private static function action_indices_to_validate( array $actions, array $sequence ): array {
		if ( ! empty( $sequence ) ) {
			$indices = [];
			foreach ( $sequence as $step ) {
				if ( ! is_array( $step ) ) {
					continue;
				}
				if ( 'branch' === ( $step['step_type'] ?? 'action' ) ) {
					continue;
				}
				$indices[] = (int) ( $step['action_index'] ?? 0 );
			}
			return array_values( array_unique( $indices ) );
		}

		$message_indices = [];
		foreach ( $actions as $i => $action ) {
			if ( ! is_array( $action ) ) {
				continue;
			}
			$type = (string) ( $action['type'] ?? '' );
			if ( in_array( $type, [ 'send_email', 'send_sms', 'send_whatsapp' ], true ) ) {
				$message_indices[] = (int) $i;
			}
		}

		if ( ! empty( $message_indices ) ) {
			return $message_indices;
		}

		return [ 0 ];
	}

	/**
	 * @param array<int, array<string, mixed>> $sequence
	 */
	private static function step_label_for_index( array $sequence, int $action_index ): int {
		if ( empty( $sequence ) ) {
			return 1;
		}
		foreach ( $sequence as $i => $step ) {
			if ( (int) ( $step['action_index'] ?? -1 ) === $action_index ) {
				return $i + 1;
			}
		}
		return $action_index + 1;
	}

	/**
	 * @param array<string, mixed> $action
	 * @return true|\WP_Error
	 */
	private static function validate_message_action( array $action, int $step_label ) {
		$type = (string) ( $action['type'] ?? '' );

		if ( 'send_email' === $type ) {
			$settings = is_array( $action['settings'] ?? null ) ? $action['settings'] : [];
			$subject  = trim( (string) ( $settings['subject'] ?? '' ) );
			if ( '' === $subject ) {
				return new \WP_Error(
					'cartcue_play_subject',
					self::step_message(
						$step_label,
						__( 'Add a subject line.', 'cartcue-sales-automation' )
					)
				);
			}

			$body = trim( (string) ( $settings['body'] ?? '' ) );
			if ( '' === $body ) {
				return new \WP_Error(
					'cartcue_play_body',
					self::step_message(
						$step_label,
						__( 'Add email content.', 'cartcue-sales-automation' )
					)
				);
			}

			$body_mode  = (string) ( $settings['body_mode'] ?? '' );
			$is_builder = 'builder' === $body_mode || EmailBlockRenderer::is_builder_content( $body );
			if ( $is_builder ) {
				$decoded = json_decode( $body, true );
				if ( ! is_array( $decoded ) ) {
					return new \WP_Error(
						'cartcue_play_body_json',
						self::step_message(
							$step_label,
							__( 'Email builder content is invalid.', 'cartcue-sales-automation' )
						)
					);
				}
				if ( empty( $decoded ) ) {
					return new \WP_Error(
						'cartcue_play_body_empty',
						self::step_message(
							$step_label,
							__( 'Add at least one block to your email.', 'cartcue-sales-automation' )
						)
					);
				}
			}

			return true;
		}

		if ( 'send_sms' === $type || 'send_whatsapp' === $type ) {
			$settings = is_array( $action['settings'] ?? null ) ? $action['settings'] : [];
			$message  = trim( (string) ( $settings['message'] ?? '' ) );
			if ( '' === $message ) {
				return new \WP_Error(
					'cartcue_play_message',
					self::step_message(
						$step_label,
						__( 'Add a message.', 'cartcue-sales-automation' )
					)
				);
			}
		}

		return true;
	}

	private static function step_message( int $step_label, string $detail ): string {
		/* translators: 1: step number, 2: detail */
		return sprintf( __( 'Message %1$d: %2$s', 'cartcue-sales-automation' ), $step_label, $detail );
	}

	/**
	 * @param array<int, array<string, mixed>> $sequence
	 * @return true|\WP_Error
	 */
	private static function validate_sequence_branches( array $sequence ) {
		foreach ( $sequence as $step_index => $step ) {
			if ( ! is_array( $step ) || 'branch' !== ( $step['step_type'] ?? 'action' ) ) {
				continue;
			}

			$step_label = $step_index + 1;
			$rules      = is_array( $step['rules'] ?? null ) ? $step['rules'] : [];
			if ( empty( $rules ) ) {
				return new \WP_Error(
					'cartcue_play_branch_rules',
					sprintf(
						/* translators: %d: 1-based branch step number */
						__( 'Branch step %d must include at least one condition.', 'cartcue-sales-automation' ),
						$step_label
					)
				);
			}

			$next_if_true  = max( 0, (int) ( $step['next_if_true'] ?? 0 ) );
			$next_if_false = max( 0, (int) ( $step['next_if_false'] ?? 0 ) );
			if ( $next_if_true === $next_if_false ) {
				return new \WP_Error(
					'cartcue_play_branch_else',
					sprintf(
						/* translators: %d: 1-based branch step number */
						__( 'Branch step %d must route If and Else to different steps.', 'cartcue-sales-automation' ),
						$step_label
					)
				);
			}
		}

		return true;
	}
}
