<?php
/**
 * WPBakery container classes for the Flip Container element.
 *
 * They extend WPBakery's TTA (Tabs/Tour/Accordion) classes so the editor shows
 * the exact "Toggle Container" chrome - a coloured header plus tabs - while
 * content() supplies our frontend 3D-flip markup.
 *
 * The two faces are LOCKED: controls_list is limited to 'edit' on the face, so
 * tabs can't be added, cloned or deleted. The container ships with exactly two
 * faces (Front / Back) via the element's default_content.
 *
 * Required only when WPBakery is active.
 *
 * @package CraftAddonsForWPBakery
 */

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

if ( ! class_exists( 'WPBakeryShortCodesContainer' ) ) {
	return;
}

if ( class_exists( 'VcShortcodeAutoloader' ) ) {
	VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Tta_Pageable' );
	VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Tta_Section' );
}

if ( ! class_exists( 'WPBakeryShortCode_Vc_Tta_Pageable' ) || ! class_exists( 'WPBakeryShortCode_Vc_Tta_Section' ) ) {
	return;
}

if ( ! class_exists( 'CAFW_Flip_Container_Shortcode' ) ) {

	/**
	 * The flip container - a locked two-tab (Front/Back) container.
	 */
	class CAFW_Flip_Container_Shortcode extends WPBakeryShortCode_Vc_Tta_Pageable {

		/**
		 * Editor controls for the container's own header bar.
		 *
		 * @var array
		 */
		protected $controls_list = array( 'edit', 'clone', 'copy', 'delete' );

		/**
		 * Frontend output (overrides the TTA template with our flip markup).
		 *
		 * @param array  $atts    Shortcode atts.
		 * @param string $content Nested face shortcodes.
		 * @return string
		 */
		public function content( $atts, $content = null ) {
			$atts = shortcode_atts(
				array(
					'direction'        => 'right',
					'trigger'          => 'hover',
					'speed'            => '0.6',
					'height'           => '300',
					'front_bg_type'    => '',
					'front_bg'         => '',
					'front_grad1'      => '',
					'front_grad2'      => '',
					'front_grad_angle' => '135',
					'front_image'      => '',
					'back_bg_type'     => '',
					'back_bg'          => '',
					'back_grad1'       => '',
					'back_grad2'       => '',
					'back_grad_angle'  => '135',
					'back_image'       => '',
					'el_id'            => '',
					'el_class'         => '',
					'css'              => '',
				),
				is_array( $atts ) ? $atts : array(),
				'cafw_flip_container'
			);

			// Direction: new right/left/up/down, mapping old horizontal/vertical for back-compat.
			$direction = in_array( $atts['direction'], array( 'right', 'left', 'up', 'down' ), true )
				? $atts['direction']
				: ( 'vertical' === $atts['direction'] ? 'up' : 'right' );
			$trigger   = 'click' === $atts['trigger'] ? 'click' : 'hover';
			$height    = absint( $atts['height'] );
			$height    = $height > 0 ? $height : 300;
			$speed     = (float) $atts['speed'];
			$speed     = $speed > 0 ? $speed : 0.6;
			$el_id     = CAFW_Element_Base::resolve_el_id( $atts );

			if ( 'click' === $trigger ) {
				wp_enqueue_script( 'cafw-flip' );
			}

			// In the WPBakery inline (frontend) editor the 3D flip can't be used,
			// so flatten both faces for editing via this class (see cafw-elements.css).
			$editor_class = function_exists( 'vc_is_inline' ) && vc_is_inline() ? 'cafw-flip--editor' : '';

			$classes = trim(
				preg_replace(
					'/\s+/',
					' ',
					sprintf(
						'cafw-flip cafw-flip--%1$s cafw-flip--%2$s %3$s %4$s %5$s',
						$direction,
						$trigger,
						$editor_class,
						CAFW_Element_Base::design_options_class( $atts ),
						$atts['el_class']
					)
				)
			);

			// Per-face background (set on the container so it's all in one panel).
			// Emitted as scoped CSS that targets the front and back face in BOTH the
			// frontend DOM (faces are direct children) and the inline editor (each
			// face is wrapped in .vc_cafw_flip_face).
			$front_bg = self::face_bg_value( $atts['front_bg_type'], $atts['front_bg'], $atts['front_grad1'], $atts['front_grad2'], $atts['front_grad_angle'], $atts['front_image'] );
			$back_bg  = self::face_bg_value( $atts['back_bg_type'], $atts['back_bg'], $atts['back_grad1'], $atts['back_grad2'], $atts['back_grad_angle'], $atts['back_image'] );
			$face_css = '';
			if ( '' !== $front_bg ) {
				$face_css .= '#' . $el_id . ' .cafw-flip__inner>.cafw-flip__face:first-of-type,'
					. '#' . $el_id . ' .cafw-flip__inner>.vc_cafw_flip_face:first-of-type .cafw-flip__face{' . $front_bg . '}';
			}
			if ( '' !== $back_bg ) {
				$face_css .= '#' . $el_id . ' .cafw-flip__inner>.cafw-flip__face:last-of-type,'
					. '#' . $el_id . ' .cafw-flip__inner>.vc_cafw_flip_face:last-of-type .cafw-flip__face{' . $back_bg . '}';
			}
			if ( '' !== $face_css ) {
				CAFW_Element_Base::add_inline_style( $face_css );
			}

			$inner_attrs = '';
			if ( 'click' === $trigger ) {
				$inner_attrs = ' tabindex="0" role="button" aria-label="' . esc_attr__( 'Flip card', 'craft-addons-for-wpbakery' ) . '"';
			}

			// Editor: use min-height so the card keeps a steady size when flipping
			// between sides (it grows if a side has more content). Frontend: fixed.
			$inner_dim = ( '' !== $editor_class ) ? 'min-height' : 'height';

			return '<div id="' . esc_attr( $el_id ) . '" class="' . esc_attr( $classes ) . '">'
				. '<div class="cafw-flip__inner" style="' . $inner_dim . ':' . esc_attr( $height ) . 'px;--cafw-flip-speed:' . esc_attr( $speed ) . 's"' . $inner_attrs . '>'
				. do_shortcode( (string) $content )
				. '</div></div>';
		}

		/**
		 * Build a face background declaration for the chosen type (color / gradient
		 * / image), or '' to keep the default.
		 *
		 * @param string $type  Background type: color | gradient | image | ''.
		 * @param string $color Solid colour (color type).
		 * @param string $grad1 Gradient start colour.
		 * @param string $grad2 Gradient end colour.
		 * @param string $angle Gradient angle in degrees.
		 * @param string $image Image attachment ID or URL.
		 * @return string CSS declaration(s), or '' when nothing usable is set.
		 */
		private static function face_bg_value( $type, $color, $grad1, $grad2, $angle, $image ) {
			if ( 'color' === $type ) {
				$c = sanitize_hex_color( $color );
				return $c ? 'background:' . $c . ';' : '';
			}

			if ( 'gradient' === $type ) {
				$c1 = sanitize_hex_color( $grad1 );
				$c2 = sanitize_hex_color( $grad2 );
				if ( $c1 && $c2 ) {
					return 'background:linear-gradient(' . (int) $angle . 'deg,' . $c1 . ',' . $c2 . ');';
				}
				return $c1 ? 'background:' . $c1 . ';' : '';
			}

			if ( 'image' === $type && '' !== $image ) {
				$url = is_numeric( $image ) ? wp_get_attachment_image_url( (int) $image, 'large' ) : esc_url_raw( $image );
				if ( $url ) {
					return 'background-image:url(' . esc_url( $url ) . ');background-size:cover;background-position:center;';
				}
			}

			return '';
		}
	}
}

