<?php
/**
 * Testimonials / Team widget render layer.
 *
 * Shortcode: [rsmspark_testimonials_team]
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Content_Widgets_Widget_Testimonials_Team
 */
class Rsmspark_Content_Widgets_Widget_Testimonials_Team {

	const REGISTRY_ID = 'testimonials_team';

	/**
	 * @return void
	 */
	public static function register() {
		Rsmspark_Content_Widgets_Shortcodes::add(
			Rsmspark_Content_Widgets_Registry::shortcode_tag( self::REGISTRY_ID ),
			array( __CLASS__, 'shortcode' ),
			self::REGISTRY_ID
		);

		Rsmspark_Content_Widgets_Blocks::add(
			'testimonials-team',
			array(
				'api_version'     => 3,
				'title'           => __( 'RSM Testimonials / Team', 'rsm-content-widgets' ),
				'description'     => __( 'Team or testimonial profiles with modal bios. Use manual entries or the admin testimonial library.', 'rsm-content-widgets' ),
				'category'        => Rsmspark_Content_Widgets_Blocks::BLOCK_CATEGORY,
				'icon'            => 'groups',
				'keywords'        => array( 'team', 'testimonials', 'rsm' ),
				'supports'        => array( 'html' => false ),
				'attributes'      => self::block_attributes(),
				'render_callback' => array( __CLASS__, 'render_block' ),
			)
		);
	}

	/**
	 * @return array<string, array<string, mixed>>
	 */
	public static function block_attributes() {
		return array(
			'title'                 => array( 'type' => 'string', 'default' => '' ),
			'layout'                => array( 'type' => 'string', 'default' => 'grid' ),
			'source'                => array( 'type' => 'string', 'default' => 'manual' ),
			'library_limit'         => array( 'type' => 'number', 'default' => 12 ),
			'library_orderby'       => array( 'type' => 'string', 'default' => 'date' ),
			'library_order'         => array( 'type' => 'string', 'default' => 'DESC' ),
			'show_submission_form'  => array( 'type' => 'boolean', 'default' => false ),
			'profiles'              => array( 'type' => 'array', 'default' => self::default_profiles() ),
		);
	}

	/**
	 * @return array<int, array<string, mixed>>
	 */
	public static function default_profiles() {
		return array(
			array(
				'photo' => 0,
				'name'  => __( 'Alex Morgan', 'rsm-content-widgets' ),
				'role'  => __( 'Product Lead', 'rsm-content-widgets' ),
				'quote' => __( 'RSM widgets made our launch pages effortless.', 'rsm-content-widgets' ),
				'bio'   => '',
			),
			array(
				'photo' => 0,
				'name'  => __( 'Jordan Lee', 'rsm-content-widgets' ),
				'role'  => __( 'Designer', 'rsm-content-widgets' ),
				'quote' => __( 'Clean defaults and flexible layouts out of the box.', 'rsm-content-widgets' ),
				'bio'   => '',
			),
		);
	}

	/**
	 * @param array<string, mixed> $atts Shortcode attributes.
	 * @param string               $content Inner content.
	 * @return string
	 */
	public static function shortcode( $atts, $content = '' ) {
		unset( $content );
		return self::render( self::prepare_template_vars( self::normalize_atts( is_array( $atts ) ? $atts : array() ) ) );
	}

	/**
	 * @param array<string, mixed> $attributes Block attributes.
	 * @return string
	 */
	public static function render_block( $attributes ) {
		return self::render( self::prepare_template_vars( self::normalize_atts( is_array( $attributes ) ? $attributes : array() ) ) );
	}

	/**
	 * @param array<string, mixed> $atts Raw attributes.
	 * @return array<string, mixed>
	 */
	public static function normalize_atts( array $atts ) {
		$defaults = array(
			'title'                => '',
			'layout'               => 'grid',
			'source'               => 'manual',
			'library_limit'        => 12,
			'library_orderby'      => 'date',
			'library_order'        => 'DESC',
			'show_submission_form' => false,
			'profiles'             => self::default_profiles(),
		);
		$parsed = Rsmspark_Content_Widgets_Render::parse_atts( $atts, $defaults, 'rsmspark_testimonials_team' );

		$layout = sanitize_key( (string) $parsed['layout'] );
		if ( ! in_array( $layout, array( 'grid', 'carousel' ), true ) ) {
			$layout = 'grid';
		}

		$source = sanitize_key( (string) $parsed['source'] );
		if ( ! in_array( $source, array( 'manual', 'library' ), true ) ) {
			$source = 'manual';
		}

		$library_orderby = sanitize_key( (string) $parsed['library_orderby'] );
		if ( ! in_array( $library_orderby, array( 'date', 'menu_order', 'title' ), true ) ) {
			$library_orderby = 'date';
		}

		$library_order = strtoupper( sanitize_key( (string) $parsed['library_order'] ) );
		if ( ! in_array( $library_order, array( 'ASC', 'DESC' ), true ) ) {
			$library_order = 'DESC';
		}

		$show_form = false;

		if ( 'library' === $source && class_exists( 'Rsmspark_Testimonials_Library', false ) ) {
			$profiles = Rsmspark_Testimonials_Library::profiles(
				array(
					'limit'   => absint( $parsed['library_limit'] ),
					'orderby' => $library_orderby,
					'order'   => $library_order,
				)
			);
		} else {
			$profiles = self::coerce_profiles( $parsed['profiles'] );
		}

		return array(
			'title'                => sanitize_text_field( (string) $parsed['title'] ),
			'layout'               => $layout,
			'source'               => $source,
			'library_limit'        => max( 1, min( 24, absint( $parsed['library_limit'] ) ) ),
			'library_orderby'      => $library_orderby,
			'library_order'        => $library_order,
			'show_submission_form' => $show_form,
			'profiles'             => $profiles,
		);
	}

