<?php
/**
 * Countdown element.
 *
 * @package BricksExtras
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Countdown element class.
 */
class X_Countdown extends \Bricks\Element {
	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';

	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xcountdown';

	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-time';

	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '.x-countdown_item';

	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xCountdown' );

	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Pro Countdown', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'evergreen', 'countdown', 'timer' );
	}

	/**
	 * Enqueue scripts.
	 */
	public function enqueue_scripts() {

		if ( bricks_is_builder_main() ) {
			return;
		}

		wp_enqueue_script( 'x-countdown', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'countdown' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );
		if ( ! \BricksExtras\Helpers::element_css_added( $this->name ) ) {
			wp_enqueue_style( 'x-countdown', BRICKSEXTRAS_URL . 'components/assets/css/countdown.css', array(), \BricksExtras\Plugin::VERSION );
		}
	}

	/**
	 * Set control groups.
	 */
	public function set_control_groups() {

		$this->control_groups['itemsGroup'] = array(
			'title' => esc_html__( 'Items', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['seperatorsGroup'] = array(
			'title' => esc_html__( 'Separator', 'bricks' ),
			'tab'   => 'content',
		);
	}

	/**
	 * Set element controls.
	 */
	public function set_controls() {

		$this->controls['mode'] = array(
			'label'       => esc_html__( 'Type', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'fixed'     => esc_html__( 'Fixed', 'bricks' ),
				'evergreen' => esc_html__( 'Evergreen', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'Evergreen', 'bricksextras' ),
			'inline'      => true,
			'rerender'    => true,
		);

		$now          = current_time( 'mysql' );
		$time_default = date( 'Y-m-d H:i:s', strtotime( $now ) + 7200 );

		$this->controls['date'] = array(
			'label'    => esc_html__( 'Date & time', 'bricks' ) . ' (' . esc_html__( 'End', 'bricks' ) . ')',
			'type'     => 'text',
			'required' => array( 'mode', '=', 'fixed' ),
			'inline'   => true,
			'default'  => $time_default,
		);

		$timezones = array(
			'UTC-12:00' => 'UTC-12:00',
			'UTC-11:00' => 'UTC-11:00',
			'UTC-10:00' => 'UTC-10:00',
			'UTC-09:30' => 'UTC-09:30',
			'UTC-09:00' => 'UTC-09:00',
			'UTC-08:00' => 'UTC-08:00',
			'UTC-07:00' => 'UTC-07:00',
			'UTC-06:00' => 'UTC-06:00',
			'UTC-05:00' => 'UTC-05:00',
			'UTC-04:30' => 'UTC-04:30',
			'UTC-04:00' => 'UTC-04:00',
			'UTC-03:30' => 'UTC-03:30',
			'UTC-03:00' => 'UTC-03:00',
			'UTC-02:00' => 'UTC-02:00',
			'UTC-01:00' => 'UTC-01:00',
			'UTC+00:00' => 'UTC+00:00',
			'UTC+01:00' => 'UTC+01:00',
			'UTC+02:00' => 'UTC+02:00',
			'UTC+03:00' => 'UTC+03:00',
			'UTC+03:30' => 'UTC+03:30',
			'UTC+04:00' => 'UTC+04:00',
			'UTC+04:30' => 'UTC+04:30',
			'UTC+05:00' => 'UTC+05:00',
			'UTC+05:30' => 'UTC+05:30',
			'UTC+05:45' => 'UTC+05:45',
			'UTC+06:00' => 'UTC+06:00',
			'UTC+06:30' => 'UTC+06:30',
			'UTC+07:00' => 'UTC+07:00',
			'UTC+08:00' => 'UTC+08:00',
			'UTC+08:45' => 'UTC+08:45',
			'UTC+09:00' => 'UTC+09:00',
			'UTC+09:30' => 'UTC+09:30',
			'UTC+10:00' => 'UTC+10:00',
			'UTC+10:30' => 'UTC+10:30',
			'UTC+11:00' => 'UTC+11:00',
			'UTC+12:00' => 'UTC+12:00',
			'UTC+12:45' => 'UTC+12:45',
			'UTC+13:00' => 'UTC+13:00',
			'UTC+14:00' => 'UTC+14:00',
		);

		$timezone_strings = timezone_identifiers_list();
		foreach ( $timezone_strings as $zone ) {
			$timezones[ $zone ] = $zone;
		}

		$timezone_default = wp_timezone()->getName();

		$this->controls['timezone'] = array(
			'tab'         => 'content',
			'required'    => array( 'mode', '=', 'fixed' ),
			'label'       => esc_html__( 'Time zone', 'bricks' ),
			'type'        => 'select',
			'searchable'  => true,
			'options'     => $timezones,
			'inline'      => true,
			'placeholder' => $timezone_default,
		);

		$this->controls['actionSeparator'] = array(
			'type' => 'separator',
		);

		$this->controls['action'] = array(
			'label'       => esc_html__( 'Action', 'bricks' ) . ' (' . esc_html__( 'End', 'bricks' ) . ')',
			'type'        => 'select',
			'options'     => array(
				'countdown' => esc_html__( 'Countdown', 'bricks' ),
				'hide'      => esc_html__( 'Hide', 'bricks' ),
				'text'      => esc_html__( 'Custom text', 'bricks' ),
				'redirect'  => esc_html__( 'Redirect', 'bricks' ),
				'sync'      => esc_html__( 'Close element', 'bricksextras' ) . ' (' . esc_html__( 'Modal', 'bricksextras' ) . ' / ' . esc_html__( 'Notification', 'bricksextras' ) . ')',
				'countUp'   => esc_html__( 'Count Up', 'bricksextras' ),
				'none'      => esc_html__( 'None', 'bricks' ),
			),
			'placeholder' => esc_html__( 'Countdown', 'bricks' ),
			'inline'      => true,
			'rerender'    => true,
		);

		$this->controls['redirectLink'] = array(
			'label'       => esc_html__( 'Redirect to', 'bricksextras' ),
			'type'        => 'link',
			'required'    => array( 'action', '=', 'redirect' ),
			'placeholder' => esc_html__( 'Redirect to..', 'bricksextras' ),
			'exclude'     => array(
				'media',
				'lightboxImage',
				'lightboxVideo',
				'attributesSep',
				'rel',
				'ariaLabel',
				'newTab',
				'title',
			),
		);

		$this->controls['redirectURL'] = array(
			'label'    => esc_html__( 'Redirect URL', 'bricksextras' ),
			'type'     => 'text',
			'required' => array( 'action', '=', 'no' ),
			'inline'   => true,
		);

		$this->controls['redirectDelay'] = array(
			'label'       => esc_html__( 'Redirect delay (seconds)', 'bricksextras' ),
			'type'        => 'text',
			'required'    => array( 'action', '=', 'redirect' ),
			'placeholder' => '0',
			'inline'      => true,
		);

		$this->controls['redirectDelayText'] = array(
			'label'    => esc_html__( 'Text during redirect delay', 'bricksextras' ),
			'type'     => 'editor',
			'required' => array( 'action', '=', 'redirect' ),
		);

		$this->controls['preventRedirect'] = array(
			'label'       => esc_html__( 'Prevent redirect for admins', 'bricksextras' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'required'    => array( 'action', '=', 'redirect' ),
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
			'inline'      => true,
		);

		$this->controls['actionText'] = array(
			'label'    => esc_html__( 'Date Reached', 'bricks' ) . ': ' . esc_html__( 'Custom text', 'bricks' ),
			'type'     => 'editor',
			'required' => array( 'action', '=', 'text' ),
			'rerender' => true,
		);

		$this->controls['fieldsSeparator'] = array(
			'label' => esc_html__( 'Fields', 'bricks' ),
			'type'  => 'separator',
		);

		$this->controls['fields'] = array(
			'required'      => array( 'mode', '!=', 'fixed' ),
			'type'          => 'repeater',
			'titleProperty' => 'format',
			'placeholder'   => esc_html__( 'Field', 'bricks' ),
			'fields'        => array(
				'type'   => array(
					'label'   => esc_html__( 'Type', 'bricks' ),
					'type'    => 'select',
					'options' => array(
						'days'    => esc_html__( 'Days', 'bricksextras' ),
						'hours'   => esc_html__( 'Hours', 'bricksextras' ),
						'minutes' => esc_html__( 'Minutes', 'bricksextras' ),
						'seconds' => esc_html__( 'Seconds', 'bricksextras' ),
					),
					'inline'  => true,
				),
				'value'  => array(
					'label'  => esc_html__( 'Value', 'bricks' ),
					'type'   => 'text',
					'inline' => true,
				),
				'format' => array(
					'label'       => esc_html__( 'Format', 'bricks' ),
					'type'        => 'text',
					'placeholder' => '%D',
					'inline'      => true,
					'info'        => '%D, %H, %M, %S (' . esc_html__( 'Lowercase removes leading zeros', 'bricks' ) . ')',
				),
			),
			'default'       => array(
				array(
					'format' => '%D days',
					'type'   => 'days',
					'value'  => 3,
				),
				array(
					'format' => '%H hours',
					'type'   => 'hours',
				),
				array(
					'format' => '%M minutes',
					'type'   => 'minutes',
				),
				array(
					'format' => '%S seconds',
					'type'   => 'seconds',
				),
			),
			'rerender'      => true,
		);

		$this->controls['fieldsFixed'] = array(
			'required'      => array( 'mode', '=', 'fixed' ),
			'type'          => 'repeater',
			'titleProperty' => 'format',
			'placeholder'   => esc_html__( 'Field', 'bricks' ),
			'fields'        => array(
				'type'   => array(
					'label'   => esc_html__( 'Type', 'bricks' ),
					'type'    => 'select',
					'options' => array(
						'days'    => esc_attr__( 'Days', 'bricksextras' ),
						'hours'   => esc_attr__( 'Hours', 'bricksextras' ),
						'minutes' => esc_attr__( 'Minutes', 'bricksextras' ),
						'seconds' => esc_attr__( 'Seconds', 'bricksextras' ),
					),
					'inline'  => true,
				),
				'format' => array(
					'label'       => esc_attr__( 'Format', 'bricks' ),
					'type'        => 'text',
					'placeholder' => '%D',
					'inline'      => true,
					'info'        => '%D, %H, %M, %S (' . esc_html__( 'Lowercase removes leading zeros', 'bricks' ) . ')',
				),
			),
			'default'       => array(
				array(
					'format' => '%D days',
					'type'   => 'days',
					'value'  => 3,
				),
				array(
					'format' => '%H hours',
					'type'   => 'hours',
				),
				array(
					'format' => '%M minutes',
					'type'   => 'minutes',
				),
				array(
					'format' => '%S seconds',
					'type'   => 'seconds',
				),
			),
			'rerender'      => true,
		);

		$this->controls['actionEndSeparator'] = array(
			'type' => 'separator',
		);

		$this->controls['flexDirectionFields'] = array(
			'label'  => esc_html__( 'Direction', 'bricks' ),
			'type'   => 'direction',
			'css'    => array(
				array(
					'property' => 'flex-direction',
					'selector' => '',
				),
			),
			'inline' => true,
		);

		// items.

		$this->controls['flexDirection'] = array(
			'label'       => esc_html__( 'Direction', 'bricks' ),
			'type'        => 'direction',
			'css'         => array(
				array(
					'property' => 'flex-direction',
					'selector' => '.x-countdown_format',
				),
			),
			'inline'      => true,
			'group'       => 'itemsGroup',
			'placeholder' => 'column',
		);

			$this->controls['itemGap'] = array(
				'tab'         => 'content',
				'label'       => esc_html__( 'Gap', 'bricks' ),
				'inline'      => true,
				'type'        => 'number',
				'units'       => true,
				'placeholder' => '5px',
				'css'         => array(
					array(
						'property' => 'gap',
						'selector' => '',
					),
				),
				'group'       => 'itemsGroup',
			);

			$this->controls['itemBackgroundColor'] = array(
				'tab'   => 'content',
				'type'  => 'color',
				'label' => esc_html__( 'Background', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'background-color',
						'selector' => '.x-countdown_item',
					),
				),
				'group' => 'itemsGroup',
			);

			$this->controls['itemBorder'] = array(
				'tab'   => 'content',
				'type'  => 'border',
				'label' => esc_html__( 'Border', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'border',
						'selector' => '.x-countdown_item',
					),
				),
				'group' => 'itemsGroup',
			);

			$this->controls['itemBoxShadow'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Box shadow', 'bricks' ),
				'type'  => 'box-shadow',
				'css'   => array(
					array(
						'property' => 'box-shadow',
						'selector' => '.x-countdown_item',
					),
				),
				'group' => 'itemsGroup',
			);

			$this->controls['itemPadding'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Padding', 'bricks' ),
				'type'  => 'spacing',
				'css'   => array(
					array(
						'property' => 'padding',
						'selector' => '.x-countdown_item',
					),
				),
				'group' => 'itemsGroup',
			);

			$this->controls['itemWidth'] = array(
				'tab'   => 'content',
				'label' => esc_html__( 'Width', 'bricks' ),
				'type'  => 'number',
				'units' => true,
				'css'   => array(
					array(
						'property' => 'width',
						'selector' => '.x-countdown_item',
					),
				),
				'group' => 'itemsGroup',
			);

			unset( $this->controls['_typography'] );

			$this->controls['typography'] = array(
				'tab'   => 'style',
				'group' => '_typography',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'type'  => 'typography',
				'css'   => array(
					array(
						'property' => 'font',
					),
				),
			);

			$this->controls['numberTypography'] = array(
				'tab'   => 'style',
				'group' => '_typography',
				'label' => esc_html__( 'Typography', 'bricks' ) . ' (' . esc_html__( 'Number', 'bricks' ) . ')',
				'type'  => 'typography',
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => '.x-countdown_number',
					),
				),
			);

			$this->controls['maybeSeperator'] = array(
				'tab'         => 'style',
				'group'       => 'seperatorsGroup',
				'label'       => esc_html__( 'Enable', 'bricks' ),
				'type'        => 'select',
				'inline'      => true,
				'options'     => array(
					'disable' => esc_html__( 'Disable', 'bricks' ),
					'enable'  => esc_html__( 'Enable', 'bricks' ),
				),
				'placeholder' => esc_html__( 'Enable', 'bricks' ),
			);

			$this->controls['seperator'] = array(
				'tab'         => 'style',
				'group'       => 'seperatorsGroup',
				'label'       => esc_html__( 'Separator', 'bricks' ),
				'type'        => 'text',
				'inline'      => true,
				'placeholder' => ':',
				'required'    => array( 'maybeSeperator', '!=', 'disable' ),
			);

			$this->controls['seperatorTypography'] = array(
				'tab'   => 'content',
				'type'  => 'typography',
				'label' => esc_html__( 'Typography', 'bricks' ),
				'css'   => array(
					array(
						'property' => 'font',
						'selector' => '.x-countdown_seperator',
					),
				),
				'group' => 'seperatorsGroup',
			);
	}

	/**
	 * Render element output.
	 */
	public function render() {

		$settings = $this->settings;

		$timezone_setting = ! empty( $settings['timezone'] ) ? $settings['timezone'] : false;

		if ( ! $timezone_setting ) {

			$default_timezone_settings = wp_timezone()->getName();

			// Check if wp_timezone is a named timezone.
			if ( in_array( $default_timezone_settings, timezone_identifiers_list(), true ) ) {

				$timezone_object = new DateTimeZone( $default_timezone_settings );
				$datetime        = new DateTime( 'now', $timezone_object );
				$timezone        = 'UTC' . $datetime->format( 'P' );

			} else {
				$timezone = 'UTC' . $default_timezone_settings;
			}
		} elseif ( in_array( $timezone_setting, timezone_identifiers_list(), true ) ) {

			$timezone_object = new DateTimeZone( $timezone_setting );
			$datetime        = new DateTime( 'now', $timezone_object );
			$timezone        = 'UTC' . $datetime->format( 'P' );

		} else {
			$timezone = $timezone_setting;
		}

		$mode            = isset( $settings['mode'] ) ? esc_attr( $settings['mode'] ) : 'evergreen';
		$date            = ! empty( $settings['date'] ) ? $settings['date'] : false;
		$fields          = ! empty( $settings['fields'] ) ? $settings['fields'] : false;
		$fields_fixed    = ! empty( $settings['fieldsFixed'] ) ? $settings['fieldsFixed'] : false;
		$action          = ! empty( $settings['action'] ) ? esc_attr( $settings['action'] ) : 'countdown';
		$action_text     = ! empty( $settings['actionText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['actionText'] ) ) : '';
		$maybe_seperator = isset( $settings['maybeSeperator'] ) ? 'enable' === $settings['maybeSeperator'] : true;
		$seperator       = isset( $settings['seperator'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['seperator'] ) ) : ':';

		if ( ! $fields ) {
			return $this->render_element_placeholder( array( 'title' => esc_html__( 'No date/fields set.', 'bricks' ) ) );
		}

		$processed_fields = 'evergreen' === $mode ? $fields : $fields_fixed;
		if ( is_array( $processed_fields ) ) {
			foreach ( $processed_fields as $key => $field ) {
				if ( isset( $field['value'] ) ) {
					$processed_fields[ $key ]['value'] = bricks_render_dynamic_data( $field['value'] );
				}
				if ( isset( $field['format'] ) ) {
					$processed_fields[ $key ]['format'] = bricks_render_dynamic_data( $field['format'] );
				}
			}
		}

		$config = array(
			'timezone'   => $timezone,
			'mode'       => $mode,
			'fields'     => $processed_fields,
			'action'     => $action,
			'actionText' => $action_text,
		);

		if ( (bool) $date ) {

			$date = $this->render_dynamic_data( $date );

			try {
				$date = new DateTimeImmutable( $date );
				$date = $date->format( 'Y-m-d H:i:s' );
			} catch ( Exception $e ) {
				// Ignore invalid date format - continue with empty date.
			}

			$config['date'] = $date;

		}

		if ( $maybe_seperator ) {
			$config['seperator'] = $seperator;
		}

		$redirect_url = false;

		if ( ! empty( $settings['redirectLink'] ) ) {

			$temp_key = '_countdown_redirect_temp';
			$this->set_link_attributes( $temp_key, $settings['redirectLink'] );
			$resolved = isset( $this->attributes[ $temp_key ] ) ? $this->attributes[ $temp_key ] : array();

			if ( ! empty( $resolved['href'] ) ) {
				$href = $resolved['href'];

				if ( is_array( $href ) ) {
					$href = reset( $href );
				}

				if ( is_string( $href ) ) {
					$redirect_url = esc_url( $href );
				}
			}

			unset( $this->attributes[ $temp_key ] );

		} elseif ( isset( $settings['redirectURL'] ) ) {
			$redirect_url = esc_url( bricks_render_dynamic_data( $settings['redirectURL'] ) );
		}

		if ( (bool) $redirect_url && 'redirect' === $action ) {
			$config['redirectURL']       = $redirect_url;
			$config['preventRedirect']   = isset( $settings['preventRedirect'] ) ? $settings['preventRedirect'] : 'enable';
			$config['redirectDelay']     = isset( $settings['redirectDelay'] ) ? absint( bricks_render_dynamic_data( $settings['redirectDelay'] ) ) : 0;
			$config['redirectDelayText'] = isset( $settings['redirectDelayText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['redirectDelayText'] ) ) : '';
		}

		$output_config = wp_json_encode( $config );

		$this->set_attribute( '_root', 'role', 'timer' );
		$this->set_attribute( '_root', 'aria-atomic', 'true' );
		$this->set_attribute( '_root', 'data-x-countdown', $output_config );

		// Generate and set a unique identifier for this instance.
		$indentifier = \BricksExtras\Helpers::set_identifier_attribute( $this );

		echo "<div {$this->render_attributes( '_root' )}></div>";
	}
}
