<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

/**
 * Wisewand API Payload Validator
 *
 * Validates API payload data before sending to Wisewand API.
 * Ensures all values conform to API requirements.
 *
 * @package Wisewand
 * @subpackage Utils
 * @since 2.4.2
 */

namespace Wisewand\Utils;

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

/**
 * Payload Validator Class
 *
 * @since 2.4.2
 */
class Wisewand_Payload_Validator {

	/**
	 * Allowed post statuses for internal links
	 *
	 * @var array
	 */
	private static $allowed_post_statuses = array( 'publish', 'draft', 'future' );

	/**
	 * Allowed publish modes
	 *
	 * @var array
	 */
	private static $allowed_publish_modes = array( 'draft', 'publish', 'scheduled', 'immediate' );

	/**
	 * Allowed content merge strategies
	 *
	 * @var array
	 */
	private static $allowed_merge_strategies = array( 'append', 'prepend', 'replace' );

	/**
	 * Allowed cannibalization actions
	 *
	 * @var array
	 */
	private static $allowed_cannibalization_actions = array( 'create', 'update', 'skip' );

	/**
	 * Validate entire payload data
	 *
	 * @param array $payload_data Payload data to validate.
	 * @return array|\WP_Error Validated payload or error.
	 */
	public static function validate_payload( $payload_data ) {
		if ( ! is_array( $payload_data ) ) {
			return new \WP_Error(
				'invalid_payload',
				__( 'Payload must be an array', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		$validated = array();

		// Validate internal_links_wp_status if present
		if ( isset( $payload_data['internal_links_wp_status'] ) ) {
			$result = self::validate_internal_links_wp_status( $payload_data['internal_links_wp_status'] );
			if ( is_wp_error( $result ) ) {
				return $result;
			}
			$validated['internal_links_wp_status'] = $result;
		}

		// Validate publish_mode if present
		if ( isset( $payload_data['publish_mode'] ) ) {
			$result = self::validate_publish_mode( $payload_data['publish_mode'] );
			if ( is_wp_error( $result ) ) {
				return $result;
			}
			$validated['publish_mode'] = $result;
		}

		// Validate content_merge_strategy if present
		if ( isset( $payload_data['content_merge_strategy'] ) ) {
			$result = self::validate_content_merge_strategy( $payload_data['content_merge_strategy'] );
			if ( is_wp_error( $result ) ) {
				return $result;
			}
			$validated['content_merge_strategy'] = $result;
		}

		// Validate cannibalization_action if present
		if ( isset( $payload_data['cannibalization_action'] ) ) {
			$result = self::validate_cannibalization_action( $payload_data['cannibalization_action'] );
			if ( is_wp_error( $result ) ) {
				return $result;
			}
			$validated['cannibalization_action'] = $result;
		}

		// Pass through other fields unchanged but sanitized
		foreach ( $payload_data as $key => $value ) {
			if ( ! isset( $validated[ $key ] ) ) {
				$validated[ $key ] = self::sanitize_payload_value( $key, $value );
			}
		}

		return $validated;
	}

	/**
	 * Validate internal_links_wp_status values
	 *
	 * @param mixed $value Value to validate.
	 * @return array|\WP_Error Valid array or error.
	 */
	public static function validate_internal_links_wp_status( $value ) {
		// Accept single string or array
		if ( is_string( $value ) ) {
			$value = array( $value );
		}

		if ( ! is_array( $value ) ) {
			return new \WP_Error(
				'invalid_internal_links_status',
				__( 'internal_links_wp_status must be an array or string', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		// Filter to allowed values
		$valid_statuses = array_intersect( $value, self::$allowed_post_statuses );

		if ( empty( $valid_statuses ) ) {
			return new \WP_Error(
				'invalid_internal_links_status',
				sprintf(
					/* translators: %s: Comma-separated list of allowed statuses */
					__( 'internal_links_wp_status contains no valid values. Allowed: %s', 'wisewand-ai-content-writer-seo-content-generator' ),
					implode( ', ', self::$allowed_post_statuses )
				)
			);
		}

		return array_values( $valid_statuses );
	}

	/**
	 * Validate publish_mode value
	 *
	 * @param mixed $value Value to validate.
	 * @return string|\WP_Error Valid mode or error.
	 */
	public static function validate_publish_mode( $value ) {
		if ( ! is_string( $value ) ) {
			return new \WP_Error(
				'invalid_publish_mode',
				__( 'publish_mode must be a string', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		if ( ! in_array( $value, self::$allowed_publish_modes, true ) ) {
			return new \WP_Error(
				'invalid_publish_mode',
				sprintf(
					/* translators: %s: Comma-separated list of allowed modes */
					__( 'Invalid publish_mode. Allowed: %s', 'wisewand-ai-content-writer-seo-content-generator' ),
					implode( ', ', self::$allowed_publish_modes )
				)
			);
		}

		return $value;
	}

	/**
	 * Validate content_merge_strategy value
	 *
	 * @param mixed $value Value to validate.
	 * @return string|\WP_Error Valid strategy or error.
	 */
	public static function validate_content_merge_strategy( $value ) {
		if ( ! is_string( $value ) ) {
			return new \WP_Error(
				'invalid_merge_strategy',
				__( 'content_merge_strategy must be a string', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		if ( ! in_array( $value, self::$allowed_merge_strategies, true ) ) {
			return new \WP_Error(
				'invalid_merge_strategy',
				sprintf(
					/* translators: %s: Comma-separated list of allowed strategies */
					__( 'Invalid content_merge_strategy. Allowed: %s', 'wisewand-ai-content-writer-seo-content-generator' ),
					implode( ', ', self::$allowed_merge_strategies )
				)
			);
		}

		return $value;
	}

	/**
	 * Validate cannibalization_action value
	 *
	 * @param mixed $value Value to validate.
	 * @return string|\WP_Error Valid action or error.
	 */
	public static function validate_cannibalization_action( $value ) {
		if ( ! is_string( $value ) ) {
			return new \WP_Error(
				'invalid_cannibalization_action',
				__( 'cannibalization_action must be a string', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		if ( ! in_array( $value, self::$allowed_cannibalization_actions, true ) ) {
			return new \WP_Error(
				'invalid_cannibalization_action',
				sprintf(
					/* translators: %s: Comma-separated list of allowed actions */
					__( 'Invalid cannibalization_action. Allowed: %s', 'wisewand-ai-content-writer-seo-content-generator' ),
					implode( ', ', self::$allowed_cannibalization_actions )
				)
			);
		}

		return $value;
	}

	/**
	 * Sanitize payload value based on key
	 *
	 * @param string $key   Field key.
	 * @param mixed  $value Field value.
	 * @return mixed Sanitized value.
	 */
	private static function sanitize_payload_value( $key, $value ) {
		// Handle arrays recursively
		if ( is_array( $value ) ) {
			return array_map(
				function ( $item ) use ( $key ) {
					return self::sanitize_payload_value( $key, $item );
				},
				$value
			);
		}

		// Handle different types
		if ( is_bool( $value ) ) {
			return $value;
		}

		if ( is_int( $value ) ) {
			return $value;
		}

		if ( is_float( $value ) ) {
			return $value;
		}

		// Default to text sanitization
		return sanitize_text_field( $value );
	}

	/**
	 * Get allowed values for a field
	 *
	 * @param string $field Field name.
	 * @return array|null Allowed values or null if field not recognized.
	 */
	public static function get_allowed_values( $field ) {
		$allowed = array(
			'internal_links_wp_status'    => self::$allowed_post_statuses,
			'publish_mode'                => self::$allowed_publish_modes,
			'content_merge_strategy'      => self::$allowed_merge_strategies,
			'cannibalization_action'      => self::$allowed_cannibalization_actions,
		);

		return isset( $allowed[ $field ] ) ? $allowed[ $field ] : null;
	}
}