	/**
	 * @param mixed $profiles Raw profiles from shortcode or block.
	 * @return array<int, array<string, mixed>>
	 */
	public static function coerce_profiles( $profiles ) {
		if ( is_string( $profiles ) && '' !== $profiles ) {
			$profiles = Rsmspark_Content_Widgets_Render::parse_json_attr( $profiles, self::default_profiles() );
		}
		if ( ! is_array( $profiles ) ) {
			$profiles = self::default_profiles();
		}

		$clean = self::sanitize_profiles( $profiles );
		if ( empty( $clean ) ) {
			$clean = self::sanitize_profiles( self::default_profiles() );
		}

		return $clean;
	}

	/**
	 * @param array<string, mixed> $content SiteOrigin content section.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_instance( array $content ) {
		$settings = isset( $content['settings'] ) && is_array( $content['settings'] ) ? $content['settings'] : array();
		$body     = isset( $content['content'] ) && is_array( $content['content'] ) ? $content['content'] : $content;
		$merged   = array_merge( $body, $settings );
		return self::normalize_atts( $merged );
	}

	/**
	 * @param array<string, mixed> $instance SiteOrigin widget instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_from_siteorigin_instance( array $instance ) {
		return self::prepare_from_instance(
			array(
				'content'  => Rsmspark_Content_Widgets_Render::section_instance( $instance, 'content' ),
				'settings' => Rsmspark_Content_Widgets_Render::section_instance( $instance, 'settings' ),
			)
		);
	}

	/**
	 * @param array<string, mixed> $attrs Block attributes.
	 * @return array<string, mixed>
	 */
	public static function instance_from_atts( array $attrs ) {
		$normalized = self::normalize_atts( $attrs );

		return array(
			'content' => array(
				'title'    => $normalized['title'],
				'layout'   => $normalized['layout'],
				'source'   => $normalized['source'],
				'profiles' => $normalized['profiles'],
			),
			'settings' => array(
				'library_limit'        => $normalized['library_limit'],
				'library_orderby'      => $normalized['library_orderby'],
				'library_order'        => $normalized['library_order'],
				'show_submission_form' => $normalized['show_submission_form'],
			),
		);
	}

	/**
	 * @param array<string, mixed> $instance SiteOrigin or import instance.
	 * @return array<string, mixed>
	 */
	public static function sanitize_instance( array $instance ) {
		unset( $instance['import_export'], $instance['panels_info'] );

		if ( isset( $instance['content'] ) || isset( $instance['settings'] ) ) {
			return self::instance_from_atts( self::prepare_from_siteorigin_instance( $instance ) );
		}

		return self::instance_from_atts( $instance );
	}

	/**
	 * @param array<int, mixed> $profiles Raw profiles.
	 * @return array<int, array<string, string>>
	 */
	public static function sanitize_profiles( array $profiles ) {
		$clean = array();
		foreach ( $profiles as $index => $profile ) {
			if ( ! is_array( $profile ) ) {
				continue;
			}
			if ( empty( $profile['name'] ) && empty( $profile['quote'] ) ) {
				continue;
			}
			$photo = $profile['photo'] ?? '';
			if ( is_numeric( $photo ) ) {
				$photo = Rsmspark_Content_Widgets_Render::media_url( $photo );
			} else {
				$photo = esc_url_raw( (string) $photo );
			}
			$clean[] = array(
				'id'    => 'profile-' . (int) $index,
				'photo' => $photo,
				'name'  => sanitize_text_field( (string) ( $profile['name'] ?? '' ) ),
				'role'  => sanitize_text_field( (string) ( $profile['role'] ?? '' ) ),
				'quote' => sanitize_textarea_field( (string) ( $profile['quote'] ?? '' ) ),
				'bio'   => wp_kses_post( (string) ( $profile['bio'] ?? '' ) ),
			);
		}
		return $clean;
	}

	/**
	 * @param array<string, mixed> $args Normalized args.
	 * @return array<string, mixed>
	 */
	public static function prepare_template_vars( array $args ) {
		return array(
			'title'                => $args['title'] ?? '',
			'layout'               => $args['layout'] ?? 'grid',
			'source'               => $args['source'] ?? 'manual',
			'show_submission_form' => ! empty( $args['show_submission_form'] ),
			'profiles'             => $args['profiles'] ?? array(),
			'widget_uid'           => 'rsmspark-cw-team-' . wp_unique_id(),
			'style_vars'           => Rsmspark_Content_Widgets_Render::inline_style_vars(),
		);
	}

	/**
	 * @param array<string, mixed> $vars Template variables.
	 * @return string
	 */
	public static function render( array $vars ) {
		if ( empty( $vars['profiles'] ) && empty( $vars['show_submission_form'] ) ) {
			return '';
		}

		return Rsmspark_Content_Widgets_Render::render_template( self::REGISTRY_ID, 'testimonials-team.php', $vars );
	}
}

function rsmspark_cw_render_testimonials_team( array $args ) {
	return Rsmspark_Content_Widgets_Widget_Testimonials_Team::render( Rsmspark_Content_Widgets_Widget_Testimonials_Team::prepare_template_vars( Rsmspark_Content_Widgets_Widget_Testimonials_Team::normalize_atts( $args ) ) );
}
