<?php
/**
 * Team Member Card element.
 *
 * A single person card - photo, name, role, short bio and social links - in
 * three arrangements (classic image-on-top, image-left, and an overlay where
 * the social icons reveal over the photo on hover). Best-of from the
 * competitors: image shapes, image hover effects (zoom / grayscale), social
 * icons, full typography and card styling. Drop several into a row of columns
 * to build a team grid.
 *
 * @package CraftAddonsForWPBakery
 */

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

/**
 * Class CAFW_Element_Team_Member
 */
class CAFW_Element_Team_Member extends CAFW_Element_Base {

	/**
	 * {@inheritDoc}
	 */
	public function get_shortcode_tag() {
		return 'cafw_team_member';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_label() {
		return esc_html__( 'Team Member', 'craft-addons-for-wpbakery' );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_description() {
		return esc_html__( 'A photo, name, role and socials.', 'craft-addons-for-wpbakery' );
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_admin_icon() {
		return 'dashicons-id';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_editor_icon() {
		return 'cafw-vc-icon cafw-vc-icon-team-member';
	}

	/**
	 * {@inheritDoc}
	 */
	protected function get_defaults() {
		return array(
			'image'             => '',
			'name'              => esc_html__( 'Jane Doe', 'craft-addons-for-wpbakery' ),
			'role'              => esc_html__( 'Co-Founder & CEO', 'craft-addons-for-wpbakery' ),
			'bio'               => esc_html__( 'A short bio about this team member and what they do best.', 'craft-addons-for-wpbakery' ),
			'socials'           => $this->default_socials(),
			'layout'            => 'classic',
			'img_shape'         => 'circle',
			'align'             => 'center',
			'img_size'          => '150',
			'img_hover'         => 'zoom',
			'name_hover_color'  => '',
			'role_color'        => '#502bf8',
			'social_color'      => '#64748b',
			'social_bg'         => '',
			'social_size'       => '16',
			'social_hover'      => '#502bf8',
			'card_padding'      => '28',
			'card_shadow'       => 'soft',
			'card_hover'        => 'lift',
			'name_font'         => '',
			'name_google_font'  => '',
			'role_font'         => '',
			'role_google_font'  => '',
			'bio_font'          => '',
			'bio_google_font'   => '',
		);
	}

	/**
	 * Default social rows.
	 *
	 * @return string URL-encoded JSON for the param_group field.
	 */
	private function default_socials() {
		$rows = array(
			array(
				'icon' => 'fa fa-brands fa-x-twitter',
				'url'  => '#',
			),
			array(
				'icon' => 'fa fa-brands fa-linkedin-in',
				'url'  => '#',
			),
			array(
				'icon' => 'fa fa-brands fa-dribbble',
				'url'  => '#',
			),
		);
		return rawurlencode( wp_json_encode( $rows ) );
	}

	/**
	 * Wireframe thumbnail for a layout option.
	 *
	 * @param string $type Layout key.
	 * @return string Inline SVG.
	 */
	private function layout_thumb( $type ) {
		$img = '#c9c6d6'; // photo / avatar.
		$t   = '#bcb9cc'; // name line.
		$x   = '#d8d5e4'; // role line.
		if ( 'horizontal' === $type ) {
			// Avatar left, name + role to the right.
			$inner = '<circle cx="14" cy="21" r="9" fill="' . $img . '"/>'
				. '<rect x="28" y="16" width="26" height="3.5" rx="1.75" fill="' . $t . '"/>'
				. '<rect x="28" y="23" width="18" height="3" rx="1.5" fill="' . $x . '"/>';
		} elseif ( 'overlay' === $type ) {
			// A photo with social icons revealing over it, name + role below.
			$inner = '<rect x="15" y="4" width="30" height="20" rx="3" fill="' . $img . '"/>'
				. '<rect x="15" y="4" width="30" height="20" rx="3" fill="#2e2150" opacity="0.4"/>'
				. '<circle cx="24" cy="14" r="2.7" fill="#fff"/><circle cx="30" cy="14" r="2.7" fill="#fff"/><circle cx="36" cy="14" r="2.7" fill="#fff"/>'
				. '<rect x="18" y="30" width="24" height="3.5" rx="1.75" fill="' . $t . '"/>'
				. '<rect x="22" y="37" width="16" height="3" rx="1.5" fill="' . $x . '"/>';
		} else { // classic.
			// Avatar on top, name + role below, centred.
			$inner = '<circle cx="30" cy="12" r="9" fill="' . $img . '"/>'
				. '<rect x="18" y="26" width="24" height="3.5" rx="1.75" fill="' . $t . '"/>'
				. '<rect x="22" y="33" width="16" height="3" rx="1.5" fill="' . $x . '"/>';
		}
		return '<svg viewBox="0 0 60 42" width="60" height="42" xmlns="http://www.w3.org/2000/svg">'
			. '<rect width="60" height="42" rx="4" fill="#f6f5fb"/>' . $inner . '</svg>';
	}

	/**
	 * {@inheritDoc}
	 */
	public function get_params() {
		$styles = esc_html__( 'Styles', 'craft-addons-for-wpbakery' );

		return array_merge(
			array(
				array(
					'type'       => 'cafw_layout',
					'heading'    => esc_html__( 'Layout', 'craft-addons-for-wpbakery' ),
					'param_name' => 'layout',
					'std'        => 'classic',
					'options'    => array(
						'classic'    => array(
							'label' => esc_html__( 'Classic (image on top)', 'craft-addons-for-wpbakery' ),
							'thumb' => $this->layout_thumb( 'classic' ),
						),
						'horizontal' => array(
							'label' => esc_html__( 'Image left', 'craft-addons-for-wpbakery' ),
							'thumb' => $this->layout_thumb( 'horizontal' ),
						),
						'overlay'    => array(
							'label' => esc_html__( 'Overlay (socials on hover)', 'craft-addons-for-wpbakery' ),
							'thumb' => $this->layout_thumb( 'overlay' ),
						),
					),
				),
				array(
					'type'       => 'attach_image',
					'heading'    => esc_html__( 'Photo', 'craft-addons-for-wpbakery' ),
					'param_name' => 'image',
				),
				array(
					'type'        => 'textfield',
					'heading'     => esc_html__( 'Name', 'craft-addons-for-wpbakery' ),
					'param_name'  => 'name',
					'value'       => esc_html__( 'Jane Doe', 'craft-addons-for-wpbakery' ),
					'admin_label' => true,
				),
				array(
					'type'       => 'textfield',
					'heading'    => esc_html__( 'Role', 'craft-addons-for-wpbakery' ),
					'param_name' => 'role',
					'value'      => esc_html__( 'Co-Founder & CEO', 'craft-addons-for-wpbakery' ),
				),
				array(
					'type'       => 'textarea',
					'heading'    => esc_html__( 'Bio', 'craft-addons-for-wpbakery' ),
					'param_name' => 'bio',
					'value'      => esc_html__( 'A short bio about this team member and what they do best.', 'craft-addons-for-wpbakery' ),
				),
				array(
					'type'        => 'param_group',
					'heading'     => esc_html__( 'Social links', 'craft-addons-for-wpbakery' ),
					'param_name'  => 'socials',
					'value'       => $this->default_socials(),
					'params'      => array(
						array(
							'type'       => 'iconpicker',
							'heading'    => esc_html__( 'Icon', 'craft-addons-for-wpbakery' ),
							'param_name' => 'icon',
							'value'      => 'fa fa-brands fa-x-twitter',
							'settings'   => array(
								'emptyIcon'    => true,
								'type'         => 'fontawesome',
								'iconsPerPage' => 200,
							),
						),
						array(
							'type'        => 'textfield',
							'heading'     => esc_html__( 'URL', 'craft-addons-for-wpbakery' ),
							'param_name'  => 'url',
							'admin_label' => true,
						),
					),
				),
				array(
					'type'             => 'dropdown',
					'heading'          => esc_html__( 'Image shape', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'img_shape',
					'value'            => array(
						esc_html__( 'Circle', 'craft-addons-for-wpbakery' )  => 'circle',
						esc_html__( 'Rounded', 'craft-addons-for-wpbakery' ) => 'rounded',
						esc_html__( 'Square', 'craft-addons-for-wpbakery' )  => 'square',
					),
					'std'              => 'circle',
					'description'      => esc_html__( 'Used by the Classic and Image-left layouts.', 'craft-addons-for-wpbakery' ),
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				array(
					'type'             => 'dropdown',
					'heading'          => esc_html__( 'Alignment', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'align',
					'value'            => array(
						esc_html__( 'Center', 'craft-addons-for-wpbakery' ) => 'center',
						esc_html__( 'Left', 'craft-addons-for-wpbakery' )   => 'left',
						esc_html__( 'Right', 'craft-addons-for-wpbakery' )  => 'right',
					),
					'std'              => 'center',
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				// ---- Styles: image ----
				array(
					'type'             => 'textfield',
					'heading'          => esc_html__( 'Image size (px)', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'img_size',
					'value'            => '150',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				array(
					'type'             => 'dropdown',
					'heading'          => esc_html__( 'Image hover', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'img_hover',
					'value'            => array(
						esc_html__( 'Zoom', 'craft-addons-for-wpbakery' )      => 'zoom',
						esc_html__( 'Grayscale', 'craft-addons-for-wpbakery' ) => 'grayscale',
						esc_html__( 'None', 'craft-addons-for-wpbakery' )      => 'none',
					),
					'std'              => 'zoom',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				// ---- Styles: social + role colours ----
				array(
					'type'             => 'colorpicker',
					'heading'          => esc_html__( 'Role color', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'role_color',
					'value'            => '#502bf8',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column cafw-bg-sep',
				),
				array(
					'type'             => 'colorpicker',
					'heading'          => esc_html__( 'Name color (hover)', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'name_hover_color',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column cafw-bg-sep',
				),
				array(
					'type'             => 'colorpicker',
					'heading'          => esc_html__( 'Social icon color', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'social_color',
					'value'            => '#64748b',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-4 vc_column',
				),
				array(
					'type'             => 'colorpicker',
					'heading'          => esc_html__( 'Social background', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'social_bg',
					'description'      => esc_html__( 'Optional - gives each icon a chip.', 'craft-addons-for-wpbakery' ),
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-4 vc_column',
				),
				array(
					'type'             => 'colorpicker',
					'heading'          => esc_html__( 'Social color (hover)', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'social_hover',
					'value'            => '#502bf8',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-4 vc_column',
				),
				array(
					'type'             => 'textfield',
					'heading'          => esc_html__( 'Social icon size (px)', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'social_size',
					'value'            => '16',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				// ---- Styles: card (background / border / radius live in Design Options) ----
				array(
					'type'             => 'dropdown',
					'heading'          => esc_html__( 'Card shadow', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'card_shadow',
					'value'            => array(
						esc_html__( 'Soft', 'craft-addons-for-wpbakery' )   => 'soft',
						esc_html__( 'Strong', 'craft-addons-for-wpbakery' ) => 'strong',
						esc_html__( 'None', 'craft-addons-for-wpbakery' )   => 'none',
					),
					'std'              => 'soft',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column cafw-bg-sep',
				),
				array(
					'type'             => 'textfield',
					'heading'          => esc_html__( 'Card padding (px)', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'card_padding',
					'value'            => '28',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
				array(
					'type'             => 'dropdown',
					'heading'          => esc_html__( 'Card hover', 'craft-addons-for-wpbakery' ),
					'param_name'       => 'card_hover',
					'value'            => array(
						esc_html__( 'Lift', 'craft-addons-for-wpbakery' )          => 'lift',
						esc_html__( 'Lift + shadow', 'craft-addons-for-wpbakery' ) => 'shadow',
						esc_html__( 'None', 'craft-addons-for-wpbakery' )          => 'none',
					),
					'std'              => 'lift',
					'group'            => $styles,
					'edit_field_class' => 'vc_col-sm-6 vc_column',
				),
			),
			$this->typography_params(
				'name',
				esc_html__( 'Name', 'craft-addons-for-wpbakery' ),
				array(
					'tag' => true,
					'sep' => true,
				)
			),
			$this->typography_params( 'role', esc_html__( 'Role', 'craft-addons-for-wpbakery' ), array( 'sep' => true ) ),
			$this->typography_params( 'bio', esc_html__( 'Bio', 'craft-addons-for-wpbakery' ), array( 'sep' => true ) )
		);
	}

	/**
	 * Append "px" to a numeric value, or '' when blank / non-numeric.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	private function px( $value ) {
		$value = trim( (string) $value );
		if ( '' === $value || ! is_numeric( $value ) ) {
			return '';
		}
		return absint( $value ) . 'px';
	}

	/**
	 * Build the row of social-link icons.
	 *
	 * @param array $atts Shortcode atts.
	 * @return string
	 */
	private function socials_html( $atts ) {
		if ( empty( $atts['socials'] ) || ! function_exists( 'vc_param_group_parse_atts' ) ) {
			return '';
		}
		$rows = vc_param_group_parse_atts( $atts['socials'] );
		if ( empty( $rows ) || ! is_array( $rows ) ) {
			return '';
		}

		$enqueued = false;
		$out      = '';
		foreach ( $rows as $row ) {
			$icon = isset( $row['icon'] ) ? trim( (string) $row['icon'] ) : '';
			$url  = isset( $row['url'] ) ? trim( (string) $row['url'] ) : '';
			if ( '' === $icon ) {
				continue;
			}
			if ( ! $enqueued && function_exists( 'vc_icon_element_fonts_enqueue' ) ) {
				vc_icon_element_fonts_enqueue( 'fontawesome' );
				$enqueued = true;
			}
			$href = ( '' !== $url ) ? esc_url( $url ) : '#';
			$out .= '<a class="cafw-team__social" href="' . $href . '" target="_blank" rel="noopener noreferrer">'
				. '<span class="' . esc_attr( $icon ) . '"></span></a>';
		}

		return ( '' !== $out ) ? '<div class="cafw-team__socials">' . $out . '</div>' : '';
	}

	/**
	 * {@inheritDoc}
	 */
	public function render( $atts, $content, $el_id ) {
		$layout = in_array( $atts['layout'], array( 'classic', 'horizontal', 'overlay' ), true ) ? $atts['layout'] : 'classic';
		$shape  = in_array( $atts['img_shape'], array( 'circle', 'rounded', 'square' ), true ) ? $atts['img_shape'] : 'circle';
		$align  = in_array( $atts['align'], array( 'center', 'left', 'right' ), true ) ? $atts['align'] : 'center';
		$ihover = in_array( $atts['img_hover'], array( 'zoom', 'grayscale', 'none' ), true ) ? $atts['img_hover'] : 'none';
		$shadow = in_array( $atts['card_shadow'], array( 'soft', 'strong', 'none' ), true ) ? $atts['card_shadow'] : 'soft';
		$chover = in_array( $atts['card_hover'], array( 'lift', 'shadow', 'none' ), true ) ? $atts['card_hover'] : 'none';

		$has_image = absint( $atts['image'] ) > 0;
		$name      = (string) $atts['name'];
		$role      = (string) $atts['role'];
		$bio       = (string) $atts['bio'];
		if ( ! $has_image && '' === trim( $name ) && '' === trim( $role ) && '' === trim( $bio ) ) {
			return '';
		}

		// CSS custom properties. Background / border / radius live in the Design
		// Options tab; the CSS falls back to the card's default look.
		$vars = array(
			'--cafw-tm-img'      => $this->px( $atts['img_size'] ),
			'--cafw-tm-role'     => sanitize_hex_color( $atts['role_color'] ),
			'--cafw-tm-soc'      => sanitize_hex_color( $atts['social_color'] ),
			'--cafw-tm-soc-size' => $this->px( $atts['social_size'] ),
			'--cafw-tm-soc-hov'  => sanitize_hex_color( $atts['social_hover'] ),
			'--cafw-tm-pad'      => $this->px( $atts['card_padding'] ),
		);
		$soc_bg = sanitize_hex_color( $atts['social_bg'] );
		if ( $soc_bg ) {
			$vars['--cafw-tm-soc-bg'] = $soc_bg;
		}
		$vars = array_filter(
			$vars,
			static function ( $v ) {
				return '' !== $v && null !== $v;
			}
		);

		// Hover colour for the name, scoped to this instance.
		$nhc = sanitize_hex_color( $atts['name_hover_color'] );
		if ( $nhc ) {
			CAFW_Element_Base::add_inline_style(
				'#' . $el_id . ':hover .cafw-team__name{color:' . $nhc . '!important}'
			);
		}

		$name_type = $this->part_typography( $atts, 'name' );
		$role_type = $this->part_typography( $atts, 'role' );
		$bio_type  = $this->part_typography( $atts, 'bio' );
		$name_tag  = in_array( $name_type['tag'], array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div' ), true ) ? $name_type['tag'] : 'h3';

		$classes = array(
			'cafw-team',
			'cafw-team--' . $layout,
			'cafw-team--shape-' . $shape,
			'cafw-team--align-' . $align,
			'cafw-team--ihover-' . $ihover,
			'cafw-team--shadow-' . $shadow,
		);
		if ( 'none' !== $chover ) {
			$classes[] = 'cafw-team--hover-' . $chover;
		}
		$dclass = CAFW_Element_Base::design_options_class( $atts );
		if ( $dclass ) {
			$classes[] = $dclass;
		}
		if ( '' !== trim( (string) $atts['el_class'] ) ) {
			$classes[] = $atts['el_class'];
		}

		$socials = $this->socials_html( $atts );

		// Photo (real image or a placeholder while none is set).
		if ( $has_image ) {
			$img = wp_get_attachment_image( absint( $atts['image'] ), 'large', false, array( 'class' => 'cafw-team__img' ) );
		} else {
			$img = '<span class="cafw-team__img cafw-team__img--placeholder" aria-hidden="true">'
				. '<svg viewBox="0 0 24 24" width="40" height="40" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm0 2c-4.42 0-8 2.5-8 5.5V22h16v-2.5c0-3-3.58-5.5-8-5.5Z"/></svg>'
				. '</span>';
		}

		ob_start();
		?>
		<div id="<?php echo esc_attr( $el_id ); ?>" class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"<?php echo $this->style_attr( $vars ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>>
			<div class="cafw-team__media">
				<?php echo $img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_get_attachment_image / static SVG. ?>
				<?php if ( 'overlay' === $layout && '' !== $socials ) : ?>
					<div class="cafw-team__overlay"><?php echo $socials; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built from escaped parts. ?></div>
				<?php endif; ?>
			</div>
			<div class="cafw-team__body">
				<?php if ( '' !== trim( $name ) ) : ?>
					<<?php echo esc_attr( $name_tag ); ?> class="cafw-team__name"<?php echo $this->style_attr( $name_type['styles'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>><?php echo esc_html( $name ); ?></<?php echo esc_attr( $name_tag ); ?>>
				<?php endif; ?>
				<?php if ( '' !== trim( $role ) ) : ?>
					<div class="cafw-team__role"<?php echo $this->style_attr( $role_type['styles'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>><?php echo esc_html( $role ); ?></div>
				<?php endif; ?>
				<?php if ( '' !== trim( $bio ) ) : ?>
					<div class="cafw-team__bio"<?php echo $this->style_attr( $bio_type['styles'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- style_attr escapes internally. ?>><?php echo wp_kses_post( wpautop( $bio ) ); ?></div>
				<?php endif; ?>
				<?php
				if ( 'overlay' !== $layout ) {
					echo $socials; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built from escaped parts.
				}
				?>
			</div>
		</div>
		<?php
		return ob_get_clean();
	}
}