if ( ! class_exists( 'CAFW_Flip_Face_Shortcode' ) ) {

	/**
	 * A single flip face (first = front, second = back via CSS nth-child).
	 *
	 * Locked to the 'edit' control only, so faces are fixed - no add / clone /
	 * delete.
	 */
	class CAFW_Flip_Face_Shortcode extends WPBakeryShortCode_Vc_Tta_Section {

		/**
		 * Only allow editing a face; never adding/cloning/deleting one.
		 *
		 * @var array
		 */
		protected $controls_list = array( 'edit' );

		/**
		 * Frontend output for a face.
		 *
		 * @param array  $atts    Shortcode atts.
		 * @param string $content Nested elements.
		 * @return string
		 */
		public function content( $atts, $content = null ) {
			$atts = shortcode_atts(
				array(
					'title'    => '',
					'el_id'    => '',
					'el_class' => '',
					'css'      => '',
				),
				is_array( $atts ) ? $atts : array(),
				'cafw_flip_face'
			);

			$el_id      = CAFW_Element_Base::resolve_el_id( $atts );
			$style_attr = '';

			$classes = trim(
				preg_replace(
					'/\s+/',
					' ',
					'cafw-flip__face ' . CAFW_Element_Base::design_options_class( $atts ) . ' ' . $atts['el_class']
				)
			);

			// In the inline editor, carry the face's title (Front / Back). It's
			// hidden via CSS and read by the Flip button as its current-side label.
			$label = '';
			if ( function_exists( 'vc_is_inline' ) && vc_is_inline() && '' !== $atts['title'] ) {
				$label = '<div class="cafw-flip__editor-label">' . esc_html( $atts['title'] ) . '</div>';
			}

			return '<div id="' . esc_attr( $el_id ) . '" class="' . esc_attr( $classes ) . '"' . $style_attr . '>'
				. $label
				. '<div class="cafw-flip__face-inner">'
				. do_shortcode( (string) $content )
				. '</div></div>';
		}
	}
}
